如何在 iOS 应用程序中强制“始终”访问位置

kiu*_*iho 5 location cllocationmanager ios swift

我正在构建的应用程序始终需要位置访问才能正常工作。该应用程序基本上跟踪位置并将其放在地图上和其他东西上(细节并不重要,哈哈)。

我的目标是这样的:

  1. 提示用户启用“始终”位置访问
  2. 如果总是请求位置访问但用户拒绝,则使应用程序无法使用 - 基本上只是显示一个小按钮,将他们重定向到可以更改该设置的设置。

我的AppDelegate.swift正在实现CLLocationManagerDelegate,代码如下:

alreadyRequestedLocationWhenInUse = UserDefaults.standard.bool(forKey: "alreadyRequestedLocationWhenInUse")
alreadyRequestedLocationAlways = UserDefaults.standard.bool(forKey: "alreadyRequestedLocationAlways")

        func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
      
        switch CLLocationManager.authorizationStatus() {
        case .notDetermined:
            if (!alreadyRequestedLocationWhenInUse) {
                print("Requesting location access 'while in use'.")
                self.locationManager.requestWhenInUseAuthorization();
                UserDefaults.standard.set(true, forKey: "alreadyRequestedLocationWhenInUse")
                alreadyRequestedLocationWhenInUse = true
            } else {
                promptToChangeLocationSettings()
            }
        case .restricted, .denied:
            print("No Location access")
            promptToChangeLocationSettings()
            break;
        case .authorizedWhenInUse:
            if (!alreadyRequestedLocationAlways) {
                print("Requesting location access 'Always'.")
                self.locationManager.requestAlwaysAuthorization()
                UserDefaults.standard.set(true, forKey: "alreadyRequestedLocationAlways")
                alreadyRequestedLocationAlways = true
            } else {
                promptToChangeLocationSettings()
            }
            break;
        case .authorizedAlways:
            self.startLocationMonitoring();
            break;
        default:
            self.locationManager.requestAlwaysAuthorization();
            return
        }
    }
Run Code Online (Sandbox Code Playgroud)

其中promptToChangeLocationSettings()是一个正常工作的函数,它将用户带到我的应用程序的设置页面。

问题是,在用户退出应用程序并返回之前,系统不会提示用户启用“始终位置跟踪”。他们被要求提供“使用时”权限(我知道它的工作方式是他们必须首先对此说“是”),但我希望始终提示立即发生!理论上,在授予“使用时”授权后应该再次调用 locationManagerDidChangeAuthorization 函数,但这种情况不会发生!为什么这不会发生?相反,在用户收到询问是否要启用“始终”位置访问的小弹出窗口之前,promptUserToChangeLocationSettings() 会运行并使应用程序无法使用。

有人可以帮我解决这个问题吗?顺便说一句,我正在使用 UserDefaults 来跟踪我们是否已完成位置权限请求(因为该请求只能完成一次)。

Rob*_*Rob 4

关于这个流程的一些观察,我们在使用时首先请求 \xe2\x80\x9c,当被授予时,才请求 \xe2\x80\x9calways\xe2\x80\x9d (如在 WWDC 2020位置新增内容中讨论):

\n
    \n
  1. 确保您在设备上运行它,而不是模拟器。您可能看不到后续的 \xe2\x80\x9cupgrade \xe2\x80\x98when-in-use\xe2\x80\x99 to \xe2\x80\x98always\xe2\x80\x99\xe2\x80\x9d 权限警报使用模拟器。

    \n
  2. \n
  3. 该功能是在 iOS 13.4 中引入的。确保您没有在早期的 iO​​S 13 版本上尝试此操作。在这些早期版本中,\xe2\x80\x99不会看到升级到 \xe2\x80\x9calways\xe2\x80\x9d 的第二个警报。

    \n
  4. \n
  5. 确保您requestAlwaysAuthorization的代码库中的其他位置没有\xe2\x80\x99t 的残留,这可能会使应用程序处于\xe2\x80\x9c临时始终\xe2\x80\x9d 状态。一旦进入临时状态,您将被锁定在 13.0 的临时流程中。

    \n
  6. \n
\n
\n

我知道这不是您所寻找的\xe2\x80\x99t,但为了未来的读者,上述的替代方案是更简单的\xe2\x80\x9cprovisionalalways\xe2\x80\x9d iOS 13.0 中引入的流程(WWDC 2019 的核心位置新增内容中概述)。你只是打电话requestAlwaysAuthorization(从不打电话requestWhenInUseAuthorization)。Apple 的目的是让用户更好地了解正在发生的情况,在应用程序使用时显示 \xe2\x80\x9cwhen in use\xe2\x80\x9d 警报并自动显示当应用程序未运行时使用位置服务时,\xe2\x80\x9calways\xe2\x80\x9d 升级警报。

\n