You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift如何实现点击按钮后依次请求相机与相册访问权限

问题根因

你当前代码的两个权限请求是并行执行的,没有顺序依赖。PHPhotoLibrary.requestAuthorization是异步回调,相机权限请求不会等相册权限的回调和后续UI操作完成就会触发,才会出现弹窗叠加的问题。

前置配置要求

请先在项目的Info.plist中添加如下权限描述,否则请求权限会直接崩溃:

  • NSPhotoLibraryUsageDescription:相册访问用途说明
  • NSCameraUsageDescription:相机访问用途说明
修复后的实现代码
import Photos
import AVFoundation

func checkPermissions() {
    // 先判断相册是否可用,优先请求相册权限
    guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else {
        // 相册不可用,直接请求相机权限
        requestCameraPermissionIfNeeded()
        return
    }
    
    PHPhotoLibrary.requestAuthorization(for: .readWrite) { [weak self] status in
        guard let self = self else { return }
        DispatchQueue.main.async {
            switch status {
            case .notDetermined, .restricted, .denied:
                print("相册权限未授权")
                self.showAlertToOpenSettings(type: 1)
                // 相册权限请求完成后再请求相机权限
                self.requestCameraPermissionIfNeeded()
            case .authorized:
                print("相册权限已授权")
                self.openPhotoPicker()
                // 相册操作触发后再请求相机权限
                self.requestCameraPermissionIfNeeded()
            case .limited:
                print("相册有限权限")
                self.showLimitedLibraryAlert()
                // 有限权限提示展示后再请求相机权限
                self.requestCameraPermissionIfNeeded()
            @unknown default:
                fatalError()
            }
        }
    }
}

// 封装独立的相机权限请求方法
private func requestCameraPermissionIfNeeded() {
    guard UIImagePickerController.isSourceTypeAvailable(.camera) else { return }
    
    AVCaptureDevice.requestAccess(for: .video) { [weak self] response in
        guard let self = self else { return }
        if !response {
            DispatchQueue.main.async {
                self.showAlertToOpenSettings(type: 2)
            }
        }
    }
}
核心修改说明
  • 把相机权限请求封装为独立方法,仅在相册权限的所有回调逻辑(包括UI操作)执行完成后再调用,保证权限请求的顺序执行
  • 新增[weak self]避免循环引用,所有UI相关操作统一调度到主队列执行,符合UIKit的线程要求
  • 新增相册不可用的兜底逻辑,兼容没有相册权限的设备场景
可选优化建议
  • 如果你的业务不需要用户进入页面就同时拥有两个权限,可以把相机权限请求放到用户实际点击拍照功能的时候再触发,减少首次使用时的权限弹窗数量,降低用户抵触
  • 统一权限被拒的弹窗逻辑,避免重复展示相同类型的提示

内容的提问来源于stack exchange,提问作者Diksha Rattan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 00:36:04