iOS应用需强制开启Always On位置权限的技术问题求助
实现强制要求Always On位置权限的解决方案
一、前置强引导,明确权限必要性
在调用系统权限请求弹窗前,先弹出自定义提示页/弹窗,直白告知用户:本应用核心功能完全依赖「始终允许」位置权限,选择「使用期间允许」或「允许一次」将无法正常使用全部功能,请务必选择「始终允许」,避免用户误选低权限选项。
二、直接通过权限状态值区分授权结果
iOS 14及以上系统中,CLAuthorizationStatus新增了authorizedOnce枚举值,无需依赖应用活跃状态变化判断,直接读取权限状态即可精准区分三种授权结果:
authorizedAlways:用户选择「始终允许」,正常进入应用流程authorizedWhenInUse:用户选择「使用期间允许」authorizedOnce:用户选择「允许一次」
示例代码(Swift):
import CoreLocation class LocationPermissionManager: NSObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() override init() { super.init() locationManager.delegate = self } // 发起始终允许权限请求 func requestAlwaysPermission() { locationManager.requestAlwaysAuthorization() } // 监听权限状态变更 func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { switch manager.authorizationStatus { case .authorizedAlways: // 权限符合要求,跳转主应用界面 enterMainApp() case .authorizedWhenInUse, .authorizedOnce: // 权限不达标,弹出强制引导弹窗 showPermissionRequiredAlert() case .denied, .restricted: // 权限被拒绝/受限,引导去系统设置修改 showGoToSettingsAlert() default: break } } // 提示用户必须选择始终允许权限的弹窗 private func showPermissionRequiredAlert() { let alert = UIAlertController(title: "权限要求", message: "本应用需要始终允许位置权限才能使用,请重新授权", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "重新授权", style: .default, handler: { [weak self] _ in self?.locationManager.requestAlwaysAuthorization() })) alert.addAction(UIAlertAction(title: "取消", style: .cancel, handler: { _ in // 取消则退出应用或停留在引导页 exit(0) })) UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true) } // 引导用户前往系统设置的弹窗 private func showGoToSettingsAlert() { let alert = UIAlertController(title: "权限被拒绝", message: "请前往系统设置开启始终允许位置权限", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "去设置", style: .default, handler: { _ in guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return } UIApplication.shared.open(settingsURL) })) alert.addAction(UIAlertAction(title: "取消", style: .cancel, handler: { _ in exit(0) })) UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true) } private func enterMainApp() { // 这里写跳转主应用界面的逻辑 } }
三、启动时校验权限,拦截非合规状态
在AppDelegate的启动方法或SceneDelegate的场景连接方法中,先检查当前权限状态,若未获得「始终允许」权限,直接显示引导页或发起权限请求,禁止进入主功能:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let currentStatus = CLLocationManager.authorizationStatus() if currentStatus != .authorizedAlways { let permissionManager = LocationPermissionManager() permissionManager.requestAlwaysPermission() // 设置根视图控制器为权限引导页 window?.rootViewController = PermissionGuideViewController() } else { // 权限合规,进入主界面 window?.rootViewController = MainTabBarController() } return true }
四、处理「允许一次」权限过期场景
「允许一次」权限仅在当前会话有效,应用退后台重启后会回到未授权状态,因此每次启动都必须重新校验权限,确保只有持有「始终允许」权限的用户才能使用应用。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

