iOS 权限管理

作者: vincentgemini | 来源:发表于2018-03-06 09:30 被阅读1476次

    网络权限管理

    一、iOS网络情况分类:

    1. 通过App应用设置网络使用权限(关闭、WLAN、WLAN与蜂窝移动网)
    2. 直接设置手机网络情况(飞行模式、无线局域网络、蜂窝移动网络)

    二、iOS开发使用到的网络判断类:

    1. AFNetworkReachability或者Reachability来判断网络的可达性,这两个类可以判断网络是否可达,以及可达时网络的类型(WLAN还是蜂窝移动网络);

    2. CTCellularData来判断网络数据是否受限,只有应用网络权限设置为WLAN与蜂窝移动网时,网络数据才会返回不受限;

    三、组合关系:

    权限 飞行模式/关闭网络 局域网 蜂窝移动网络
    关闭 不可达-数据受限 不可达-数据受限 不可达-数据受限
    WLAN 不可达-数据受限 WLAN-数据受限 不可达-数据受限
    WLAN和蜂窝移动网 不可达-数据受限 WLAN-数据不受限 WLAN-数据不受限

    注:关闭网络,及关闭无线局域网和蜂窝移动网络。

    四、特殊说明:

    1. 第一次安装应用(之前从未安装过),第一次启动App时,会提示选择网络,选择之后就不会提示选择网络;但有时第一次安装时不出现选择网络,需要在设置中修改任意一个应用的网络权限,然后重启App,就会提示网络(目前没有找到不出现选择网络的原因);

    2. 当网络由可达状态切换到不可达状态后,第一进入App时,系统会提示一次网络权限改变的提示;

    3. 修改网络权限时,App不会重启,这个地方与相册授权不同。相册、相机、麦克风等修改权限后返回时,App会重新启动。

    五、代码:

    CTCellularData *cellularData = [[CTCellularData alloc] init];
    cellularData.cellularDataRestrictionDidUpdateNotifier = ^(CTCellularDataRestrictedState state) {
            //获取联网权限状态
            switch (state) {
                case kCTCellularDataRestricted:
                    NSLog(@"Restricrted");
                    break;
                    
                case kCTCellularDataNotRestricted:
                    NSLog(@"Not Restricted");
                    break;
                    
                    //未知,第一次请求
                case kCTCellularDataRestrictedStateUnknown:
                    NSLog(@"Unknown");
                    break;
                    
                default:
                    break;
            };
        };
    
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            //获取联网可达状态
            switch (status) {
                case AFNetworkReachabilityStatusUnknown:
                    NSLog(@"NetworkingTypeUnknown");
                    break;
                    
                case AFNetworkReachabilityStatusNotReachable:
                    NSLog(@"NetworkingTypeNotReachable");
                    break;
                    
                case AFNetworkReachabilityStatusReachableViaWWAN:
                    NSLog(@"NetworkingTypeReachableViaWWAN");
                    break;
                    
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    NSLog(@"NetworkingTypeReachableViaWiFi");
                    break;
                    
                default:
                    NSLog(@"NetworkingTypeUnknown");
                    break;
            }
    

    相机和麦克风权限管理

    • 判断相机或麦克风权限

       [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {//相机权限 
            if (granted) { 
                NSLog(@"Authorized");
            }else{ 
                NSLog(@"Denied or Restricted");
            }
        }];
      
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {//麦克风权限
            if (granted) {
                NSLog(@"Authorized");
            }else{
                NSLog(@"Denied or Restricted");
            }
        }];
      
    • 查看摄像头或麦克风权限

        AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];//相机权限
        AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];//麦克风权限
      
        switch (authStatus) {
            case AVAuthorizationStatusNotDetermined:
            {
                //获取权限
                break;
            }  
            case AVAuthorizationStatusRestricted:
            {
                handler(NO);
                break;
            }
            case AVAuthorizationStatusDenied:
            {
                handler(NO);
                break;
            }
            case AVAuthorizationStatusAuthorized:
            {
                handler(YES);
                break;
            }
            default:
            {
                handler(NO);
                break;
            }
        }
      
    • 麦克风权限另一种方式:

        AVAudioSessionRecordPermission micPermisson = [[AVAudioSession sharedInstance] recordPermission];
        if (micPermisson == AVAudioSessionRecordPermissionUndetermined) {
            [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
                handler(granted);
            }];
        } else if (micPermisson == AVAudioSessionRecordPermissionGranted) {
            handler(YES);
        } else {
            handler(NO);
        }
      

    相册权限管理

    导入头文件@import Photos (iOS 8.0 以后)

    • 判断相册权限:

        PHAuthorizationStatus photoStatus = [PHPhotoLibrary authorizationStatus];
        if (photoStatus == PHAuthorizationStatusNotDetermined) {
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                if (status == PHAuthorizationStatusAuthorized) {
                    handler(YES);
                } else {
                    handler(NO);
                }
            }];
        } else if (photoStatus == PHAuthorizationStatusAuthorized) {
            handler(YES);
        } else {
            handler(NO);
        }
      
    • 查看相册权限:

        PHAuthorizationStatus photoAuthorStatus = [PHPhotoLibrary authorizationStatus];
        switch (photoAuthorStatus) {
            case PHAuthorizationStatusAuthorized:
                NSLog(@"Authorized");
                break;
            case PHAuthorizationStatusDenied:
                NSLog(@"Denied");
                break;
            case PHAuthorizationStatusNotDetermined:
                NSLog(@"not Determined");
                break;
            case PHAuthorizationStatusRestricted:
                NSLog(@"Restricted");
                break;
            default:
                break;
        }
      

    通讯录

    • 判断通讯录权限

        if (IS_OS_9_OR_LATER) {
            CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
            if (status == CNAuthorizationStatusNotDetermined) {
                self.contactStore = [[CNContactStore alloc] init];
                [_contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
                    handler(granted);
                }];
            } else if (status == CNAuthorizationStatusAuthorized) {
                handler(YES);
            } else {
                handler(NO);
            }
        } else {  //iOS 8 and below
            ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
            if (status == kABAuthorizationStatusNotDetermined) {
                ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(nil, nil); 
                ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error){
                    handler(granted);
                    CFRelease(addressBook);
                });
            } else if (status == kABAuthorizationStatusAuthorized) {
                handler(YES);
            } else {
                handler(NO);
            }
        }
      

    日历和提醒权限

    • 判断日历或提醒权限

        EKEntityType type = eventType == EventAuthorizedCalendar ? EKEntityTypeEvent : EKEntityTypeReminder;
        EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:type];
        if (status == EKAuthorizationStatusNotDetermined) {
            if (!self.eventStore) {
                self.eventStore = [[EKEventStore alloc] init];
            }
            [self.eventStore requestAccessToEntityType:type completion:^(BOOL granted, NSError * _Nullable error) {
                handler(granted);
            }];
        } else if (status == EKAuthorizationStatusAuthorized) {
            handler(YES);
        } else {
            handler(NO);
        }
      

    定位权限

    • 判断定位权限

        -(void)accessLocation:(LocationAuthorizedType)authorizedType handler:(LocationHandler)handlr
        {
            CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
            if (status == kCLAuthorizationStatusNotDetermined) {
                if (!self.locationManager) {
                    self.locationManager = [[CLLocationManager alloc] init];
                    self.locationManager.delegate = self;
                }
                self.locationBlock = handlr;
                if (authorizedType == LocationAuthorizedAlways) {
                    [self.locationManager requestAlwaysAuthorization];
                } else {
                    [self.locationManager requestWhenInUseAuthorization];
                }
            } else if (status == kCLAuthorizationStatusAuthorizedAlways ||    status == kCLAuthorizationStatusAuthorizedWhenInUse){
                handlr(YES, nil);
            } else {
                handlr(NO, nil);
            }
        }
      
        #pragma mark - CLLocationManagerDelegate
        -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
        {
            _locationBlock(YES, nil);
        }
      
        -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
        {
            _locationBlock(YES, newLocation);
      
            [self.locationManager stopUpdatingLocation];
            self.locationManager.delegate=nil;
            self.locationManager = nil;
        }
      

    推送权限

    • 设置推送权限:

        UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:setting];
      
    • 查看推送权限:

        UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings];
        switch (settings.types) {
            case UIUserNotificationTypeNone:
                NSLog(@"None");
                break;
            case UIUserNotificationTypeAlert:
                NSLog(@"Alert Notification");
                break;
            case UIUserNotificationTypeBadge:
                NSLog(@"Badge Notification");
                break;
            case UIUserNotificationTypeSound:
                NSLog(@"sound Notification'");
                break;
            default:
                break;
        }
      

    特殊说明

    1. 一般第一次获取权限时,都会获取到一个类似未知或未设置的状态,当获取到这个状态时,再去获取相应的权限。

    2. 当重新安装App后,只有网络权限会使用之前的设置,其他权限都会提示用户选择。

    待续......

    相关文章

      网友评论

        本文标题:iOS 权限管理

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