Swift, правене на персонализирани анотации на MapKit с json/php

Следвам този урок: 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 адрес htttp//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["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)
}

person J Smith    schedule 09.07.2018    source източник
comment
вижте този отговор   -  person zombie    schedule 10.07.2018
comment
Първо, този въпрос е изключително сложен... вие искате корекции на множество кодове само в един въпрос! Второ. Форматът JSON, използван в урока, не е JSON. Поне не по начина, по който изглежда във въпроса ви. Трето, форматът от моя PHP файл трябва да бъде структуриран като масив - това означава, че трябва да има квадратни скоби, затварящи низа, който сте публикували.   -  person Barns    schedule 10.07.2018
comment
Добре, за да опростя тогава, как да променя начина, по който те анализират и използват своя json отговор в кода на урока, до начина, по който използвам моя. Добавих кода, който използвам (който работи в други приложения), както и техния код под Редактиране в OP.   -  person J Smith    schedule 10.07.2018