网络权限管理
一、iOS网络情况分类:
- 通过App应用设置网络使用权限(关闭、WLAN、WLAN与蜂窝移动网)
- 直接设置手机网络情况(飞行模式、无线局域网络、蜂窝移动网络)
二、iOS开发使用到的网络判断类:
AFNetworkReachability或者Reachability来判断网络的可达性,这两个类可以判断网络是否可达,以及可达时网络的类型(WLAN还是蜂窝移动网络);
CTCellularData来判断网络数据是否受限,只有应用网络权限设置为WLAN与蜂窝移动网时,网络数据才会返回不受限;
三、组合关系:
权限 | 飞行模式/关闭网络 | 局域网 | 蜂窝移动网络 |
---|---|---|---|
关闭 | 不可达-数据受限 | 不可达-数据受限 | 不可达-数据受限 |
WLAN | 不可达-数据受限 | WLAN-数据受限 | 不可达-数据受限 |
WLAN和蜂窝移动网 | 不可达-数据受限 | WLAN-数据不受限 | WLAN-数据不受限 |
注:关闭网络,及关闭无线局域网和蜂窝移动网络。
四、特殊说明:
第一次安装应用(之前从未安装过),第一次启动App时,会提示选择网络,选择之后就不会提示选择网络;但有时第一次安装时不出现选择网络,需要在设置中修改任意一个应用的网络权限,然后重启App,就会提示网络(目前没有找到不出现选择网络的原因);
当网络由可达状态切换到不可达状态后,第一进入App时,系统会提示一次网络权限改变的提示;
修改网络权限时,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; }
特殊说明
一般第一次获取权限时,都会获取到一个类似未知或未设置的状态,当获取到这个状态时,再去获取相应的权限。
当重新安装App后,只有网络权限会使用之前的设置,其他权限都会提示用户选择。
待续......