Я следую этому руководству: https://www.raywenderlich.com/160517/mapkit-tutorial-getting-started
Эти вопросы касаются swift (независимо от того, что использует последняя версия xcode), JSON и PHP. Учебник работает как есть, но я хочу внести несколько изменений. Я сделал все остальное, но я застрял на следующих вопросах.
Есть несколько различий между учебным кодом и тем, что я пытаюсь заставить приложение делать. В основном, формат JSON в руководстве отличается от того, что выплевывает моя PHP-страница.
У меня есть несколько вопросов.
1) Как мне изменить код на:
a) использовать данные JSON из URL-адреса, а не из файла PublicArt.json, который используется в руководстве, и
б) как изменить код из руководства, чтобы он принимал формат JSON, который я получаю из файла PHP на своем сервере?
Вышеупомянутый вопрос относится к следующим 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-адрес http//www.samplesite.com/json.php (не совсем тот URL, который я использую, но вы его понимаете, URL-адрес, который я фактически использую, создает рабочий код JSON)
2) Наконец, в руководстве используется вспомогательная выноска в качестве информационной кнопки, которая открывает приложение «Карты» и указывает направление к местоположению. Вместо этого, как я могу использовать эту кнопку для создания перехода к другому ViewController при нажатии кнопки? Я думаю, что это часть кода из руководства, которая открывает приложение "Карты":
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["независимо"], чтобы получить значения из строки ответа. Меня смущает форматирование в учебнике.
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)
}