如何获得用户位置? [苹果系统]

时间:2017-08-07 19:16:27

标签: swift xcode macos cllocationmanager

我正在尝试使用以下代码获取用户的当前位置,但它不起作用。我已将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 ");
    }

我已经阅读了苹果文档,上面是苹果建议的代码。我在这里失踪了什么?任何形式的帮助都非常感谢。感谢

修改 由于某种原因,requestAlwaysAuthorization()不可用。见下面的截图 enter image description here

3 个答案:

答案 0 :(得分:3)

  

由于某种原因,requestAlwaysAuthorization()不可用。

requestAlwaysAuthorization()不可用,因为您在macOS中工作,the documentation表明该方法仅适用于iOS和watchOS。请参阅页面右侧的SDK列表,靠近顶部:

list of SDKs

答案 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(太平洋标准时间)

制作此示例的步骤:

  1. 打开Xcode并创建一个新的macOS项目
  2. 编辑项目模板提供的ViewController以匹配上面的代码
  3. NSLocationWhenInUseUsageDescription键添加到info.plist
  4. 在项目设置的应用目标的“签名和功能”部分中,选中“强化运行时”下的“位置”复选框。

答案 2 :(得分:-1)

确保位置管理员有权查找用户的位置。在致电位置更新之前,您应该致电locationManager.requestAlwaysAuthorization()

同时检查您的模拟器调试是否模拟用户位置。