检测 requestAlwaysAuthorization 何时未调用 iOS 14
Posted
技术标签:
【中文标题】检测 requestAlwaysAuthorization 何时未调用 iOS 14【英文标题】:Detect when requestAlwaysAuthorization not called iOS 14 【发布时间】:2020-11-10 01:28:33 【问题描述】:我正在尝试使用多步骤流程请求用户的位置;但是,当调用requestAlwaysAuthorization
时,如果它没有被执行,我想移动以显示一条消息。
让我通过展示我的流程来更好地解释
这是我目前的流程
-
请求
While in use
用户选择Allow Once
-> 转到2
用户选择Allow While Using App
-> 转到2
用户选择Don't Allow
-> 显示错误信息
请求Always permission
用户选择 Keep Only While Using
-> 显示错误消息(问题 #1:我无法检测到这个)
用户选择Change to Always Allow
-> 显示成功消息
如果用户从1
选择Allow Once
,我什至不能调用requestAlwaysAuthorization
,因为调用它会导致任何结果,甚至Apple 状态
如果用户使用 Allow Once 响应 requestWhenInUseAuthorization(),则由于临时授权,Core Location 将忽略对 requestAlwaysAuthorization() 的进一步调用。
Source
我的目标是,如果用户从1
中选择Allow Once
,那么应该一起跳过requestAlwaysAuthorization
。
如果从1
选择Allow Wile Using App
并从requestAlwaysAuthorization
选择Keep Only while using
,那么我想知道那个状态。
我知道可以做到,只是不知道怎么做。这是一个可以实现我想要实现的应用程序
从第一张图片中,用户选择了Allow While Using App
,然后选择了Keep Only While Using
,他们能够检测到它,或者能够检测到对话出现的事实,并且在用户响应之前他们没有移动到第三张图片。
另一种情况如下:
从用户选择的第一张图片Allow Once
和从第二张图片,无论用户选择什么,他们都会转到图片 3,而不显示始终权限(请记住,第二张图片不是真正的权限,它只是用来欺骗用户的按钮);因此他们能够分辨出对话没有出现,或者用户从上一步中选择了Allow Once
(一个或另一个,我不能做任何一个)。
显然我无法记录每个组合并以 gif 格式发布,所以如果您想体验应用程序名称是 Zenly
因此,最终目标是能够等待用户响应对话(如果出现对话),否则只需移动到下一个屏幕。
这是我所做的,引用自苹果
核心位置将授权保留为使用时。委托没有收到任何更新。
我想也许在总是请求时我也应该手动执行委托,所以我在函数 requestAlwaysLocation()
中添加了这一行
self.locationManagerDidChangeAuthorization(self.locationManager)
但是,这显然行不通,因为在Allow While Using App
是从步骤1
中选择的情况下,Change to Always Allow
是从步骤2
中选择的,现在委托将被调用两次...
然后我想如果我可以从步骤1
检测到配置When in Use
,我也许可以绕过但我不知道该怎么做。
这是LocationManager
的sn-p
func requestWhenInUserLocation()
self.locationManager.requestWhenInUseAuthorization()
func requestAlwaysLocation()
self.locationManager.requestAlwaysAuthorization()
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager)
print("authroizatino changed")
// let accuracyAuthorization = manager.accuracyAuthorization
let status = manager.authorizationStatus
// -change function will just change some internal properties and will post a notification so views that subscribe to it can react accordingly.
switch status
case CLAuthorizationStatus.authorizedAlways:
self.change(permission: .Location, to: .Location(.Always))
break
case CLAuthorizationStatus.authorizedWhenInUse:
self.change(permission: .Location, to: .Location(.WhenInUse))
break
case CLAuthorizationStatus.denied:
self.change(permission: .Location, to: .Denied)
break
case CLAuthorizationStatus.notDetermined:
self.change(permission: .Location, to: .NotDetermined)
break
case CLAuthorizationStatus.restricted:
self.change(permission: .Location, to: .Location(.Restricted))
break
@unknown default:
self.change(permission: .Location, to: .Unknown)
break
我希望我能够清楚地解释我想要什么
【问题讨论】:
这看起来像是一个用例,您不应该尝试绕过 Apple 实施的流程。只需询问“始终”,然后启用后台位置更新。 ios会在适当的时候提示用户升级你的位置访问权限。 如何解决? Apple 确实允许您在任何时候提示always
许可。我认为您指的是我正在尝试检测Allow Once
或者在请求always
时权限保持不变。不幸的是,有这种要求的有效案例;例如,像Zenly
这样的应用程序没有它就无法运行,因此他们需要它作为入职培训的一部分。我正在构建的应用程序处于类似情况。我不想实现它,因为我明白为什么它可以被视为workaround
,但它不是我的应用程序,这是客户的应用程序。
另外请注意,使用 iOS 14,您不必等待 iOS 选择何时升级通知。如果您像我一样将其分解为 2 个步骤,您可以随时提出请求。
我理解这个过程。更改的行为是在 iOS 13.4 中引入的,我在商店中有一个应用程序可以执行您正在尝试的操作,因为它确实需要始终获得许可,或者它只是不起作用。但是,如果你告诉用户为什么你总是需要,总是提示他们而你没有它,那么你就不得不忍受它。您可以在下次应用启动时再次检查。您还可以在 didBecomeActive
事件之后检查,因为这意味着对话框已被关闭
我曾尝试向他们解释这一点,但如果未提供always
,他们坚持要阻止用户在入职期间访问应用程序。话虽如此,你写的最后一句话是golden key
。非常感谢,我不知道我怎么从来没想过这样做。 hiding in plain sight
这句话在这里绝对适用。再次感谢。
【参考方案1】:
感谢@Paulw11,我能够解决它。其实很简单。
我不能在这里添加任何实现,因为它真的取决于一个人的用例,而且我使用的是 SwiftUI。
所以我所做的就是在按下Request Always
按钮时创建一个bool
状态并将其设置为true,我还有一个应用程序的活动状态的观察者这是解决这个问题的关键 我在bool
状态上也有一个观察者。
如果布尔状态发生变化,而应用的活动状态没有变化,则用户选择了Allow Once
;但是,如果状态确实发生了变化,那么我会等待它再次处于活动状态。
如果它变为活动状态,我会检查位置权限,如果它仍然是When in Use
,那么用户选择Keep Only While Using
,否则他们选择Change to Always
所有学分都归于 Paulw11
编辑:如果用户从设置更改位置权限,我也有应用程序从后台进入前台的观察者
注意:如果您在 SwiftUI 中使用Combine
,上述算法可以得到很大的改进。我写的大部分都没用,你可以订阅权限和应用的活动状态。
【讨论】:
以上是关于检测 requestAlwaysAuthorization 何时未调用 iOS 14的主要内容,如果未能解决你的问题,请参考以下文章
行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测)
行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测)
行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测)