美文网首页
取照片实践2018

取照片实践2018

作者: 勇往直前888 | 来源:发表于2018-09-29 11:00 被阅读44次

基本需求

拍照,比如拍身份证上传之类的,或者直接从手机相册取出照片,然后压缩,上传服务器。目前这个过程已经非常普遍。
权限是第一个要考虑的问题,另外,还有就是判断是否有摄像头,比如,模拟器就没有摄像头。

系统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中添加权限申请,不然会崩溃
image.png
  • 模拟器是没有相机的,如何判断?
    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;
  1. AVAuthorizationStatusAuthorized说明用户已经授权使用相机,可以放心操作。

  2. AVAuthorizationStatusNotDetermined这个状态要注意一下,这是后,“设置”中是无法找到对应设置项的。这个时候,要弹出“系统的授权对话框”对话框的内容就是在plist中设置的自定义文本框。

        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                // 用户同意授权
            } else {
                // 用户拒绝授权
            }
        }];
  1. 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];
    }
/// 拍照按钮点击事件
- (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];
    }
}

相关文章

网友评论

      本文标题:取照片实践2018

      本文链接:https://www.haomeiwen.com/subject/dpljoftx.html