如何解决如何在iOS应用中强制“始终”进行位置访问
我正在构建的应用需要始终具有位置访问权限才能正常运行。该应用程序基本上会跟踪位置,并将其放在地图和其他内容上(细节并不重要,哈哈)。
我的目标是:
我的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
}
}
其中hintTotochangeLocationSettings()是可以正常工作的功能,可将用户带到我的应用程序的设置页面。
问题在于,直到他们退出应用程序并返回时,系统不会提示用户启用“始终位置跟踪”。他们被要求获得“使用中”权限(我知道它的工作方式是必须首先对它说“是”),但是我希望始终提示总是马上发生!理论上,在授予“使用时”授权后,应该再次调用locationManagerDidChangeAuthorization函数,但这不会发生!为什么不会发生这种情况?相反,在用户收到询问他们是否要启用“始终”位置访问的小提示之前,会运行hintUsertochangeLocationSettings()并使其无法使用。
有人可以帮我解决这个问题吗? 顺便说一句,我正在使用UserDefaults来跟踪我们是否已完成位置许可请求(因为该请求只能执行一次)。
解决方法
关于此流程的一些观察结果,我们首先请求“在使用中”,然后在获得许可时才请求“始终”(如WWDC 2020 What's New in Location中所述):
-
确保在设备而不是模拟器上运行它。使用模拟器时,您可能看不到随后的“在使用中”升级为“始终””权限警报。
-
此功能在iOS 13.4中引入。确保您不在较早的iOS 13版本上尝试这样做。在那些较早的版本上,您将不会看到第二个警报升级到“始终”。
-
请确保您在代码库中的其他地方没有挥之不去的
requestAlwaysAuthorization
,这可能会使该应用程序处于“始终临时”状态。进入临时状态后,您将被锁定在13.0的临时流程中。
我知道这不是您想要的,但是为了将来的读者,上述的替代方法是iOS 13.0中引入的更简单的“ provisional always”流程(在WWDC 2019的{{3}中概述})。您只需致电requestAlwaysAuthorization
(就不会致电requestWhenInUseAuthorization
)。 Apple的目的是让用户更好地了解正在发生的事情,在应用程序使用时显示“使用中”警报,并在应用程序未运行时使用位置服务时自动显示“始终”升级警报。
这是一个解决方案,得到了我想要的结果: 首先:在AppDelegate.swift didFinishLaunchingWithOptions函数中调用locationManagerDidChangeAuthorization(locationManager)。我也在applicationWillEnterForeground中调用了它,以便每次打开应用程序时都会重新检查。
第二,这是我的新locationManagerDidChangeAuthorization函数。只需删除return / break语句,但在忘记之前我要立即回答:
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch CLLocationManager.authorizationStatus() {
case .notDetermined:
UserDefaults.standard.set(false,forKey: "alreadyRequestedAlwaysLocationAccess")
alreadyRequestedAlwaysLocationAccess = false
DispatchQueue.main.async{
self.coreLocationManager.requestWhenInUseAuthorization()
self.locationManagerDidChangeAuthorization(manager)
}
break;
case .restricted,.denied:
print("No Location access")
promptToChangeLocationSettings()
break;
case .authorizedWhenInUse:
if (!alreadyRequestedAlwaysLocationAccess) {
print("Requesting location access 'Always'.")
UserDefaults.standard.set(true,forKey: "alreadyRequestedAlwaysLocationAccess")
alreadyRequestedAlwaysLocationAccess = true
DispatchQueue.main.async{
self.coreLocationManager.requestAlwaysAuthorization()
self.locationManagerDidChangeAuthorization(manager)
}
} else {
promptToChangeLocationSettings()
}
break;
case .authorizedAlways:
self.startLocationMonitoring();
break;
default:
return
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。