可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
this is my code.getting this EXC_BAD_ACCESS(code=EXC_i386_GPFLT).I don'n know how to find and solve plz help me ...application getting crash when get longitude
mapServerRequest="Hyderabad,india" var mapAddress:NSString=mapServerRequest mapAddress.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet()) println(mapAddress) var urlpath=NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address=%@", mapAddress) println(urlpath) var url = NSURL.URLWithString(urlpath) println(url) var jsonData:NSData=NSData(contentsOfURL:url) if(jsonData != nil) { var error:NSError=NSError(coder: nil) var result:NSDictionary=NSJSONSerialization .JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary //println(result) if (error != nil) { mapServerResultArray=result.valueForKey("results") as NSMutableArray // println(mapServerResultArray) } var longitud:NSString longitud=mapServerResultArray.objectAtIndex(0).valueForKey("geometry").valueForKey("location").valueForKey("lng")as NSString var latitud :NSString = (mapServerResultArray .objectAtIndex(0).valueForKey("geometry").valueForKey("location").valueForKey("lat")) as NSString placeName=mapServerResultArray .objectAtIndex(0).valueForKey("formatted_address") as NSString var longitude:Float=longitud.floatValue var latitude:Float=latitud.floatValue self.zoomMapAndCenterAtLatitude(latitude) self.zoomMapAndCenterAtLongitud(longitude)
回答1:
Your problem here is that most of the operations you are performing can return nil, which will crash Swift if you try and use it as a non-nil value. You need to be explicit about testing for nil. The sledgehammer way of doing it would be
let mapAddress = "Hyderabad,india" let url = NSURL.URLWithString("http://maps.googleapis.com/maps/api/geocode/json?address=\(mapAddress)") let jsonData = NSData(contentsOfURL:url) var latitude = NSNumber(double: 0.0) var longitude = NSNumber(double: 0.0) var success = false if jsonData != nil { if let result = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary { if let mapServerResultArray = result.valueForKey("results") as? NSArray { if let geometry = mapServerResultArray[0].valueForKey("geometry") as? NSDictionary { if let location = geometry.valueForKey("location") as? NSDictionary { if let lat = location.valueForKey("lat") as? Float { latitude = lat if let lng = location.valueForKey("lng") as? Float { longitude = lng success = true } } } } } } } if success { println("Latitude = \(latitude), longitude=\(longitude)") } else { println("Failed") }
... however that is ugly. As this routine may or may not find any of the keys, at the end you may or may not have a valid pair of coordinates. This is exactly what Optionals are for. Consider rewriting it as a function that returns an optional:
struct Coordinate { // Or use any of Cocoa's similar structs var latitude: Double var longitude: Double } func getCoordsOf(#address: String) -> Coordinate? { let url = NSURL.URLWithString("http://maps.googleapis.com/maps/api/geocode/json?address=\(address)") let jsonData = NSData(contentsOfURL:url) if jsonData == nil { return nil } let result = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary if result == nil { return nil } if let geometry = result.valueForKey("results").valueForKey("geometry") as? NSArray { if geometry.count > 0 { let lat = geometry[0].valueForKey("location")?.valueForKey("lat")?.doubleValue let lng = geometry[0].valueForKey("location")?.valueForKey("lng")?.doubleValue if (lat != nil) && (lng != nil) { return Coordinate(latitude: lat!, longitude: lng!) } } } return nil } if let coord = getCoordsOf(address: "Hyderabad,india") { // ... do something }
This uses Optional Chaining (?) to lessen the testing, but we have to break it at geometry because we need that to be an array, as we need to access a specific element of it (and, of course, should test that it isn't an empty array!)
p.s. - ironically, your test on error != nil does nothing, as you did not send error to the JSONObjectWithData routine.
回答2:
In that type of situation you can convert latitude to string. Updated code:
mapServerRequest="Hyderabad,india" var mapAddress:NSString=mapServerRequest mapAddress.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet()) println(mapAddress) var urlpath=NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address=%@", mapAddress) println(urlpath) var url = NSURL.URLWithString(urlpath) println(url) var jsonData:NSData=NSData(contentsOfURL:url) if(jsonData != nil) { var error:NSError=NSError(coder: nil) var result:NSDictionary=NSJSONSerialization .JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary //println(result) if (error != nil) { mapServerResultArray=result.valueForKey("results") as NSMutableArray // println(mapServerResultArray) } var longitud:NSString longitud=NSString(format:mapServerResultArray.objectAtIndex(0).valueForKey("geometry").valueForKey("location").valueForKey("lng")) var latitud :NSString latitud=NSString(format:(mapServerResultArray .objectAtIndex(0).valueForKey("geometry").valueForKey("location").valueForKey("lat"))) placeName=NSString(format:mapServerResultArray .objectAtIndex(0).valueForKey("formatted_address")) var longitude:Float=longitud.floatValue var latitude:Float=latitud.floatValue self.zoomMapAndCenterAtLatitude(latitude) self.zoomMapAndCenterAtLongitud(longitude)
回答3:
Short answer:
enable Zombies in the Scheme and it will enable a breakpoint and proper reason will be displayed in the logs
Technical reason:
You are trying to do something which in not allowed in the architecture refer this What's the meaning of exception code "EXC_I386_GPFLT"?
回答4:
This response you are getting :"http://maps.googleapis.com/maps/api/geocode/json?address=Hyderabad,india"
You can fetch like below:
Here jsondict is your respnse from api
NSArray *results = [jsonDict objectForKey:@"results"]; NSDictionary *geometry = [[results objectAtIndex:0] valueForKey:@"geometry"]; NSArray *location = [geometry objectForKey:@"location"]; float lat = [[location valueForKey:@"lat"] floatValue]; float lng = [[location valueForKey:@"lng"] floatValue];
回答5:
use this :
var longitud:NSString =(mapServerResultArray.objectAtIndex(0).valueForKey("geometry").objectForKey("location").valueForKey("lng")) as NSString var latitud :NSString = (mapServerResultArray .objectAtIndex(0).valueForKey("geometry").objectForKey("location").valueForKey("lat")) as NSString placeName=mapServerResultArray .objectAtIndex(0).valueForKey("formatted_address") as NSString var longitude:Float=longitud.floatValue var latitude:Float=latitud.floatValue self.zoomMapAndCenterAtLatitude(latitude) self.zoomMapAndCenterAtLongitud(longitude)