展开 CLLocation 位置坐标时出现致命错误

Fatal error when unwrapping CLLocation Location Coordinate

我目前有一个测试应用程序可以自学 Core Location。这是一个带有按钮的应用程序,当您按下按钮时,它会显示您的位置,或者在定位服务关闭时发出警报。

我收到一个致命错误(展开选项值时意外发现 nil)当位置服务打开时,我尝试打印字符串。我在文档中找不到 CLLocationManager.location.coordinate returns 可选值的任何地方。我将包括代码片段。谢谢!

let locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    if CLLocationManager.authorizationStatus() == .NotDetermined {
    locationManager.requestWhenInUseAuthorization()
    }
}

@IBAction func testLocation(sender: AnyObject) {
    switch CLLocationManager.authorizationStatus() {
    case .AuthorizedAlways, .AuthorizedWhenInUse:
        printCurrentCoordinates()
    case .Restricted, .Denied:
        disabledLocationSeriveAlert()
    default:
        println("Failed")
    }
func printCurrentCoordinates() {
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.startUpdatingLocation()
    println("\(locationManager.location.coordinate.latitude)")
    println("\(locationManager.location.coordinate.longitude)")
}

func disabledLocationSeriveAlert() {
    let alert = UIAlertController(title: "Unable to retrieve location", message: "Enable location services in system settings", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
    self.presentViewController(alert, animated: true, completion: nil)
}

问题是 locationManagerlocation 属性 届时将是 nil

属性 包含最近检索到的位置数据。你刚刚分配了location manager,那时候那个属性里面不会有任何数据。

根据CLLocationManager Class Reference

location

Property The most recently retrieved user location. (read-only)

Declaration

@NSCopying var location: CLLocation! { get }

Discussion

The value of this property is nil if no location data has ever been retrieved.

您似乎没有给 CLLocationManager 足够的时间来更新位置。


我查看了文档,在声明 locationManager.location.coordinate.latitude 中,location 是唯一一个可选的。它是隐式展开的,所以这就是为什么你不需要在它后面添加 ! 的原因。

printCurrentCoordinates 方法中,您尝试在调用 startUpdatingLocation 后立即打印坐标。 location 的文档说:

The value of this property is nil if no location data has ever been retrieved.

startUpdatingLocation 的文档说:

This method returns immediately. Calling this method causes the location manager to obtain an initial location fix (which may take several seconds) and notify your delegate by calling its locationManager:didUpdateLocations: method.

因此,在尝试打印位置之前,您没有给位置管理器足够的时间来修复位置。

您有几个选择 - 您可以提前调用 startUpdatingLocation 然后在 printCurrentCoordinates 中打印坐标,或者您可以让 printCurrentCoordinates 开始更新位置然后打印locationManager:didUpdateLocations:.

中的坐标

location 未设置时为零(来自文档)

The value of this property is nil if no location data has ever been retrieved.

您必须使用委托来获取位置。这是异步操作,因此调用后值不可用 startUpdatingLocation()

您必须实施 CLLocationManagerDelegate(并将您的对象设置为委托)并等待 locationManager:didUpdateLocations: 方法 - 只有这样 location 才会有一些数据。

获取位置是一个异步操作 - 实际上,您调用以启动操作的方法是 startUpdatingLocation() 而不是 getLocation()。这表明进程已启动,但在调用方法时尚未完成 returns.

位置通过 func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) 方法异步提供,该方法是您必须在 class 中采用的 CLLocationManagerDelegate 协议的一部分。当然,您必须设置 CLLocationManager 实例的 delegate 属性。如果您曾经使用过表格,您应该知道它是如何工作的。

但是,我建议阅读官方文档,或者像this one

这样的好教程