iOS 权限管理

网络权限管理

一、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后,只有网络权限会使用之前的设置,其他权限都会提示用户选择。

待续......

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容

  • 一个 APP 需要使用各种权限,比如相机,相册,位置等等,一般情况下我们习惯用到的时候,就去判断权限然后调用系统的...
    雨影阅读 2,310评论 0 7
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,509评论 25 707
  • 打捞垃圾的人 这个人的岗位就是路边这一段河道 他的工作任务就是打捞河面的垃圾 行人和风源源...
    单老师码字阅读 389评论 4 7
  • 像是一匹马的回忆录,记录了自己一生的荣耀和屈辱,想起了那句老话“千里马常有而伯乐不常有”虽然黑骏马历经众多波折但结...
    韩东秀阅读 281评论 0 0
  • 其实很早以前就知道马克笔这种东西了,但并没有心动,只是认为:对,它是一种笔。仅此而已。 然而,真正品让我感受到...
    宇本人666阅读 2,894评论 0 12