目录
相册权限
+ (void)photosWithIsShowNoAuthorizedAlert:(BOOL)isShow
isOnlyAdd:(BOOL)isOnlyAdd
authorized:(void(^)(BOOL isAuthorized))authorized {
/**
PHAuthorizationStatusNotDetermined = 0,//未决状态
PHAuthorizationStatusRestricted,//设备限制了对照片库的访问权限,比如家长控制
PHAuthorizationStatusDenied,// 明确拒绝了
PHAuthorizationStatusAuthorized,// 已经授权
PHAuthorizationStatusLimited API_AVAILABLE(ios(14)),,//只授权用户选择的照片而不是授权所有照片
*/
[self requestPhotosIsOnlyAdd:isOnlyAdd handler:^(PHAuthorizationStatus status) {
if (@available(iOS 14, *)) {
if (status == PHAuthorizationStatusAuthorized) {
if (authorized) { authorized(YES);}
return;
} else if (status == PHAuthorizationStatusLimited) {
if (authorized) { authorized(YES);}
return;
}
} else {
if (status == PHAuthorizationStatusAuthorized) {
if (authorized) { authorized(YES);}
return;
}
}
//获取授权失败
if (authorized) { authorized(NO);}
if (isShow) {
// 需要根据app风格,封装风格统一的提示弹框
[self showAlertViewWithTitle:@"需开启以下权限:照片" content:@"开启授权才可以使用此功能"];
}
}];
}
/// 请求相册权限
/// - Parameters:
/// - isOnlyAdd: 是否请求 仅添加照片权限
/// - handler: 结果回调
+ (void)requestPhotosIsOnlyAdd:(BOOL)isOnlyAdd handler:(void(^)(PHAuthorizationStatus status))handler {
if (@available(iOS 14, *)) {
// iOS14对相册权限的管理更加精细化了增加了:PHAccessLevelAddOnly(仅添加) 和 PHAccessLevelReadWrite(可读取可添加)
// 如果level传入的是PHAccessLevelAddOnly,用户在设置处设置的 "仅添加照片权限" 这是返回的status是PHAuthorizationStatusAuthorized
// 如果level传入的是PHAccessLevelReadWrite,用户在设置处设置的 "仅添加照片权限" 这是返回的status是PHAuthorizationStatusDenied
//
// iOS14增加了另外一个新权限:PHAuthorizationStatusLimited,只允许授权用户选择的照片而不是授权所有照片
PHAccessLevel level = isOnlyAdd ? PHAccessLevelAddOnly : PHAccessLevelReadWrite;
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatusForAccessLevel:level];
if (status == PHAuthorizationStatusNotDetermined) {
[PHPhotoLibrary requestAuthorizationForAccessLevel:level handler:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
if (handler) {handler(status);};
});
}];
} else {
if (handler) {handler(status);};
}
} else {
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusNotDetermined) {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
if (handler) {handler(status);};
});
}];
} else {
if (handler) {handler(status);};
}
}
}
相机权限
+ (void)cameraWithIsShowNoAuthorizedAlert:(BOOL)isShow authorized:(void(^)(BOOL isAuthorized))authorized {
/**
AVAuthorizationStatusNotDetermined = 0,// 未决状态
AVAuthorizationStatusRestricted = 1,//设备限制了对照片库的访问权限,比如家长控制
AVAuthorizationStatusDenied = 2,// 明确拒绝了
AVAuthorizationStatusAuthorized = 3,// 已经授权
*/
[self requestCamera:^(AVAuthorizationStatus status) {
if (status == AVAuthorizationStatusAuthorized){
if (authorized) { authorized(YES);}
} else {
if (authorized) { authorized(NO);}
if (isShow) {
[self showAlertViewWithTitle:@"需开启以下权限:相机" content:@"开启授权才可以使用相机功能"];
}
}
}];
}
+ (void)requestCamera:(void(^)(AVAuthorizationStatus status))handler {
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (status == AVAuthorizationStatusNotDetermined) {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
dispatch_async(dispatch_get_main_queue(), ^{
if(granted){
if (handler) {handler(AVAuthorizationStatusAuthorized);};
}else {
if (handler) {handler(AVAuthorizationStatusDenied);};
}
});
}];
} else {
if (handler) {handler(status);};
}
}
定位权限
+ (void)locationWithIsShowNoAuthorizedAlert:(BOOL)isShow authorized:(void(^)(BOOL isAuthorized))authorized {
/**
// 未决状态
kCLAuthorizationStatusNotDetermined = 0,
// 设备限制了对照片库的访问权限,比如家长控制
kCLAuthorizationStatusRestricted,
// 已经拒绝
kCLAuthorizationStatusDenied,
// 始终允许
kCLAuthorizationStatusAuthorizedAlways API_AVAILABLE(macos(10.12), ios(8.0)),
// 仅应用使用期间,推荐
kCLAuthorizationStatusAuthorizedWhenInUse API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos),
// 已经废弃
kCLAuthorizationStatusAuthorized API_DEPRECATED("Use kCLAuthorizationStatusAuthorizedAlways", ios(2.0, 8.0)) API_AVAILABLE(macos(10.6)) API_UNAVAILABLE(watchos, tvos) = kCLAuthorizationStatusAuthorizedAlways
*/
[self requestLocation:^(CLAuthorizationStatus status) {
if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse){
if (authorized) { authorized(YES);}
} else {
if (authorized) { authorized(NO);}
if (isShow) {
[self showAlertViewWithTitle:@"需开启以下权限:定位(需要开启系统定位服务)" content:@"开启授权才可以使用定位功能"];
}
}
}];
}
+ (void)requestLocation:(void(^)(CLAuthorizationStatus status))handler {
FZAuthorizationTool *tool = [[FZAuthorizationTool alloc] init];
CLAuthorizationStatus status = kCLAuthorizationStatusNotDetermined;
if (@available(iOS 14.0, *)) {
status = [tool.manager authorizationStatus];
} else {
status = [CLLocationManager authorizationStatus];
}
if (status == kCLAuthorizationStatusNotDetermined) {
[tool.manager requestWhenInUseAuthorization];
void(^temp)(CLAuthorizationStatus status) = ^(CLAuthorizationStatus tempStatus) {
if (handler) {handler(tempStatus);};
};
tool.locationBlock = temp;
} else {
if (handler) {handler(status);};
}
}
// 启动定位
+ (void)startUpdatingLocation:(void (^)(id data))handler {
FZAuthorizationTool *tool = [[FZAuthorizationTool alloc] init];
tool.getLocationsCallBlock = handler;
[tool.manager startUpdatingLocation];
}
代理方法
//ios(14.0) 的代理回调
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager {
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status != kCLAuthorizationStatusNotDetermined && self.locationBlock) {
self.locationBlock(status);
self.locationBlock = nil;
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
[self.manager stopUpdatingLocation];
CLLocation *currLocation = [locations lastObject];
if (self.getLocationsCallBlock) {
self.getLocationsCallBlock(@{@"latitude":@(currLocation.coordinate.latitude),@"longitude":@(currLocation.coordinate.longitude)});
self.getLocationsCallBlock = nil;
}
}
//定位失败
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
[self.manager stopUpdatingLocation];
if (self.getLocationsCallBlock) {
self.getLocationsCallBlock(@{});
self.getLocationsCallBlock = nil;
}
}
- (CLLocationManager *)manager {
if (!_manager) {
_manager = [[CLLocationManager alloc] init];
_manager.delegate = self;
}
return _manager;
}
NFC权限
一. 权限添加
当应用程序在capability添加NFC权限,但我们的描述文件没有包含响应的NFC权限就会报下面的错误
Showing Recent Messages
Provisioning profile “com.xxx.xxx.development” doesn’t support the Near Field Communication Tag Reading capability.
Showing Recent Messages
Provisioning profile “com.xxx.xxx.development” doesn’t include the com.apple.developer.nfc.readersession.formats entitlement.
在开发者网站,找到对应的bundleID,找到Capabilities,添加NFC Tag Reading权限,保存.
删除原有的描述文件,重新生成新的描述文件
二. NFC
当我们在不支持NFC的手机上调用相关接口时会报错
-[NFCHardwareManager queueReaderSession:sessionConfig:completionHandler:]:96 error=Error Domain=NFCError Code=1 "Feature not supported" UserInfo={NSLocalizedDescription=Feature not supported}
-[NFCTagReaderSession beginSessionWithConfig:]:365 error:Error Domain=NFCError Code=1 "Feature not supported" UserInfo={NSLocalizedDescription=Feature not supported}, errorCode: 0x1
在iPhone7之后才支持NFC功能
行者常至,为者常成!