我正在尝试使用以下代码获取用户的当前位置,但它不起作用。我已将NSLocationWhenInUseUsageDescription
密钥和NSLocationAlwaysUsageDescription
密钥添加到我的Info.plist
文件中。
以下是代码
var locationManager = CLLocationManager();
override func viewDidLoad() {
super.viewDidLoad()
startReceivingLocationChanges();
}
func startReceivingLocationChanges() {
let authorizationStatus = CLLocationManager.authorizationStatus()
if authorizationStatus != .authorizedAlways {
// User has not authorized access to location information.
print("not authorized");
return
}
if !CLLocationManager.locationServicesEnabled() {
print("not enabled");
return
}
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 100.0 // In meters.
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let lastLocation = locations.last!
print(lastLocation)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error);
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print("inside didChangeAuthorization ");
}
我已经阅读了苹果文档,上面是苹果建议的代码。我在这里失踪了什么?任何形式的帮助都非常感谢。感谢
答案 0 :(得分:3)
由于某种原因,requestAlwaysAuthorization()不可用。
requestAlwaysAuthorization()
不可用,因为您在macOS中工作,the documentation表明该方法仅适用于iOS和watchOS。请参阅页面右侧的SDK列表,靠近顶部:
答案 1 :(得分:1)
这里的问题是,在10.15之前的macOS上,没有像iOS上那样显式调用请求位置访问。呼叫startUpdatingLocation()
时,会自动显示用户权限提示。
在上面的代码中,执行永远不会被调用,因为函数startReceivingLocationChanges
总是在检查当前状态的第一条语句中返回(最有可能是“尚未确定的状态”)。因此,它永远不会深入到该功能的startUpdatingLocation()
调用中,因此永远不会提示用户允许位置报告。
在macOS 10.15中,requestAlwaysAuthorization()
可用,但如果在使用应用程序时只需要使用位置,则似乎并不需要。
此外,在macOS上,.authorized
似乎比.authorizedAlways
(已被证明是同义词)更受青睐,尽管在10.15中添加了requestAlwaysAuthorization()
函数,它们可能会对此进行更改(尽管文档尚未更新,以指示在此答案时已发生这种情况。
如果您不拨打requestAlwayAuthorization()
,则似乎只需要NSLocationWhenInUseUsageDescription
info.plist键。
此外,有必要在macOS应用程序项目的“签名和功能”下的“强化运行时”中设置“位置”复选框。这是我正在测试的macOS 10.14.6上的Xcode 11.2.1所必需的。较旧的设置或未采用强化运行时的设置(现在为默认设置),可能必须在项目构建设置中的其他位置进行设置。
这是NSViewController子类的源,该子类在macOS 10.14.6的Xcode 11.2.1中成功检查了位置管理器和当前位置:
import Cocoa
import CoreLocation
class ViewController: NSViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
print("starting location update requests")
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
print("location manager auth status changed to:" )
switch status {
case .restricted:
print("status restricted")
case .denied:
print("status denied")
case .authorized:
print("status authorized")
let location = locationManager.location
print("location: \(String(describing: location))")
case .notDetermined:
print("status not yet determined")
default:
print("unknown state: \(status)")
}
}
func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print( "location manager failed with error \(error)" )
}
}
如果我在首次启动应用程序时对“启用位置服务”提示说“是”,则在macOS 上这对我有用。
控制台输出(被稍微混淆):
位置管理器身份验证状态更改为:状态尚未确定 位置管理员身份验证状态更改为:状态授权位置: 可选(<+ 4X.48,-12X.62632228> +/- 65.00m(速度-1.00 mps / 课程-1.00)@ 19/15/19,上午10:24:30(太平洋标准时间)
制作此示例的步骤:
NSLocationWhenInUseUsageDescription
键添加到info.plist 答案 2 :(得分:-1)
确保位置管理员有权查找用户的位置。在致电位置更新之前,您应该致电locationManager.requestAlwaysAuthorization()
。
同时检查您的模拟器调试是否模拟用户位置。