【问题标题】:How to get user location?如何获取用户位置?
【发布时间】:2019-11-20 17:31:14
【问题描述】:

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

【问题讨论】:

  • 您是否成功获取了该位置?我也有问题
  • @SUMITNIHALANI 在下面看到我的回答。

标签: swift xcode macos cllocationmanager


【解决方案1】:

这里的问题是,在 10.15 之前的 macOS 上,没有像在 iOS 上那样显式调用请求位置访问。拨打startUpdatingLocation()时自动提示用户权限。

在您上面的代码中,执行永远不会到达该调用,因为您的函数startReceivingLocationChanges 总是在它检查当前状态的第一条语句中返回(这很可能是“状态尚未确定”)。因此它永远不会在该函数中进一步调用startUpdatingLocation(),因此永远不会提示用户允许位置报告。

在 macOS 10.15 中,requestAlwaysAuthorization() 可用,但如果您只需要在使用应用时使用位置信息,则似乎不需要。

此外,在 macOS 上,.authorized 似乎比 .authorizedAlways 更受欢迎(记录为同义词),尽管在 10.15 中添加了 requestAlwaysAuthorization() 函数,他们可能会改变这一点(尽管文档尚未更新为表明在回答此问题时发生了这种情况)。

如果您不调用requestAlwayAuthorization(),那么似乎只需要NSLocationWhenInUseUsageDescription info.plist 键。

另外,需要在macOS应用项目的“Signing & Capabilities”下的“Hardened Runtime”中设置“Location”复选框。这是我正在测试的 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 上如果我在第一次启动应用程序时对“启用位置服务”提示说“是”

控制台输出(稍微混淆):

位置管理器身份验证状态更改为:状态尚未确定 位置管理器身份验证状态更改为:状态授权位置: 可选( +/- 65.00m (速度-1.00 mps / 课程 -1.00) @ 2019 年 11 月 15 日,太平洋标准时间上午 10:24:30)

制作此示例的步骤:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      还要检查您的模拟器调试是否模拟了用户位置。

      【讨论】:

      • 醒来。 macOS 没有所谓的模拟器或模拟器。
      • @nomadoda 检查我的编辑。请求授权不可用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多