CLLocationManager无权限变更回调缺失 Always授权申请异常方案咨询
iOS Always 位置权限申请无回调问题的可行 Workaround 方案
前置基础:修正权限状态判断逻辑
- 不要直接依赖
CLLocationManagerDelegate的权限变更回调结果作为后续流程的唯一判断依据,每次执行流程前主动调用+[CLLocationManager authorizationStatus]获取当前最新状态 - 区分「临时允许一次」和「永久使用期间授权」:用户选择「允许一次」后,授权状态会在应用退后台、进程重启后自动重置为
kCLAuthorizationStatusNotDetermined,你可以在首次拿到authorizedWhenInUse状态后,增加1.5s的延迟校验,再次主动查询权限状态,同时监听UIApplicationWillResignActiveNotification,如果短时间内退后台再返回后权限状态变回未确定,即可判定为用户选择了「允许一次」,此时终止后续Always申请流程,弹窗引导用户手动到系统设置中开启永久位置权限
问题1:用户选「允许一次」后申请Always静默失败的解决方案
- 执行Always申请前增加自定义引导弹窗:在确认拿到的是永久的
authorizedWhenInUse权限后,先弹App自定义的提示页,说明需要始终权限的用途,用户点击确认后再触发系统的Always申请 - 监听系统权限弹窗的生命周期:可以通过遍历
UIApplication.sharedApplication.windows的层级,检测到系统权限弹窗(避免直接调用私有API判断类名,可通过检测当前keyWindow的rootViewController是否存在presentedViewController,且类型为UIAlertController的通用逻辑判断),监听弹窗的dismiss事件,弹窗消失后300ms主动调用authorizationStatus查询最新权限状态,即可判断用户的选择结果,不需要依赖系统回调
问题2:用户选「仅保留使用期间授权」无回调的解决方案
- 基于上述弹窗监听的逻辑,在触发Always申请后,只要监听到系统权限弹窗消失,就立刻主动拉取最新的权限状态:
- 如果状态变为
authorizedAlways,说明用户同意了始终权限 - 如果状态还是
authorizedWhenInUse,说明用户选择了「仅保留使用期间授权」 - 如果状态变为
denied,说明用户直接拒绝了权限
- 如果状态变为
- 注意系统仅允许申请一次Always权限,所以如果本次用户选择了保留使用期间,后续不要再主动触发申请,改为引导用户到系统设置页手动修改权限
审核规避注意事项
不要使用私有API直接访问系统弹窗的类名、属性,避免审核被拒,仅通过通用的present层级判断、弹窗消失事件触发主动查询即可。
内容的提问来源于stack exchange,提问作者Anticro
相关产品推荐
相关产品推荐

