Reputation: 79
I'm trying to use the Google Geolocation api, within Xcode using Swift, to allow the conversion of text address to latitude and longitude.
http://maps.googleapis.com/maps/api/geocode/json?address=washington%20dc is an example JSON call.
the error: Type 'String' does not confirm to protocol 'NSCopying', appears when trying to access elements within the dictionary of results.
@IBAction func submitButtonPressed(sender: AnyObject) {
var address = addAddressTextField.text
var escapedAddress = address.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let urlpath = "http://maps.googleapis.com/maps/api/geocode/json?address=" + escapedAddress!
println(urlpath)
let url = NSURL(string: urlpath)!
let urlSession = NSURLSession.sharedSession()
let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { (data, responce, error) -> Void in
if error != nil{
println("there is an error")
}
var err : NSError?
var results = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if err != nil{
println("there is a second error")
}
let formattedAddress: AnyObject! = results["results"]![0]!["formatted_address"]!
let latitude: AnyObject! = results["results"]![0]!["geometry"]!["location"]!["lat"]!
let longitude: AnyObject! = results["results"]![0]!["geometry"]!["location"]!["lng"]!
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.fullAddressLabel.text = "\(formattedAddress)"
self.latLabel.text = "\(latitude)"
self.longLabel.text = "\(longitude)"
})
})
jsonQuery.resume()
}
The error only occurs on the lines:
let latitude: AnyObject! = results["results"]![0]!["geometry"]!["location"]!["lat"]!
let longitude: AnyObject! = results["results"]![0]!["geometry"]!["location"]!["lng"]!
and the let formattedAddress: AnyObject! = ... line works perfectly.
I have tried defining the variables as Strings and NSStrings and using '... as String' within the definition but to no luck.
Upvotes: 1
Views: 584
Reputation: 879
I ran into the same issue with json try this
let latitude = results["results"]![0]!["geometry"]!!["location"]!!["lat"]!! as String
let longitude = results["results"]![0]!["geometry"]!!["location"]!!["lng"]!! as String
note, This does not include any error checking at all also if the labels you are updating are standard labels you can just do
mylabel.stringValue = latitude
or something like that :P
Here is a direct copy of how i phrase my json objects without error checking
var FilePath = object["main"]![row]!["Paths:"]!!["FilePath:"]!! as String
Upvotes: 0
Reputation: 86651
The problem is not the returned variables but the keys. NSDictionary
expects its keys to conform to NSCopying
and presumably a Swift string literal does not.
I would try to figure out exactly which access is causing the issue by not trying to get the whole thing in one line (your program will crash btw if you get an unexpected response because you assume all the keys exist in all the dictionaries).
On the assumption that you know you have at least one result and you have put it in a variable called results0
(this comes from external data so you must check it), I'd do this
var latitude: Double?
var longitude: Double?
if let geometry = results0["geometry"] as? NSDictionary
{
if let location = geometry["location"] as? NSDictionary
{
latitude = location["lat"] as? Double
longitude = location["lon"] as? Double
}
}
Either you will get the same error on one of the lines accessing the dictionaries or something else may go wrong. You might have to fiddle about with the casting too to get it right (I haven't even tried to compile the above code). But the point is that now the code is spread out over several lines, it should be much easier to isolate the error.
Upvotes: 0