iOS系统权限简单封装

前提条件

苹果审核要求使用隐私权限必须在plist文件中详细的描述使用用途,以下文为例,可以直接复制到plist文件中。

1
2
3
4
5
6
7
8
9
10
<key>NSCameraUsageDescription</key>
<string>开启访问相机权限可以拍摄您喜欢的照片设置为菜品样照</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>开启添加照片权限可以将您喜欢的图片保存在本地相册</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>开启访问相册权限可以选择您喜欢的照片设置为菜品样照</string>
<key>NSLocationUsageDescription</key>
<string>开启定位权限可以选择您的店铺位置</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>开启定位权限可以选择您的店铺位置</string>

系统要求

ios >= 9.0

使用方法

使用iOS 类别特性,添加NSObject类别 NSObject+Privacy ,使用简单方便。

  1. 引入头文件 #import "NSObject+Privacy.h"

  2. 添加代码

    1
    2
    3
    4
    5
    [self checkPrivacyEnable:PhotoLibraryPrivacy withResult:^(BOOL result) {
    if (result) {

    }
    }];

相关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
//
// NSObject+Privacy.m
// Privacy
//
// Created by 洪强 on 2019/2/23.
// Copyright © 2019 洪强. All rights reserved.
//

#import "NSObject+Privacy.h"
#import <Photos/Photos.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreLocation/CoreLocation.h>
#import <UserNotifications/UserNotifications.h>

typedef void (^ PrivacyCancelBlock)(void);

@implementation NSObject (Privacy)

- (void)checkPrivacyEnable:(SystemPrivacy)type withResult:(void (^)(BOOL result))result {

[self checkPrivacyEnableWithAlert:NO WithType:type withResult:result withCancel:nil];
}

- (void)checkPrivacyEnableWithAlert:(SystemPrivacy)type withResult:(void (^)(BOOL result))result {

[self checkPrivacyEnableWithAlert:YES WithType:type withResult:result withCancel:nil];
}

- (void)checkPrivacyEnableWithAlert:(SystemPrivacy)type withResult:(void (^)(BOOL result))result withCancel:(void (^)(void))cancel {

[self checkPrivacyEnableWithAlert:YES WithType:type withResult:result withCancel:cancel];
}

- (void)checkPrivacyEnableWithAlert:(BOOL)isAlert WithType:(SystemPrivacy)type withResult:(void (^)(BOOL result))result withCancel:(void (^)(void))cancel {

if (type == CameraPrivacy) { // 相机权限

NSString *mediaType = AVMediaTypeVideo;
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied ) {

if (isAlert) {

[self showAlertViewWithTitle:@"开启相机权限" WithMessage:[NSString stringWithFormat:@"相机权限未开启,请进入系统【设置】>【隐私】>【相机】中打开开关,并允许%@使用相机",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]] WithAlertTitle:@"立即开启" WithCancelTitle:@"取消" WithCancelBlock:^{
if (cancel) {
cancel();
}
}];
}
result(NO);
}else {
result(YES);
}

}else if (type == PhotoLibraryPrivacy) { // 相册权限

PHAuthorizationStatus author = [PHPhotoLibrary authorizationStatus];
if (author == PHAuthorizationStatusRestricted || author == PHAuthorizationStatusDenied) {
//无权限
if (isAlert) {

[self showAlertViewWithTitle:@"开启照片权限" WithMessage:[NSString stringWithFormat:@"照片权限未开启,请进入系统【设置】>【隐私】>【照片】中打开开关,并允许%@使用照片",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]] WithAlertTitle:@"立即开启" WithCancelTitle:@"取消" WithCancelBlock:^{
if (cancel) {
cancel();
}
}];
}
result(NO);
}else {
result(YES);
}

}else if (type == MicrophonePrivacy) { // 麦克风权限

AVAudioSessionRecordPermission permissionStatus = [[AVAudioSession sharedInstance] recordPermission];

switch (permissionStatus) {
case AVAudioSessionRecordPermissionUndetermined: {

NSLog(@"第一次调用,是否允许麦克风弹框");
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
if (granted) {
result(NO);
}else {
result(NO);
}
}];
break;
}
case AVAudioSessionRecordPermissionDenied: {

NSLog(@"已经拒绝麦克风弹框");
if (isAlert) {

[self showAlertViewWithTitle:@"开启麦克风权限" WithMessage:[NSString stringWithFormat:@"麦克风权限未开启,请进入系统【设置】>【隐私】>【麦克风】中打开开关,并允许%@使用麦克风",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]] WithAlertTitle:@"立即开启" WithCancelTitle:@"取消" WithCancelBlock:^{
if (cancel) {
cancel();
}
}];
}
result(NO);
break;
}
case AVAudioSessionRecordPermissionGranted: {

NSLog(@"已经允许麦克风弹框");
result(YES);
break;
}
default:

result(YES);
break;
}
}else if (type == LocationPrivacy) { // 位置权限

BOOL enable = [CLLocationManager locationServicesEnabled];
int status = [CLLocationManager authorizationStatus];

if (!enable || status == 1 || status == 2) {

if (isAlert) {

[self showAlertViewWithTitle:@"开启定位权限" WithMessage:[NSString stringWithFormat:@"定位服务未开启,请进入系统【设置】>【隐私】>【定位服务】中打开开关,并允许%@使用定位服务",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]] WithAlertTitle:@"立即开启" WithCancelTitle:@"取消" WithCancelBlock:^{
if (cancel) {
cancel();
}
}];
}
result(NO);
}else {
result(YES);
}
}else if (type == UserNotificationPrivacy) { // 通知权限

if (@available(iOS 10.0, *)) {

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {

if (granted) {

//获取用户是否同意开启通知
NSLog(@"已经允许通知");
result(YES);

}else {
if (isAlert) {

[self showAlertViewWithTitle:@"开启通知权限" WithMessage:[NSString stringWithFormat:@"通知权限未开启,请进入系统【设置】>【通知】>【%@】中打开开关,允许通知",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]] WithAlertTitle:@"立即开启" WithCancelTitle:@"取消" WithCancelBlock:^{
if (cancel) {
cancel();
}
}];
}
result(NO);
}
}];
}else {

if ([[UIApplication sharedApplication] currentUserNotificationSettings].types <= UIUserNotificationTypeNone) {

if (isAlert) {

[self showAlertViewWithTitle:@"开启通知权限" WithMessage:[NSString stringWithFormat:@"通知权限未开启,请进入系统【设置】>【通知】>【%@】中打开开关,允许通知",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]] WithAlertTitle:@"立即开启" WithCancelTitle:@"取消" WithCancelBlock:^{
if (cancel) {
cancel();
}
}];
}
result(NO);

}else {
result(YES);
}
}
}
}

- (void)showAlertViewWithTitle:(NSString *)title WithMessage:(NSString *)msg WithAlertTitle:(NSString *)alertTitle WithCancelTitle:(NSString *)cancelTitle WithCancelBlock:(PrivacyCancelBlock)cancelBlock {

UIAlertController * alert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *alertAction = [UIAlertAction actionWithTitle:alertTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
if (cancelBlock) {
cancelBlock();
}
}];
[alert addAction:alertAction];
[alert addAction:cancelAction];

UIViewController *rootViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
[rootViewController presentViewController:alert animated:YES completion:nil];
}

@end

项目地址

点击查看