iOS开发中如何统一响应各类权限变更?
iOS 统一监听各类权限变更的可靠方式
iOS 没有为所有权限类型提供像 CLLocationManager 那样的专属代理回调,但可以通过 NotificationCenter 监听系统通知 + 前台主动校验 的组合方案,统一响应各类权限的变更:
1. 监听专属权限变更通知
大部分系统权限框架都会提供对应的权限变更通知,注册这些通知可以实时感知权限变化:
相机/麦克风权限(AVFoundation)
监听 AVCaptureDevice.authorizationStatusDidChangeNotification,相机或麦克风权限变更时会触发:
// 注册通知 NotificationCenter.default.addObserver( self, selector: #selector(onCameraAuthChanged), name: AVCaptureDevice.authorizationStatusDidChangeNotification, object: nil ) // 回调处理 @objc private func onCameraAuthChanged() { let status = AVCaptureDevice.authorizationStatus(for: .video) // 根据状态更新逻辑:比如提示用户、调整UI交互 switch status { case .authorized: // 权限已允许,执行相关操作 break case .denied, .restricted: // 权限被拒绝,引导用户前往设置开启 break default: break } }
相册权限(Photos)
监听 PHPhotoLibrary.authorizationStatusDidChangeNotification:
NotificationCenter.default.addObserver( self, selector: #selector(onPhotoAuthChanged), name: PHPhotoLibrary.authorizationStatusDidChangeNotification, object: nil ) @objc private func onPhotoAuthChanged() { let status = PHPhotoLibrary.authorizationStatus() // 处理权限变更逻辑 }
通讯录/日历/提醒事项(Contacts/EventKit)
这类框架的通知会同时响应内容变更和权限变更,需要在回调中主动检查权限状态:
- 通讯录:监听
CNContactStoreDidChangeNotification,回调中通过CNContactStore.authorizationStatus(for: .contacts)检查状态 - 日历/提醒事项:监听
EKEventStoreChangedNotification,回调中通过EKEventStore.authorizationStatus(for: .event)检查状态
2. 前台主动校验补充
对于部分没有专属变更通知的权限(如健康Kit),或者担心通知遗漏的场景,可以监听APP从后台回到前台的通知,统一校验所有关心的权限:
NotificationCenter.default.addObserver( self, selector: #selector(onAppEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil ) @objc private func onAppEnterForeground() { // 批量检查相机、相册、通讯录等权限状态 checkCameraAuthorization() checkPhotoAuthorization() // ... 其他权限检查 }
注意事项
- 务必在对象销毁时移除通知观察者,避免内存泄漏:
deinit { NotificationCenter.default.removeObserver(self) } - 部分通知在APP启动时会自动触发一次,初始化阶段可以先执行一次权限检查,避免重复处理逻辑
- 引导用户前往设置时,可以通过
UIApplication.openSettingsURLString打开APP设置页面
内容的提问来源于stack exchange,提问作者bli00
相关产品推荐
相关产品推荐

