美文网首页
Swift-常用权限检测

Swift-常用权限检测

作者: 熊本丸 | 来源:发表于2020-04-27 14:02 被阅读0次

最近在Swift项目实践中,用到了系统的一些权限请求,如定位、相机、相册、日历.....,为了更方便的查询各种权限状态以及使用这些功能,我简单的整理了一些常用的系统权限的状态以及授权。

特别说明:在使用这些功能时,需要在info.plist中添加对应的描述,否则将导致项目崩溃,在添加定位权限描述以及相册权限描述时,需要添加以下描述,否则可能会导致包上传到itunesConnect时找不到包,当然,苹果也会在你包上传之后发邮件提醒你

*  Privacy - Photo Library Additions Usage Description
*  Privacy - Photo Library Usage Description
*  Privacy - Location When In Use Usage Description
*  Privacy - Location Always and When In Use Usage Description

1.导入头文件、自定义权限的各种状态,方便各种的权限状态的统一处理

import CoreLocation
import ContactsUI
import PhotosUI
import AssetsLibrary
import EventKitUI
import CoreTelephony
import AVFoundation
//回调处理
typealias BWPrivacyAuthorizerCompletionClosure = (_ granted: Bool)->Void

enum BWPrivacyAuthorizerStatus {
    case notDetermined                  //尚未授权
    case restricted                     //家长控制
    case denied                         //拒绝
    case authorized                     //已授权
}

2.常用权限状态,将各种权限状态转化成统一的自定义的权限状态,方便统一处理

//定位授权状态
 func bw_locationAuthorizationStatus() -> BWPrivacyAuthorizerStatus {
     let status = CLLocationManager.authorizationStatus()
     switch status {
     case .denied:
         return .denied
     case .notDetermined:
         return .notDetermined
     case .restricted:
         return .restricted
     case .authorized:
         return .authorized
     default:
         return .authorized
     }
 }

//通讯录授权状态
func bw_contactAuthorizationStatus() -> BWPrivacyAuthorizerStatus {
    let status = CNContactStore.authorizationStatus(for: .contacts)
    switch status {
    case .notDetermined:
        return .notDetermined
    case .restricted:
        return .restricted
    case .denied:
        return .denied
    case .authorized:
        return .authorized
    default:
        return .authorized
    }
}

//相册授权状态
func bw_photoLibraryAuthorizationStatus() -> BWPrivacyAuthorizerStatus {
    if #available(iOS 9.0, *) {
        let status = PHPhotoLibrary.authorizationStatus()
        switch status {
        case .notDetermined:
            return .notDetermined
        case .restricted:
            return .restricted
        case .denied:
            return .denied
        default:
            return .authorized
        }
    } else {
        let status = ALAssetsLibrary.authorizationStatus()
        switch status {
        case .notDetermined:
            return .notDetermined
        case .restricted:
            return .restricted
        case .denied:
            return .denied
        default:
            return .authorized
        }
    }
}

//相机授权状态
func bw_cameraAuthorizationStatus() -> BWPrivacyAuthorizerStatus {
    let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
    switch status {
    case .notDetermined:
        return .notDetermined
    case .restricted:
        return .restricted
    case .denied:
        return .denied
    case .authorized:
        return .authorized
    default:
        return .authorized
    }
}

//日历授权状态
func bw_calendarAuthorizationStatus() -> BWPrivacyAuthorizerStatus {
    let status = EKEventStore.authorizationStatus(for: EKEntityType.event)
    switch status {
    case .notDetermined:
        return .notDetermined
    case .restricted:
        return .restricted
    case .denied:
        return .denied
    case .authorized:
        return .authorized
    default:
        return .authorized
    }
}

//麦克风权限
func bw_audioAuthorizationStatus() -> BWPrivacyAuthorizerStatus {
    let status = AVAudioSession.sharedInstance().recordPermission
    switch status {
    case .undetermined:
        return .notDetermined
    case .denied:
        return .denied
    case .granted:
        return .authorized
    }
}

3.请求授权

//MARK: 通讯录相关权限

func bw_requestContactAuthorization(with completion: @escaping BWPrivacyAuthorizerCompletionClosure) {
    let status = bw_contactAuthorizationStatus()
    switch status {
    case .notDetermined:
        let store = CNContactStore.init()
        store.requestAccess(for: .contacts) { (granted, error) in
            DispatchQueue.main.async {
                if granted == false {
                    bw_showAlertWithTitle("无法访问通讯录", message: bw_authorizationNotice(title: "通讯录"))
                }
                completion(granted)
            }
        }
    case .restricted,.denied:
        completion(false)
        bw_showAlertWithTitle("无法访问通讯录", message: bw_authorizationNotice(title: "通讯录"))
    case .authorized:
        completion(true)
    }
}

//MARK: 相册相关权限

func bw_requestPhotoLibraryAuthorization(with completion: @escaping BWPrivacyAuthorizerCompletionClosure) {
    let status = bw_photoLibraryAuthorizationStatus()
    switch status {
    case .notDetermined:
        if #available(iOS 9.0, *) {
            PHPhotoLibrary.requestAuthorization { (status) in
                DispatchQueue.main.async {
                    switch status {
                    case .authorized:
                        completion(true)
                    default:
                        completion(false)
                        bw_showAlertWithTitle("无法访问照片", message: bw_authorizationNotice(title: "照片"))
                    }
                }
            }
        }
    case .restricted,.denied:
        bw_showAlertWithTitle("无法访问照片", message: bw_authorizationNotice(title: "照片"))
    case .authorized:
        completion(true)
    }
}

//MARK: 相机相关权限
func bw_requestCameraAuthorization(with completion: @escaping BWPrivacyAuthorizerCompletionClosure) {
    let status = bw_cameraAuthorizationStatus()
    switch status {
    case .notDetermined:
        AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) in
            DispatchQueue.main.async {
                if granted == false {
                    bw_showAlertWithTitle("无法访问相机", message: bw_authorizationNotice(title: "相机"))
                }
                completion(granted)
            }
        })
    case .restricted,.denied:
        bw_showAlertWithTitle("无法访问相机", message: bw_authorizationNotice(title: "相机"))
    case .authorized:
        completion(true)
    }
}

//MARK: 日历相关权限

func bw_requestCalendarAuthorization(with completion: @escaping BWPrivacyAuthorizerCompletionClosure) {
    let status = bw_calendarAuthorizationStatus()
    switch status {
    case .notDetermined:
        let store = EKEventStore.init()
        store.requestAccess(to: .event) {(granted, error) in
            DispatchQueue.main.async {
                if granted == false {
                    bw_showAlertWithTitle("无法访问日历", message: bw_authorizationNotice(title: "日历"))
                }
                completion(granted)
            }
        }
    case .authorized:
        completion(true)
    case .restricted,.denied:
        bw_showAlertWithTitle("无法访问日历", message: bw_authorizationNotice(title: "日历"))
    }
}

//MARK:定位相关权限
func bw_requestLocationAuthorization(with locationManager: CLLocationManager, completion: @escaping BWPrivacyAuthorizerCompletionClosure) {
    let status = bw_locationAuthorizationStatus()
    switch status {
    case .denied,.restricted:
        completion(false)
        bw_showAlertWithTitle("无法开启定位", message: "请在iPhone的\"设置-隐私-位置\"中允许\(BWAppDispalyName)开启位置权限")
    case .notDetermined:
        locationManager.requestWhenInUseAuthorization()
    //            locationManager.startUpdatingLocation()
    case .authorized:
        completion(true)
    }
}

//MARK: 麦克风相关权限
func bw_requestAudioAuthorization(with completion: @escaping BWPrivacyAuthorizerCompletionClosure) {
    let status = bw_audioAuthorizationStatus()
    switch status {
    case .notDetermined:
        AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
            DispatchQueue.main.async {
                if granted == false {
                    bw_showAlertWithTitle("无法访问麦克风", message: bw_authorizationNotice(title: "麦克风"))
                }
                completion(granted)
            }
        }
    case .denied:
        completion(true)
        bw_showAlertWithTitle("无法访问麦克风", message: bw_authorizationNotice(title: "麦克风"))
    case .authorized:
        completion(true)
    default:
        break
    }
}

//MARK: 通知相关权限
func bw_notificationAuthorizationStatus(with completion: @escaping BWPrivacyAuthorizerCompletionClosure) {
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            switch settings.authorizationStatus {
            case .authorized,.provisional:
                completion(true)
            case .notDetermined:
                completion(false)
            case .denied:
                completion(false)
            @unknown default:
                completion(false)
            }
        }
    } else {
        let isNotificationEnabled = UIApplication.shared.currentUserNotificationSettings?.types.contains(UIUserNotificationType.alert)
        if isNotificationEnabled == true {
            completion(true)
        } else {
            completion(false)
        }
    }
}

//MARK: 弹窗展示

private func bw_authorizationNotice(title: String) -> String {
    return "请在iPhone的\"设置-隐私-\(title)\"中允许\(BWAppDispalyName)访问\(title)"
}

private func bw_showAlertWithTitle(_ title: String, message: String) {
    let alertController = UIAlertController.init(title: title, message: message, preferredStyle: .alert)
    let cancelAction = UIAlertAction.init(title: "取消", style: .cancel, handler: nil)
    let goAction = UIAlertAction.init(title: "前往设置", style: .default) { (action) in
        if let settingUrl = URL(string: UIApplication.openSettingsURLString) {
            if UIApplication.shared.canOpenURL(settingUrl) {
                UIApplication.shared.openURL(settingUrl)
            }
        }
    }
    alertController.addAction(cancelAction)
    alertController.addAction(goAction)
    UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
}

相关文章

  • Swift-常用权限检测

    1.选择导入头文件 1.是否开启媒体资料库/Apple Music 服务 2.检测是否开启联网 3.检测是否开启定...

  • Swift-常用权限检测

    1.选择导入头文件 1.是否开启媒体资料库/Apple Music 服务 2.检测是否开启联网 3.检测是否开启定...

  • Swift-常用权限检测

    最近在Swift项目实践中,用到了系统的一些权限请求,如定位、相机、相册、日历.....,为了更方便的查询各种权限...

  • iOS相关权限检测和申请

    iOS权限相关的检测和申请 在iOS开发过程中常用到的权限整理如下: 相册权限检测 相册权限申请 相机权限检测 相...

  • 获取文件权限

    检测linux下文件的权限 检测linux下多个文件的权限

  • 检测 iOS 系统网络权限被关闭

    检测 iOS 系统网络权限被关闭 检测 iOS 系统网络权限被关闭

  • 2020-07-13

    /** * 检测权限 */private void checkPermission() { //先检查权限 ...

  • Swift-访问权限

    一、private: 表示私有的,除了局部变量其它都可以修饰。 private修饰全局变量、全局函数、枚举、结构体...

  • Linux学习--文件权限

    February 1, 2017 常用的文件类型 文件权限 目录文件的权限 特殊权限 常用的文件类型 文件权限 目...

  • iOS中各个权限功能提示弹框

    1. 麦克风权限 单存检测是否有麦克风权限,并不会弹出是否允许弹出权限提示框 检测是否有权限,如果没有授权过,会弹...

网友评论

      本文标题:Swift-常用权限检测

      本文链接:https://www.haomeiwen.com/subject/admywhtx.html