iOS系統開發中,最經常使用的系統受權,莫過於系統通知
,用戶相冊
,位置服務
了,這篇文章將簡單講解這三項功能的開發,並附帶我寫的一個開源項目,統一管理系統受權。git
注:本文和項目基於iOS 8.0
及以上系統框架,低版本框架接口略有不一樣。github
系統通知方法在UIApplication類方法中,其中使用isRegisteredForRemoteNotifications
獲取本地推送受權狀態。swift
+ (UIUserNotificationType)notificationType { UIApplication* application = [UIApplication sharedApplication]; return [application currentUserNotificationSettings].types; }
這裏受權狀態的枚舉類型有app
UIUserNotificationTypeNone
無受權框架
UIUserNotificationTypeBadge
角標工具
UIUserNotificationTypeSound
聲音this
UIUserNotificationTypeAlert
通知spa
原枚舉以下rest
typedef NS_OPTIONS(NSUInteger, UIUserNotificationType) { UIUserNotificationTypeNone = 0, // the application may not present any UI upon a notification being received UIUserNotificationTypeBadge = 1 << 0, // the application may badge its icon upon a notification being received UIUserNotificationTypeSound = 1 << 1, // the application may play a sound upon a notification being received UIUserNotificationTypeAlert = 1 << 2, // the application may display an alert upon a notification being received } NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;
受權方法code
UIUserNotificationType type = UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound; UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:type categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:setting];
注意,每一項受權,一旦用戶拒絕,必須前往設置
的相關APP頁面開啓。APP內跳設置
的方法是
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
註冊本地通知也是有回調的,實現UIApplicationDelegate
的didRegisterUserNotificationSettings
方法。
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { }
相應的也有失敗的回調。
8.0系統版本之後,框架中加入了Photos.framework
框架,固然是用UIImagePickerController
一樣會提醒用戶受權使用相冊或相機,這裏介紹一下Photos
框架的受權。
相冊權限狀態
+ (PHAuthorizationStatus)photoAccesStatus { return [PHPhotoLibrary authorizationStatus]; }
typedef NS_ENUM(NSInteger, PHAuthorizationStatus) { PHAuthorizationStatusNotDetermined = 0, // User has not yet made a choice with regards to this application PHAuthorizationStatusRestricted, // This application is not authorized to access photo data. // The user cannot change this application’s status, possibly due to active restrictions // such as parental controls being in place. PHAuthorizationStatusDenied, // User has explicitly denied this application access to photos data. PHAuthorizationStatusAuthorized // User has authorized this application to access photos data. } NS_AVAILABLE_IOS(8_0);
這裏受權狀態有四個狀態
PHAuthorizationStatusNotDetermined
未受權
PHAuthorizationStatusRestricted
受權中
PHAuthorizationStatusDenied
拒絕
PHAuthorizationStatusAuthorized
已受權
受權Block方法
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { }];
位置服務受權稍微複雜一點點,8.0之後,進行位置服務受權要注意一點是,須要在工程的Info.plist
文件中加入NSLocationAlwaysUsageDescription
字段。字段中是開發者展現給用戶的位置服務的使用場景介紹,或者是請求受權的描述。若是不添加這個字段,受權接口無任何反應。
狀態接口
+ (CLAuthorizationStatus)positionAuthorizationStatus { return [CLLocationManager authorizationStatus]; }
受權方法
+ (void)authorizedPosition:(CLLocationManager *)manager { [manager requestAlwaysAuthorization]; }
注意這裏傳入的manager必定要是個property
,若是是一個局部變量,大括號結束,釋放掉了,受權就會消失,就會出現受權框一閃而過的現象。
開源項目 DeviceAccessViewController
PermissionScope
(Github)是一個超級屌,而且好用的開源控件,用來向用戶申請系統受權。若是你有使用cocospod
管理工具,這樣加入use_frameworks!
,由於PermissionScope
是swift
寫的,須要編譯成Framework才能夠給ObjC用。
use_frameworks! pod 'PermissionScope'
具體用法
PermissionScope* scope = [[PermissionScope alloc] initWithBackgroundTapCancels:YES]; //[scope addPermission:[[CameraPermission alloc] init] message:@"請求使用您的相機"]; //[scope addPermission:[[BluetoothPermission alloc] init] message:@"請求使用您的藍牙"]; //[scope addPermission:[[ContactsPermission alloc] init] message:@"請求使用您的通信錄"]; //[scope addPermission:[[EventsPermission alloc] init] message:@"請求使用您的日曆"]; [scope addPermission:[[LocationAlwaysPermission alloc] init] message:@"請求使用您的位置"]; [scope addPermission:[[MicrophonePermission alloc] init] message:@"請求使用您的麥克風"]; [scope addPermission:[[NotificationsPermission alloc] initWithNotificationCategories:nil] message:@"請求使用通知服務"]; [scope show:^(BOOL s, NSArray<PermissionResult *> * _Nonnull results) { } cancelled:^(NSArray<PermissionResult *> * _Nonnull canceled) { }];
這個例子很明瞭吧,但要注意幾點
最少要添加一個Permission
最多添加3個Permission
8.0之後,進行位置服務受權,須要在工程的Info.plist
文件中加入NSLocationAlwaysUsageDescription
字段。