我不知道这是怎么发生的,为什么会发生这种情况,不管怎么说呢?
崩溃正在这个方法中发生
func getLocation(completion: @escaping (String) -> Void) {
guard let longitude = (locationManager.location?.coordinate.longitude) else {
return
}
guard let latitude = (locationManager.location?.coordinate.latitude) else { return }
let location = CLLocation(latitude: latitude, longitude: longitude)
print(location)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
print(location)
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
print("locality is \(pm.locality)") //prints: locality is nil
completion(pm.locality!) //crash: fatal error: unexpectedly found nil while unwrapping an Optional value
}
else {
print("Problem with the data received from geocoder")
}
})
}
并在viewDidLoad中调用此函数,如下所示
getLocation( completion: {
locality in
self.city = locality
print("youre living in \(self.city)")
})
就像我说这在模拟器中完美运行(我的位置设置是城市自行车骑行)
如果有更好的方式来吸引用户,我可以选择解决方案。
答案 0 :(得分:3)
您编写的代码completion(pm.locality!)
已完成Forced Unwrapping。您尝试访问pm的locality属性,通过在locality之后放置一个感叹号来强制解包其值,您会触发运行时错误,因为没有值可以解包。强制解包只有在您确定它时才会执行包含一个值。
可选链接是强制解包的替代方法,可通过在可选值之后放置问号标记来完成。例如
if let locality = pm?.locality {
print(locality)
}
这告诉Swift在可选的pm属性上“链”并在pm存在时检索locality的值。 如果您仍然对可选项感到困惑,可以获取详细信息Here
func getLocation(completion: @escaping (String) -> Void) {
guard let longitude = (locationManager.location?.coordinate.longitude) else {
return
}
guard let latitude = (locationManager.location?.coordinate.latitude) else { return }
let location = CLLocation(latitude: latitude, longitude: longitude)
print(location)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
print(location)
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}else{
var address:String = "Not Found"
let placeArray = placemarks
// Place details
var placeMark: CLPlacemark?
placeMark = placeArray?[0]
// Street address
if let street = placeMark?.addressDictionary?["Thoroughfare"] as? NSString {
address = street as String
}
// City
if let city = placeMark?.addressDictionary?["City"] as? NSString {
address += "," + (city as String)
}
completion(address)
}
})
}
答案 1 :(得分:1)
试试这个:
let geoCoder = CLGeocoder()
let location = CLLocation(latitude:latitude, longitude:longitude)
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
// Place details
var placeMark: CLPlacemark!
placeMark = placemarks?[0]
// Address dictionary
print(placeMark.addressDictionary)
// Location name
if let locationName = placeMark.addressDictionary!["Name"] as? NSString {
print(locationName)
}
// Street address
if let street = placeMark.addressDictionary!["Thoroughfare"] as? NSString {
print(street)
}
// City
if let city = placeMark.addressDictionary!["City"] as? NSString {
print(city)
}
// Zip code
if let zip = placeMark.addressDictionary!["ZIP"] as? NSString {
print(zip)
}
// Country
if let country = placeMark.addressDictionary!["Country"] as? NSString {
print(country)
}
})