iOS info.plist应用权限配置

iOS info.plist应用权限配置iOS APP审核比较严格,十分注重保护用户隐私。没有用户对APP授权,很多涉及数据采集的功能都无法使用。这里记录一些info.plist中常用的权限配置及权限状态检查,后面会陆续补充。

iOS APP审核比较严格,十分注重保护用户隐私。没有用户对APP授权,很多涉及数据采集的功能都无法使用。这里记录一些常用的权限配置及权限状态检查,后面会陆续补充。

一、常见隐私权限
1.基本格式 Privacy – xxxx :详细描述,如图:样例一.png
ps:详细描述要写的与具体功能相关,否则APP审核可能会被打回。
2.隐私权限清单
Privacy - Camera Usage Description : 使用相机(拍照或录制)
Privacy - Face ID Usage Description : 使用FaceID
Privacy - NFC Scan Usage Description : 使用NFC扫描
Privacy - Microphone Usage Description :使用麦克风(录音)
Privacy - Bluetooth Always Usage Description :使用手机蓝牙
//定位
Privacy - Location When In Use Usage Description : APP使用期间获取定位信息(仅限应用在前台)
Privacy - Location Always and When In Use Usage Description :允许一直获取定位信息(包括前台和后台)
//图库
Privacy - Photo Library Usage Description :允许从图库读取图片或视频
Privacy - Photo Library Additions Usage Description :向图库添加图片或视频
二、检查权限状态,及主动申请
这一部分是最基本的容错,调用方法前去获取设备硬件状态或权限是否授权。进而去规避一些由于用户没有授权权限,直接调用对应方法而导致的崩溃。

1.相机 这里用到的是AVCaptureDevice来检查权限状态,后续会添加使用其他方法状态获取的方式。

    private func isPrepareOfAVCaptureVideoDevice(_ completionHandler: @escaping (Bool) -> Void) {
        let videoStatus = AVCaptureDevice.authorizationStatus(for: .video)

        if videoStatus == .notDetermined{
            AVCaptureDevice.requestAccess(for: .video) {
                completionHandler($0)
            }
            return
        }
        completionHandler(videoStatus == .authorized)
    }

2.麦克风 同相机获取权限状态的方式,后续也会添加。

    private func isPrepareOfAVCaptureAudioDevice(_ completionHandler: @escaping (Bool) -> Void) {
        let audioStatus = AVCaptureDevice.authorizationStatus(for: .audio)
        if audioStatus == .notDetermined {
            AVCaptureDevice.requestAccess(for: .audio) {
                completionHandler($0)
            }
            return
        }
        completionHandler(audioStatus == .authorized)
    }

3.图库 PhotoLibrary权限在iOS14.0进行了细化: a)获取图库读写权限


        if #available(iOS 14, *) {
            let readWriteStatus = PHPhotoLibrary.authorizationStatus(for: .readWrite)
            print(readWriteStatus)
            PHPhotoLibrary.requestAuthorization(for: .readWrite) { (status) in
                self.handleRequestStatus(status: status)
            }
        } else {
            let readWriteStatus = PHPhotoLibrary.authorizationStatus()
            print(readWriteStatus)
            PHPhotoLibrary.requestAuthorization { (status) in
                self.handleRequestStatus(status: status)
            }
        }
    }

    func handleRequestStatus(status:PHAuthorizationStatus){
        switch status {
        case .notDetermined:
            print("The user hasn't determined this app's access.")
        case .restricted:
            print("The system restricted this app's access.")
        case .denied:
            print("The user explicitly denied this app's access.")
        case .authorized:
            print("The user authorized this app to access Photos data.")
        case .limited:
            print("The user authorized this app for limited Photos access.")
        @unknown default:
            fatalError()
        }
    }

b)仅向图库添加,为了对称添加了iOS14版本以下的

    func checkPhotosLibraryAddtionStatus(){
        if #available(iOS 14, *) {
            let readWriteStatus = PHPhotoLibrary.authorizationStatus(for: .addOnly)
            print(readWriteStatus)
            PHPhotoLibrary.requestAuthorization(for: .addOnly) { [self] (status) in
                handleRequestStatus(status: status)
            }
        } else {
            let readWriteStatus = PHPhotoLibrary.authorizationStatus()
            print(readWriteStatus)
            PHPhotoLibrary.requestAuthorization { (status) in
                self.handleRequestStatus(status: status)
            }
        }
    }
    
    func handleRequestStatus(status:PHAuthorizationStatus){
        switch status {
        case .notDetermined:
            print("The user hasn't determined this app's access.")
        case .restricted:
            print("The system restricted this app's access.")
        case .denied:
            print("The user explicitly denied this app's access.")
        case .authorized:
            print("The user authorized this app to access Photos data.")
        case .limited:
            print("The user authorized this app for limited Photos access.")
        @unknown default:
            fatalError()
        }
    }

4.蓝牙

  //蓝牙状态获取是通过delegate方法centralManagerDidUpdateState来实现的
  func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .resetting:
            print("服务连接中断,正在重连")
        case .unsupported:
            print("设备不支持")
        case .unauthorized:
            if #available(iOS 13.0, *) {
                switch central.authorization {
                case .restricted:
                    print("设备蓝牙有问题,被限制使用")
                case .denied:
                    print("被用户拒绝了")
                default:
                    print("啥也不是~~~~~")
                }
            } else {
                print("用户未授权")
            }
        case .poweredOff:
            print("蓝牙未打开")
        case .poweredOn:
            print("蓝牙已打开")
            
        default:
            print("啥也不是~~~~~")
        }

5.定位

    func checkLocationStatus(){
        let locationManager = CLLocationManager()
        if #available(iOS 14.0, *) {
            let status = locationManager.authorizationStatus
            self.requestLocationAuthor(status: status)
        } else {
            let status = CLLocationManager.authorizationStatus()
            self.requestLocationAuthor(status: status)
        }
    }
    
    func requestLocationAuthor(status:CLAuthorizationStatus){
        let locationManager = CLLocationManager()

        switch status {
        case .authorizedAlways:
            print("The user authorized this app is authorizedAlways.")
        case .authorizedWhenInUse:
            print("The user authorized this app is authorizedWhenInUse.")
        case .denied:
            print("The user authorized this app is denied.")
        case .notDetermined://根据需求二选一
// locationManager.requestAlwaysAuthorization()
            locationManager.requestWhenInUseAuthorization()
            
        case .restricted:
            print("The user authorized this app is restricted.")

        default:
            fatalError()
        }
    }

6.NFC 要使用NFC功能开发需要在证书中添加NFC开发选项,配置证书后然后在项目中添加Capability。 NFC Capability配置.png 获取状态是否可用比较简单,内部封装好的api直接调用即可。

//MARK: NFC相关
import CoreNFC
extension ViewController{
    func checkNFCReaderAvailable() -> Bool{
       return NFCNDEFReaderSession.readingAvailable
    }
}

7.FaceID 请求设备本地解锁认证(密码,faceID,TouchID),LAPolicy有两种枚举类型,deviceOwnerAuthenticationWithBiometrics仅调用设备设置的touchid或faceID进行认证,deviceOwnerAuthentication会根据设备设置的解锁方式进行请求,默认是设备密码认证,即使在没有设置生物学识别信息(指纹、面部特征)的情况下也可以使用

import LocalAuthentication
var context = LAContext()
extension ViewController{

    func requetAuthor(){
        /* canEvaluatePolicy()方法用来检查认证方式是否可用,也可用来标记状态 evaluatePolicy()方法用来进行认证方法调用 */
            context = LAContext()
            context.localizedCancelTitle = "设置title"

            var error: NSError?
            if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
                let reason = "设置具体描述"
                context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason ) { success, error in
                    if success {
                        DispatchQueue.main.async { [unowned self] in
                           print("认证成功")
                        }

                    } else {
                        print(error?.localizedDescription ?? "认证失败")
                    }
                }
            } else {
                print(error?.localizedDescription ?? "无法调用系统认证方式")
            }
        }
}

8.消息通知 检查消息通知状态

  func checkNotificationAvailable(){
        if #available(iOS 10, *) {
            UNUserNotificationCenter.current().getNotificationSettings { (settings) in
                print(settings.authorizationStatus)
                switch settings.authorizationStatus{
                case .authorized:
                    print("已授权")
                case .denied:
                    print("用户拒绝消息通知")
                case .notDetermined:
                    print("未确定消息权限")
                //这两个是新的,没有做深入探究
                case .ephemeral:
                    print("ephemeral")
                case .provisional:
                    print("provisional")

                default:
                    break
                }
            }
        }else{
            let isRegistered = UIApplication.shared.isRegisteredForRemoteNotifications
            print(isRegistered)
        }
    }
附:iOS 网络通信配置

iOS 9.0 以后APP网络请求需要在info.plist中配置NSAppTransportSecurity,具体配置如下图:网络通信配置2.png

Apple官方文档:ProtectedResources
Demo:Demo链接

今天的文章iOS info.plist应用权限配置分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/15042.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注