首页 > 解决方案 > Swift,使用 json/php 制作自定义 MapKit 注释

问题描述

我正在关注本教程:https ://www.raywenderlich.com/160517/mapkit-tutorial-getting-started

这些问题与 swift(无论最新版本的 xcode 使用什么)、JSON 和 PHP 有关。本教程按原样工作,但我想进行一些修改。我已经完成了其他所有事情,但我被困在以下问题上。

教程代码与我试图让应用程序执行的操作之间存在一些差异。主要是教程中的 JSON 格式与我的 PHP 页面吐出的不同。

我有几个问题。

1)如何将代码修改为:

a) 使用来自 URL 的 JSON 数据,而不是教程中使用的 PublicArt.json 文件,并且

b) 如何修改教程中的代码以接受我从服务器上的 PHP 文件接收的 JSON 格式?

上述问题参考了以下2段代码(教程中的原始代码):

init?(json: [Any]) {
// 1
self.title = json[16] as? String ?? "No Title"
self.locationName = json[12] as! String
self.discipline = json[15] as! String
// 2
if let latitude = Double(json[18] as! String),
let longitude = Double(json[19] as! String) {
self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
} else {
self.coordinate = CLLocationCoordinate2D()
}
}

和这段代码(教程中的原始代码):

func loadInitialData() {
// 1
guard let fileName = Bundle.main.path(forResource: "PublicArt", ofType: "json") 
else { return }
let optionalData = try? Data(contentsOf: URL(fileURLWithPath: fileName))

guard
let data = optionalData,
// 2
let json = try? JSONSerialization.jsonObject(with: data),
// 3
let dictionary = json as? [String: Any],
// 4
let works = dictionary["data"] as? [[Any]]
else { return }
// 5
let validWorks = works.flatMap { Artwork(json: $0) }
artworks.append(contentsOf: validWorks)
}

本教程中使用的 JSON 格式是这样的:

[ 55, "8492E480-43E9-4683-927F-0E82F3E1A024", 55, 1340413921, "436621", 1340413921, "436621", "{\n}", "Sean Browne", "Gift of the Oahu Kanyaku Imin Centennial Committee", "1989", "Large than life-size bronze figure of King David Kalakaua mounted on a granite pedestal. Located at Waikiki Gateway Park.", "Waikiki Gateway Park", "http://hiculturearts.pastperfect-online.com/34250images/002/199103-3.JPG", "1991.03", "Sculpture", "King David Kalakaua", "Full", "21.283921", "-157.831661", [ null, "21.283921", "-157.831661", null, false ], null ]

我想要使​​用的 PHP 文件的格式是这样的:

{"id":1,"placeid":"1","lat":"25.4432","long":"-153.2345","location_title":"Sample Location","location_subtitle":"Sample Subtitle","log_status":"success"} {"id":2,"placeid":"2","lat":"25.4543","long":"-153.2345","location_title":"Sample Location 2","location_subtitle":"Sample Subtitle 2","log_status":"success"} {"id":3,"placeid":"3","lat":"25.4632","long":"-153.2345","location_title":"Sample Location 3","location_subtitle":"Sample Subtitle 3","log_status":"success"} 本教程使用文件 PublicArt.json,我使用 url htttp//www.samplesite.com/json.php(不是我使用的真正的 url,但你明白了,我实际使用的 url 产生工作 JSON 代码)

2) 最后,本教程使用标注附件作为信息按钮来打开地图应用程序以指示前往某个位置的方向。相反,当单击按钮时,如何使用此按钮创建到不同 ViewController 的 segue?我认为这是教程中打开地图应用程序的代码的一部分:

let mapsButton = UIButton(frame: CGRect(origin: CGPoint.zero,
size: CGSize(width: 30, height: 30)))
mapsButton.setBackgroundImage(UIImage(named: "Maps-icon"), for: UIControlState())
rightCalloutAccessoryView = mapsButton

谢谢你的帮助。非常感谢!

编辑:

好的,这是我从“我的 PHP 文件”中获取信息的代码。在这种情况下,您甚至不需要 var1 和 var2,因为 json.php 无论如何都会吐出所有数据。使用我的代码,我可以只使用 responseJSON["whatever"] 从响应字符串中获取值。我对教程中的格式感到困惑。

let url = "https://www.samplesite.com/json.php"

let var1 = self.textForm1.text!
let var2 = self.textForm2.text!

let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
request.httpMethod = "POST"

let postString = "var=\(var1)&var2=\(var2)"
print(postString)

request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")

request.httpBody = postString.data(using: String.Encoding.utf8)

let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in

guard error == nil && data != nil else {
print("error=\(String(describing: error))")
return
}

do {
if let responseJSON = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject]{

// If successful
if ((responseJSON["log_status"]!) as! String == "success") {

// do stuff here if log_status response is success

}
} else {

//If there is an error do stuff here

}

}
}
catch {
print("Error -> \(error)")
}
}
task.resume()

如何修改教程中的代码以便能够以类似的方式解析数据?这是教程中的代码:

func loadInitialData() {
// 1
guard let fileName = Bundle.main.path(forResource: "PublicArt", ofType: "json") 
else { return }
let optionalData = try? Data(contentsOf: URL(fileURLWithPath: fileName))

guard
let data = optionalData,
// 2
let json = try? JSONSerialization.jsonObject(with: data),
// 3
let dictionary = json as? [String: Any],
// 4
let works = dictionary["data"] as? [[Any]]
else { return }
// 5
let validWorks = works.flatMap { Artwork(json: $0) }
artworks.append(contentsOf: validWorks)
}

标签: jsonswiftxcodeannotationsandroid-mapview

解决方案


推荐阅读