Reputation: 1614
I was in the process of parsing JSON data from the google maps API to get my current location city using longitude & latitude.
But now im stuck with my code here and i cannot access the data in the results. For instance i want to get the data in the "administrative_area_level_2" for the key "long name". How can i access it?
dispatch_async(dispatch_get_main_queue(), {
if let urlContent = data{
do{
let jsonResult = try NSJSONSerialization.JSONObjectWithData(urlContent, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
if let results = jsonResult["results"] as? [[String : AnyObject]] {
for result in results{
if let addressComponents = result["address_components"] as? [[String : AnyObject]] {
print(addressComponents)
}
}
}
// print(jsonResult)
} catch{
}
}
})
Here are the addressComponents JSON results in console:
[["types": (
route
), "short_name": Abou Al MAGD Al Askalani, "long_name": Abou Al MAGD Al Askalani], ["types": (
"administrative_area_level_3",
political
), "short_name": Al Golf, "long_name": Al Golf], ["types": (
"administrative_area_level_2",
political
), "short_name": Nasr City, "long_name": Nasr City], ["types": (
"administrative_area_level_1",
political
), "short_name": Cairo Governorate, "long_name": Cairo Governorate], ["types": (
country,
political
), "short_name": EG, "long_name": Egypt]]
Here are the results jsonResult results in console:
results = (
{
"address_components" = (
{
"long_name" = "Abou Al MAGD Al Askalani";
"short_name" = "Abou Al MAGD Al Askalani";
types = (
route
);
},
{
"long_name" = "Al Golf";
"short_name" = "Al Golf";
types = (
"administrative_area_level_3",
political
);
},
{
"long_name" = "Nasr City";
"short_name" = "Nasr City";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = "Cairo Governorate";
"short_name" = "Cairo Governorate";
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Egypt;
"short_name" = EG;
types = (
country,
political
);
}
);
Upvotes: 3
Views: 3508
Reputation: 1681
func calculateDistanceByGoogleAPI(){
let currentLat = 48.855683 //self.currentLocation.latitude
let currentLon = 2.353580 //self.currentLocation.longitude
let restLat = self.restaurantObj.location.coordinate.latitude
let restLon = self.restaurantObj.location.coordinate.longitude
let url = "https://maps.googleapis.com/maps/api/distancematrix/json?&origins=\(currentLat),\(currentLon)&destinations=\(restLat),\(restLon)&key=\(Constants.GMAP_KEY)"
let encodedUrl = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
let header: HTTPHeaders = [ "Accept": "application/json", "Content-Type": "application/json" ]
AF.request(encodedUrl! , method: .get,encoding: JSONEncoding.default, headers: header)
.responseJSON { (response) in
if let result = response.result.value {
let json = JSON(result) //use SwiftyJSON pod and import
let distanceStr = json["rows"][0]["elements"][0]["distance"]["text"].string
self.distanceLbl.text = distanceStr
}
}
}
Use a JSON library like SwiftyJSON and read the gooogle api response like this
Upvotes: 0
Reputation: 285039
For deeply nested JSON I'd recommend a third-party library like SwiftyJSON
but this is a "without" solution. It uses the filter
function to get the item containing the requested type
if let urlContent = data {
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(urlContent, options: NSJSONReadingOptions()) as! [String : AnyObject]
if let results = jsonResult["results"] as? [[String : AnyObject]] {
for result in results{
if let addressComponents = result["address_components"] as? [[String : AnyObject]] {
let filteredItems = addressComponents.filter{ if let types = $0["types"] as? [String] {
return types.contains("administrative_area_level_2") } else { return false } }
if !filteredItems.isEmpty {
print(filteredItems[0]["long_name"] as! String)
}
}
}
}
} catch let error as NSError {
print(error)
}
}
Upvotes: 2
Reputation: 6272
In one of my apps I am loading details about place using placeID. However, the results are returned in the same format as you have. Here is a code snippet which might help you:
let task = NSURLSession.sharedSession().dataTaskWithURL(url) {(data, _, retError) in
if let error = retError {
self.error = .RequestError(error)
return
}
guard
let JSON = data else {
self.error = .CannotParseData
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(JSON, options: .MutableContainers)
guard
let results = json["results"] as? [[String: AnyObject]]
else {
self.error = .CannotParseData
return
}
if results.count == 0 {
self.error = .NoResults
return
}
let result = results[0]
// first check that locality exists
guard let resultTypes = result["types"] as? [String],
let addressComponents = result["address_components"] as? [[String:AnyObject]],
let formattedAddress = result["formatted_address"] as? String,
let geometry = result["geometry"] as? [String:AnyObject],
let location = geometry["location"] as? [String:Double],
let lat = location["lat"],
let lng = location["lng"]
else {
//let error = NSError()
self.error = .CannotParseData
return
}
// at this point you can use all the variables declared above
}
}
I hope this is helpful.
Upvotes: 0