I'm following this tutorial: https://www.raywenderlich.com/160517/mapkit-tutorial-getting-started
These questions are in regard to swift (whatever the latest version of xcode uses), JSON and PHP. The tutorial works as is, but I want to make several modifications. I've done everything else but I'm stuck on the following questions.
There are several differences between the tutorial code and what I'm trying to get the app to do. Mainly, the JSON format in the tutorial is different from what my PHP page is spitting out.
I have several questions.
1) How do I modify the code to:
a) use the JSON data from a URL, not from the PublicArt.json file as used in the tutorial, and
b) how do I modify the code from the tutorial to accept the JSON format I'm receiving from a PHP file on my server?
The above question is in reference to the following 2 piece of code (original code in the tutorial):
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()
}
}
and this code (original code in the tutorial):
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)
}
The JSON format used in the tutorial is this:
[ 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 ]
The format from my PHP file that I want to use is this:
{"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"}
The tutorial uses file PublicArt.json and I use url htttp//www.samplesite.com/json.php (not really the url I use but you get it, the url I actually use produces working JSON code)
2) Finally, the tutorial uses a callout accessory as an info button to open up the Maps app to give directions to a location. Instead, how can I use this button to create a segue to a different ViewController when the button is clicked? I think this is the part of the code from the tutorial the opens the Maps app:
let mapsButton = UIButton(frame: CGRect(origin: CGPoint.zero,
size: CGSize(width: 30, height: 30)))
mapsButton.setBackgroundImage(UIImage(named: "Maps-icon"), for: UIControlState())
rightCalloutAccessoryView = mapsButton
Thanks for your help. It's very appreciated!
Edit:
Ok, so here's my code for getting information from "my PHP file". In this case you don't even need var1 and var2, because json.php is made to spit out all the data anyway. With my code I can just us responseJSON["whatever"] to get values out of the response string. I'm confused about the formatting in the tutorial.
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()
How do I modify the code from the tutorial to be able to parse the data in a similar way? This is the code from the tutorial:
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)
}