简体   繁体   English

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

[英]Fatal error when unwrapping CLLocation Location Coordinate

I currently have a test application to teach myself Core Location.我目前有一个测试应用程序来自学核心位置。 It is an app with a button which will either show your location when you press a button, or an alert when location services are off.这是一个带有按钮的应用程序,当您按下按钮时会显示您的位置,或者在位置服务关闭时发出警报。

I get a fatal error (unexpectedly found nil when unwrapping option value) When location services are on and I attempt to println the string.我收到一个致命错误(在解包选项值时意外发现 nil)当位置服务打开时,我尝试打印字符串。 I cannot find anywhere in the documentation where the CLLocationManager.location.coordinate returns an optional value.我在文档中找不到 CLLocationManager.location.coordinate 返回可选值的任何地方。 I will include the code snippet.我将包括代码片段。 Thanks!谢谢!

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

It looks like you aren't giving the CLLocationManager enough time to update the location.看起来您没有给CLLocationManager足够的时间来更新位置。


I looked at the documentation, and in the statement locationManager.location.coordinate.latitude , location is the only one that's an optional.我查看了文档,在locationManager.location.coordinate.latitude语句中, location是唯一一个可选的。 It's implicitly unwrapped, so that's why you don't need an !它是隐式解包的,所以这就是为什么你不需要! after it.之后。

In the printCurrentCoordinates method, you attempt to print the coordinates immediately after you call startUpdatingLocation .printCurrentCoordinates方法中,您尝试在调用startUpdatingLocation后立即打印坐标。 The documentation for location says: location的文档说:

The value of this property is nil if no location data has ever been retrieved.如果从未检索过位置数据,则此属性的值为nil

And the documentation for startUpdatingLocation says: 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.调用此方法会导致位置管理器获取初始位置修复(可能需要几秒钟)并通过调用它的locationManager:didUpdateLocations:方法通知您的委托。

So, you aren't giving the location manager enough time to get a location fix before you attempt to print the location.因此,在您尝试打印位置之前,您没有给位置管理器足够的时间来获取位置修复。

You have a couple of choices - you can call startUpdatingLocation earlier and then print the coordinates in printCurrentCoordinates , or you could have printCurrentCoordinates start updating the location and then print the coordinates in locationManager:didUpdateLocations: .您有几个选择 - 您可以提前调用startUpdatingLocation ,然后在printCurrentCoordinates打印坐标,或者您可以让printCurrentCoordinates开始更新位置,然后在locationManager:didUpdateLocations:打印坐标。

The issue is location property of locationManager will be nil at that time.问题是location的财产locationManager将是nil ,在那个时候。

That property contains the most recently retrieved location data.该属性包含最近检索的位置数据。 You just allocated location manager, at that time there won't be any data in that property.您刚刚分配了位置管理器,那时该属性中将没有任何数据。

According to CLLocationManager Class Reference :根据CLLocationManager 类参考

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.如果从未检索过位置数据,则此属性的值为 nil。

location is nil when not set (from doc)未设置时location为零(来自文档)

The value of this property is nil if no location data has ever been retrieved.如果从未检索过位置数据,则此属性的值为 nil。

You have to use delegate to get the location.您必须使用委托来获取位置。 This is asynchronous operation, so value not available right after call startUpdatingLocation()这是异步操作,因此在调用startUpdatingLocation()后值不可用

You must implement CLLocationManagerDelegate (and set your object as delegate) and wait for locationManager:didUpdateLocations: method - only then location will have some data.您必须实现 CLLocationManagerDelegate(并将您的对象设置为委托)并等待locationManager:didUpdateLocations:方法 - 只有这样location才会有一些数据。

Obtaining the location is an asynchronous operation - in fact the method you invoke to start the op is startUpdatingLocation() and not getLocation() .获取位置是一个异步操作 - 事实上,您调用来启动操作的方法是startUpdatingLocation()而不是getLocation() That is an indication that the process is started, and it's not completed at the time the invoked method returns.这表明进程已启动,并且在调用的方法返回时尚未完成。

The location is provided asynchronously via the func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) method, part of the CLLocationManagerDelegate protocol that you must adopt in your class.位置是通过func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)方法异步提供的,该方法是您必须在类中采用的CLLocationManagerDelegate协议的一部分。 And of course you have to set the delegate property of the CLLocationManager instance.当然,您必须设置CLLocationManager实例的delegate属性。 If you have ever worked with tables, you should know how it works.如果您曾经使用过表格,您应该知道它是如何工作的。

However, I recommend reading the official docs, or a good tutorial likethis one但是,我建议阅读官方文档,或者像这样的好教程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM