我目前有一个测试应用程序来自学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)
}
答案 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
这样的好教程