反向地理编码局部在设备上返回nil,在模拟器上工作

时间:2016-11-24 10:57:23

标签: swift ios-simulator

我不知道这是怎么发生的,为什么会发生这种情况,不管怎么说呢?

崩溃正在这个方法中发生

  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)")
    })

就像我说这在模拟器中完美运行(我的位置设置是城市自行车骑行)

如果有更好的方式来吸引用户,我可以选择解决方案。

2 个答案:

答案 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)
            }

        })