iOS开发之系统权限

18 篇文章 0 订阅

背景

配合监管要求,针对APP用户获取管理权限做如下整改:

  1. APP在首次启动页面对权限进行解释说明(包括解释权限的涵义以及说明使用权限的用途)
  2. 个人中心-设置,增加权限设置菜单,展示涉及获取的所有权限,以及展示当前开启/关闭状态
  3. 一切为了监管……

软件环境

  • Xcode11.2
  • Swift4.2
  • iOS13.2.2

开门见山,上代码

工具类:SystemPermissionMonitor.swift

检测相机权限
static func checkCamera() -> (Bool, AVAuthorizationStatus) {
    let status = AVCaptureDevice.authorizationStatus(for: .video)
    return (status == .authorized, status)
}
检测相册权限
// (iOS 8, *)
static func checkPhotoLibrary() -> (Bool, PHAuthorizationStatus) {
    let status = PHPhotoLibrary.authorizationStatus()
    return (status == .authorized, status)
}
// (iOS, introduced: 6.0, deprecated: 9.0, message: "Use PHAuthorizationStatus in the Photos framework instead")
static func checkPhotoLibrary4oldVersion() -> (Bool, ALAuthorizationStatus) {
    let status = ALAssetsLibrary.authorizationStatus()
    let authorized = status == .authorized
    return (authorized, status)
}
获取相册权限
static func openPhotoLibraryAlert() -> (Bool, PHAuthorizationStatus) {
    let sema = DispatchSemaphore(value: 0)
    var status: PHAuthorizationStatus = .notDetermined
    PHPhotoLibrary.requestAuthorization { (authStatus) in
        status = authStatus
        sema.signal()
    }
    let _ = sema.wait(timeout: DispatchTime.distantFuture)
    return (status == .authorized, status)
}
检测定位权限
static func checkLocation() -> (Bool, CLAuthorizationStatus) {
    let status = CLLocationManager.authorizationStatus()
    return (status == .authorizedAlways || status == .authorizedWhenInUse, status)
}
检测通知权限
static func checkNotification() -> (Bool, Any?) {
    if #available(iOS 10.0, *) {
        let sema = DispatchSemaphore(value: 0)
        var status: UNAuthorizationStatus = .notDetermined
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            status = settings.authorizationStatus
            sema.signal()
        }
        let _ = sema.wait(timeout: DispatchTime.distantFuture)
        return (status == .authorized, status)
    } else {
        let settings = UIApplication.shared.currentUserNotificationSettings
        let types = settings?.types
        let isEnabled = types == [.alert, .badge, .sound]
        return (isEnabled, types)
    }
}

ViewModel:SystemPermissionViewModel.swift

App需要用到的权限枚举
enum PermissionType: Int {
    case PhotoLibrary
    case Camera
    case Location
    case Notification
    case Audio
    case Others
}
实体
struct PermissionModel {
    var name: String?
    var status: Any?
    var authorized: Bool = false
    var permissionType: PermissionType = .Others
    init(_ name: String?, permissionType: PermissionType) {
        self.name = name
        self.permissionType = permissionType
    }
}
数据初始化
var permissionArray: [PermissionModel] = []
override func setup() {
    super.setup()
    let permissionNameArray = ["相册","相机","地理位置","通知", "麦克风", "其他"]
    let permissionTypeArray: [PermissionType] = [.PhotoLibrary, .Camera, .Location, .Notification, .Audio, .Others]
    permissionArray = []
    for (i, name) in permissionNameArray.enumerated() {
        let model = PermissionModel(name, permissionType: permissionTypeArray[i])
        permissionArray.append(model)
    }
  // Check permission
  checkPermission()
  // Reload tableView
  updateDataArray(permissionArray)
}
检测是否开启各权限
private func checkPermission() {
    let (authorized4photoLibrary, status4photoLibrary) = SystemPermissionMonitor.checkPhotoLibrary()
    filterPermissionArray(authorized4photoLibrary, status: status4photoLibrary, permissionType: .PhotoLibrary)

    let (authorized4camera, status4camera) = SystemPermissionMonitor.checkCamera()
    filterPermissionArray(authorized4camera, status: status4camera, permissionType: .Camera)

    let (authorized4location, status4location) = SystemPermissionMonitor.checkLocation()
    filterPermissionArray(authorized4location, status: status4location, permissionType: .Location)

    let (authorized4notification, status4notification) = SystemPermissionMonitor.checkNotification()
    filterPermissionArray(authorized4notification, status: status4notification, permissionType: .Notification)

    let (authorized4audio, status4audio) = SystemPermissionMonitor.checkAudio()
    filterPermissionArray(authorized4audio, status: status4audio, permissionType: .Audio)
}
过滤不需要显示的权限&更新权限实体状态
private func filterPermissionArray(_ authorized: Bool, status: Any?, permissionType: PermissionType) {
    for (i, model) in permissionArray.enumerated() {
        if model.permissionType != permissionType { continue }

        if isNotDetermined(status, permissionType: permissionType) {
            // Remove permissions that user has not yet made a choice with regards to this application
            permissionArray.remove(at: i)
        } else {
            // Update the value of the property
            permissionArray[i].authorized = authorized
            permissionArray[i].status = status
        }
        break
    }
}
判断用户是否尚未对此应用程序的权限作出选择(.notDetermined)
/// Whether user has not yet made a choice with regards to this application
private func isNotDetermined(_ status: Any?, permissionType: PermissionType) -> Bool {
    switch permissionType {
        case .PhotoLibrary:
            let status: PHAuthorizationStatus? = status as? PHAuthorizationStatus
            return status == .notDetermined
        case .Camera, .Audio:
            let status: AVAuthorizationStatus? = status as? AVAuthorizationStatus
            return status == .notDetermined
        case .Location:
            let status: CLAuthorizationStatus? = status as? CLAuthorizationStatus
            if #available(iOS 13, *) {
                // “Allow once”, your app will be notified that the CLAuthorizationStatus changed to authorizedWhenInUse. Just like you’re used to in older iOS version when you get a permanent permission. It is now allowed for your app to start requesting locations, no code changes necessary.
                // Users can jump out and back into your app, and you will still have location permission. It’s only after a (longer) period of inactivity that iOS will revoke the permission and turn the CLAuthorizationStatus back to notDetermined
                // Return false, adapting to the new 'allow just once' location permission in iOS 13
                return false
            }
            return status == .notDetermined
        case .Notification:
            if #available(iOS 10.0, *) {
                let status: UNAuthorizationStatus? = status as? UNAuthorizationStatus
                return status == .notDetermined
            }
        break
        default:
            break
    }
    return false
}
效果图

权限设置页面

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好,iOS开发中需要使用Wi-Fi的功能需要在应用程序中获取Wi-Fi的权限。获取Wi-Fi权限的步骤如下: 1. 在应用程序的Info.plist文件中添加以下代码,允许应用程序访问Wi-Fi信息: ```xml <key>NSWi-FiUsageDescription</key> <string>需要使用您的Wi-Fi信息来进行某些操作</string> ``` 在字符串中,您可以描述应用程序为什么需要访问Wi-Fi信息。这个描述将显示在系统弹出的权限请求对话框中,让用户知道应用程序为什么需要Wi-Fi权限。 2. 在应用程序中使用系统提供的WiFiManager类来访问Wi-Fi信息。例如,以下代码将检查当前设备是否连接到Wi-Fi网络: ```swift import SystemConfiguration.CaptiveNetwork func getWiFiInfo() -> [AnyHashable: Any]? { var wifiInfo: [AnyHashable: Any]? if let interfaces = CNCopySupportedInterfaces() as NSArray? { for interface in interfaces { if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary? { wifiInfo = interfaceInfo as? [AnyHashable: Any] break } } } return wifiInfo } let wifiInfo = getWiFiInfo() if let ssid = wifiInfo?["SSID"] as? String { print("当前连接的Wi-Fi名称为:\(ssid)") } else { print("当前未连接到Wi-Fi网络") } ``` 这段代码使用了SystemConfiguration框架中的CaptiveNetwork类来获取当前设备连接的Wi-Fi网络信息。注意,在使用CaptiveNetwork类时,需要导入SystemConfiguration框架。 希望这些步骤能够对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值