Swift 权限请求服务PermissionManager

107 阅读2分钟

简单用gpt训练了个权限请求管理类,使用RxSwift返回,支持链式请求,支持多权限请求,失败权限使用error抛出

//  
//  PermissionManager.swift  
//  HoneyChat  
//  
//  Created by hccc on 2023/3/16.  
//  
  
import Foundation  
import RxSwift  
import AVFoundation  
import Photos  
import CoreLocation  
import MediaPlayer  
import CoreBluetooth  
import AppTrackingTransparency  
  
enum PermissionErrorError {  
    ///  音频权限  
    case audio  
    /// 视频权限  
    case video  
    /// 蓝牙权限  
    case bluetooth  
    /// 定位权限  
    case location  
    /// 相册权限  
    case photoLibrary  
    /// 相机权限  
    case camera  
    /// 隐私权限跟踪授权  
    case tracking  
}  
// 枚举定义不同的权限类型  
enum PermissionType {  
    /// 音频权限  
    case audio  
    /// 视频权限  
    case video  
    /// 蓝牙权限  
    case bluetooth  
    /// 定位权限  
    case location  
    /// 相册权限  
    case photoLibrary  
    /// 相机权限  
    case camera  
    /// 跟踪授权  
    case tracking  
  
    var error: PermissionError {  
        switch self {  
        case .audio:  
            return .audio  
        case .video:  
            return .video  
        case .bluetooth:  
            return .bluetooth  
        case .location:  
            return .location  
        case .photoLibrary:  
            return .photoLibrary  
        case .camera:  
            return .camera  
        case .tracking:  
            return .tracking  
        }  
    }  
  
    // 根据不同的权限类型获取相应的媒体类型  
    var avMediaType: AVMediaType? {  
        switch self {  
        case .audio:  
            return .audio  
        case .video:  
            return .video  
        case .camera:  
            return .video  
        default:  
            return nil  
        }  
    }  
  
    // 根据不同的权限类型获取相应的媒体类型  
    var mediaType: PHAssetMediaType? {  
        switch self {  
        case .photoLibrary:  
            return .image  
        default:  
            return nil  
        }  
    }  
  
    // 获取蓝牙权限状态  
    var cbPeripheralManagerAuthorizationStatus: CBPeripheralManagerAuthorizationStatus? {  
        switch self {  
        case .bluetooth:  
            return CBPeripheralManager.authorizationStatus()  
        default:  
            return nil  
        }  
    }  
}  
  
class PermissionManager {  
    private static let locationManager = CLLocationManager() // 定义 CLLocationManager 实例  
  
    // MARK: 请求多个权限  
    static func requestPermissions_ typesPermissionType...) -> Observable<Void> {  
        guard types.count > 0 else {  
            return .empty()  
        }  
        var obserable: Observable<Void= .just(())  
        for type in types {  
            obserable = obserable.flatMap { _ -> Observable<Voidin  
                return PermissionManager  
                    .requestPermission(for: type)  
                    .map({ grant in  
                        if grant {  
                            return ()  
                        } else {  
                            // 错误的权限直接丢出响应的错误  
                            throw type.error  
                        }  
                    })  
            }  
        }  
        return obserable.observe(on: MainScheduler.asyncInstance)  
    }  
    // MARK: 请求系统权限静态方法并返回 Observable 对象  
    static func requestPermission(for permissionTypePermissionType) -> Observable<Bool> {  
        switch permissionType {  
        case .audio, .video, .camera:  
            return requestMediaPermission(for: permissionType) // 请求音视频、相机权限  
        case .location:  
            return requestLocationPermission() // 请求定位权限  
        case .photoLibrary:  
            return requestPhotoLibraryPermission() // 请求相册权限  
        case .bluetooth:  
            return requestBluetoothPermission() // 请求蓝牙权限  
        case .tracking:  
            return requestTrackingAuthorization() // 请求隐私权限  
        }  
    }  
  
    // MARK: 请求音视频、相机权限  
    private static func requestMediaPermission(for permissionTypePermissionType) -> Observable<Bool> {  
        guard let mediaType = permissionType.avMediaType else {  
            return .empty()  
        }  
  
        return Observable.create { observer in  
            let status = AVCaptureDevice.authorizationStatus(for: mediaType)  
  
            switch status {  
            case .authorized:  
                observer.onNext(true)  
                observer.onCompleted()  
            case .notDetermined:  
                AVCaptureDevice.requestAccess(for: mediaType) { granted in  
                    observer.onNext(granted)  
                    observer.onCompleted()  
                }  
            default:  
                observer.onNext(false)  
                observer.onCompleted()  
            }  
  
            return Disposables.create()  
        }  
    }  
  
    // MARK: 请求定位权限  
    private static func requestLocationPermission() -> Observable<Bool> {  
        return Observable.create { observer in  
            let status = CLLocationManager.authorizationStatus()  
  
            switch status {  
            case .authorizedWhenInUse, .authorizedAlways:  
                observer.onNext(true)  
                observer.onCompleted()  
            case .notDetermined:  
                locationManager.requestWhenInUseAuthorization()  
                observer.onNext(false)  
            default:  
                observer.onNext(false)  
                observer.onCompleted()  
            }  
  
            return Disposables.create()  
        }  
    }  
  
    // MARK: 请求相册权限  
    private static func requestPhotoLibraryPermission() -> Observable<Bool> {  
        return Observable.create { observer in  
            let status = PHPhotoLibrary.authorizationStatus()  
  
            switch status {  
            case .authorized:  
                observer.onNext(true)  
                observer.onCompleted()  
            case .notDetermined:  
                PHPhotoLibrary.requestAuthorization { status in  
                    observer.onNext(status == .authorized)  
                    observer.onCompleted()  
                }  
            default:  
                observer.onNext(false)  
                observer.onCompleted()  
            }  
  
            return Disposables.create()  
        }  
    }  
  
    // MARK: 请求蓝牙权限  
    private static func requestBluetoothPermission() -> Observable<Bool> {  
        guard let status = PermissionType.bluetooth.cbPeripheralManagerAuthorizationStatus else {  
            return .just(false)  
        }  
  
        switch status {  
        case .authorized, .notDetermined:  
            return .just(true)  
        default:  
            return .just(false)  
        }  
    }  
    // MARK: 请求隐私权限  
    private static func requestTrackingAuthorization() -> Observable<Bool> {  
        if #available(iOS 14*) {  
            return Observable<Bool>.create { obs in  
                ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in  
                    switch status {  
                    case .authorized:  
                        // 用户已授权追踪权限  
                        obs.onNext(true)  
                        obs.onCompleted()  
                    case .denied:  
                        // 用户拒绝了追踪权限  
                        obs.onNext(false)  
                        obs.onCompleted()  
                    case .notDetermined:  
                        // 还没有询问用户是否授权追踪  
                        obs.onNext(false)  
                        obs.onCompleted()  
                    case .restricted:  
                        // 应用程序无法请求追踪权限,例如由于家长控制等限制  
                        obs.onNext(false)  
                        obs.onCompleted()  
                    @unknown default:  
                        obs.onNext(false)  
                        obs.onCompleted()  
                    }  
                })  
                return Disposables.create()  
            }  
        } else {  
            return .just(true)  
            // 如果设备运行的是较早的 iOS 版本,则不需要请求追踪权限。  
        }  
    }  
}