基本需求
拍照,比如拍身份证上传之类的,或者直接从手机相册取出照片,然后压缩,上传服务器。目前这个过程已经非常普遍。
权限是第一个要考虑的问题,另外,还有就是判断是否有摄像头,比如,模拟器就没有摄像头。
系统API
系统提供了一个UIImagePickerController
来做这个事,用起来不是很方便,不过代码基本上能找到,现在也很成熟了。
不过,总体感觉总是不大好。有没有更优雅的方法,或者有好用的第三方库吗?不想自己造轮子,当然想找个现成的轮子。
TZImagePickerController
这个第三方库有5K
多的star
,并且最近已经有更新,适配了iPhone XR
,看上去挺不错的,准备尝试一下。
- 新建工程,使用CocoaPod下载代码,申请权限。没有权限的话会崩溃。
Privacy - Camera Usage Description
Privacy - Location When In Use Usage Description
Privacy - Microphone Usage Description
Privacy - Photo Library Usage Description
- 在要使用的地方引入头文件,就像官网中介绍的,几行代码就可以了。
#import <TZImagePickerController/TZImagePickerController.h>
- (IBAction)photoButtonTouched:(id)sender {
TZImagePickerController *vc = [[TZImagePickerController alloc] initWithMaxImagesCount:9 delegate:nil];
[vc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
NSLog(@"photos: %@", photos);
}];
[self presentViewController:vc animated:YES completion:nil];
}
-
授权提醒,模拟器不支持相机的
log
输出,都做了,交互提示都很友好 -
先展示取照片界面,最后有拍照图标,还有预览功能,还能取原图,功能做得很丰富,很不错。
-
如果以上功能可以满足需求,强烈建议使用。比直接使用系统的
UIImagePickerController
方便很多。
官网链接: TZImagePickerController
关于相机授权
- 需要在plist中添加权限申请,不然会崩溃
- 模拟器是没有相机的,如何判断?
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
if ([UIImagePickerController isSourceTypeAvailable: sourceType]) {
// 有相机设备,打开相机照相
} else {
NSLog(@"模拟器中无法打开照相机,请在真机中使用");
}
- 是否授权,如何判断?
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
有如下几种状态:
typedef NS_ENUM(NSInteger, AVAuthorizationStatus) {
AVAuthorizationStatusNotDetermined = 0,
AVAuthorizationStatusRestricted = 1,
AVAuthorizationStatusDenied = 2,
AVAuthorizationStatusAuthorized = 3,
} API_AVAILABLE(macos(10.14), ios(7.0)) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
-
AVAuthorizationStatusAuthorized
说明用户已经授权使用相机,可以放心操作。 -
AVAuthorizationStatusNotDetermined
这个状态要注意一下,这是后,“设置”中是无法找到对应设置项的。这个时候,要弹出“系统的授权对话框”对话框的内容就是在plist
中设置的自定义文本框。
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
// 用户同意授权
} else {
// 用户拒绝授权
}
}];
-
AVAuthorizationStatusRestricted、AVAuthorizationStatusDenied
这时候应该自定义一个Alert
对话框,提醒用户去手机的"设置"页面打开授权。
// 提示用户去设置
if ((status == AVAuthorizationStatusRestricted) || (status == AVAuthorizationStatusDenied)) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"无法使用相机" message:@"请在iPhone的\"设置-隐私-相机\"中允许%@访问相机" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *setAction = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:setAction];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];
}
- TZImagePickerController中关于相机授权的代码如下,可以参考一下:
/// 拍照按钮点击事件
- (void)takePhoto {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if ((authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)) {
NSDictionary *infoDict = [TZCommonTools tz_getInfoDictionary];
// 无权限 做一个友好的提示
NSString *appName = [infoDict valueForKey:@"CFBundleDisplayName"];
if (!appName) appName = [infoDict valueForKey:@"CFBundleName"];
NSString *message = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Please allow %@ to access your camera in \"Settings -> Privacy -> Camera\""],appName];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Can not use camera"] message:message delegate:self cancelButtonTitle:[NSBundle tz_localizedStringForKey:@"Cancel"] otherButtonTitles:[NSBundle tz_localizedStringForKey:@"Setting"], nil];
[alert show];
} else if (authStatus == AVAuthorizationStatusNotDetermined) {
// fix issue 466, 防止用户首次拍照拒绝授权时相机页黑屏
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[self pushImagePickerController];
});
}
}];
} else {
[self pushImagePickerController];
}
}
网友评论