展开 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)
}
问题是 locationManager
的 location
属性 届时将是 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
这样的好教程
我目前有一个测试应用程序可以自学 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)
}
问题是 locationManager
的 location
属性 届时将是 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
这样的好教程