解包CLLocation位置坐标时出现致命错误

时间:2015-06-15 19:45:30

标签: ios iphone swift ios8 optional

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

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

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

4 个答案:

答案 0 :(得分:5)

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

我查看了文档,在locationManager.location.coordinate.latitude语句中,location是唯一可选的文档。它是隐式展开的,这就是为什么你不需要!之后的原因。

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

  

如果从未检索到任何位置数据,则此属性的值为nil

startUpdatingLocation的文档说:

  

此方法立即返回。调用此方法会导致位置管理器获取初始位置修复(可能需要几秒钟)并通过调用其locationManager:didUpdateLocations:方法通知您的代理。

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

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

答案 1 :(得分:3)

问题是location当前locationManager的{​​{1}}属性为nil

该属性包含最近检索到的位置数据。您刚刚分配了位置管理器,那时候该属性中没有任何数据。

根据CLLocationManager Class Reference

  

location

     

属性最近检索到的用户位置。   (只读)

     

<强>声明

     

@NSCopying var location: CLLocation! { get }

     

<强>讨论

     

如果没有位置数据,则此属性的值为nil   曾被检索过。

答案 2 :(得分:3)

未设置时,

location为nil(来自doc)

  

如果从未检索到任何位置数据,则此属性的值为nil。

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

之后,值不可用

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

答案 3 :(得分:3)

获取位置是一种异步操作 - 实际上,您调用以启动操作的方法是startUpdatingLocation()而不是getLocation()。这表示进程已启动,并且在调用的方法返回时未完成。

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

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

这样的好教程