相机 相册 相关

2020-03-03  本文已影响0人  喵喵粉

swift

1. 请求权限

import Photos
import AVFoundation

typealias OperationBlock = () -> ()

class PrivilegeObj {
}

//
// MARK: - 相机 相册 权限
//
extension PrivilegeObj {

    // 相机权限
    class func extCameraPermissions(authorizedBlock: OperationBlock?, deniedBlock: OperationBlock?) {
        
        let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
        
        // .notDetermined  .authorized  .restricted  .denied
        if authStatus == .notDetermined {
            // 第一次触发授权 alert
            AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) in
                self.extCameraPermissions(authorizedBlock: authorizedBlock, deniedBlock: deniedBlock)
            })
        } else if authStatus == .authorized {
                if Thread.isMainThread {///回到主线程
                    authorizedBlock?()
                } else {
                        DispatchQueue.main.async {
                            authorizedBlock?()
                        }
                }
        } else {
                if Thread.isMainThread {///回到主线程
                    deniedBlock?()
                } else {
                        DispatchQueue.main.async {
                            deniedBlock?()
                        }
                }
        }
    }

    // 相册权限
    class func extPhotoAlbumPermissions(authorizedBlock: OperationBlock?, deniedBlock: OperationBlock?) {
        let authStatus = PHPhotoLibrary.authorizationStatus()
        
        // .notDetermined  .authorized  .restricted  .denied
        if authStatus == .notDetermined {
            // 第一次触发授权 alert
            PHPhotoLibrary.requestAuthorization { (status) in
                self.extPhotoAlbumPermissions(authorizedBlock: authorizedBlock, deniedBlock: deniedBlock)
            }
        } else if authStatus == .authorized  {
                if Thread.isMainThread {///回到主线程
                    authorizedBlock?()
                } else {
                        DispatchQueue.main.async {
                            authorizedBlock?()
                        }
                }
        } else {
                if Thread.isMainThread {///回到主线程
                    deniedBlock?()
                } else {
                        DispatchQueue.main.async {
                            deniedBlock?()
                        }
                }
        }
    }
}

2. demo

import UIKit
import MobileCoreServices

class ViewController: UIViewController {
    @IBOutlet weak var ivOringin: UIImageView!
    @IBOutlet weak var ivEdited: UIImageView!
    
    @IBAction func handelCameraEvent(_ sender: UIButton) {
        PrivilegeObj.extCameraPermissions(authorizedBlock: {
            self.startType(.camera)
        }) {[unowned self] in
            let vc = UIAlertController(title: "无法访问相机", message: "请在设置-隐私-相机中允许访问", preferredStyle: .alert)
            let okA = UIAlertAction(title: "设置", style: .default) { (_) in
                if #available(iOS 10.0, *) {
                    UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
                } else {
                    UIApplication.shared.openURL(URL(string: UIApplication.openSettingsURLString)!)
                }
            }
            let cancelA = UIAlertAction(title: "取消", style: .default)
            vc.addAction(okA)
            vc.addAction(cancelA)
            self.present(vc, animated: true, completion: nil)
        }
    }
    @IBAction func handelPhotoEvent(_ sender: UIButton) {
        PrivilegeObj.extPhotoAlbumPermissions(authorizedBlock: {
            self.startType()
            }) {[unowned self] in
                let vc = UIAlertController(title: "无法访问相册", message: "请在设置-隐私-相册中允许访问相册", preferredStyle: .alert)
                let okA = UIAlertAction(title: "设置", style: .default) { (_) in
                    if #available(iOS 10.0, *) {
                        UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
                    } else {
                        UIApplication.shared.openURL(URL(string: UIApplication.openSettingsURLString)!)
                    }
                }
                let cancelA = UIAlertAction(title: "取消", style: .default)
                vc.addAction(okA)
                vc.addAction(cancelA)
                self.present(vc, animated: true, completion: nil)
            }
    }
    ///照片库
    @IBAction func handelPhotoLibraryEvent(_ sender: UIButton) {
        self.startType(.savedPhotosAlbum)
    }
}
extension ViewController {
    
    ///拍视频/照片、选视频/照片
    fileprivate func startType(_ type: UIImagePickerController.SourceType = .photoLibrary) {
        
        ///1.相机是否可用, 否则用相册
        var sourceType = type
        if sourceType == .camera {
            if !UIImagePickerController.isSourceTypeAvailable(.camera) {
                sourceType = .photoLibrary
                DebugLog("相机不可用,使用相册")
            }
        }
        
        ///2.打印信息
        if let types = UIImagePickerController.availableMediaTypes(for: type) {
            DebugLog(types)
        }
        
        ///3.设置imagePicker
        let imagePicker = UIImagePickerController()
        imagePicker.sourceType = sourceType
        imagePicker.delegate = self
        imagePicker.allowsEditing = true
        imagePicker.mediaTypes = [kUTTypeMovie as String, kUTTypeImage as String]
        
        ///4.iphone ipad
        present(imagePicker, animated: true, completion: nil)
        
    }
}
extension ViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true, completion: nil)
        
        let mediaType = info[.mediaType]
        let mediaURL = info[.mediaURL]
        let originalImage = info[.originalImage]
        let editedImage = info[.editedImage]
        DebugLog(mediaType)
        DebugLog(mediaURL)
        
        var isMovie: Bool = false
        if let mdType = mediaType as? String {
            if mdType == kUTTypeMovie as String {
                isMovie = true
            }
        }
        
        if isMovie {
            ///1.视频
            guard let mdURL = mediaURL as? URL else {
                return
            }
            
            let path = mdURL.relativePath
            DebugLog("视频地址", path)
            
        } else {
            ///2.图片
            if Thread.isMainThread {
                if originalImage != nil {
                    ivOringin.image = (originalImage as! UIImage)
                }
                if editedImage != nil {
                    ivEdited.image = (editedImage as! UIImage)
                }
            } else {
                DispatchQueue.global().async {
                    DispatchQueue.main.async {
                        if originalImage != nil {
                            self.ivOringin.image = (originalImage as! UIImage)
                        }
                        if editedImage != nil {
                            self.ivEdited.image = (editedImage as! UIImage)
                        }
                    }
                }
            }
        }
    }
}

//
// MARK: - 相机配置可用
//
extension ViewController {
    func cameraSuportsMedia(mediaType:String, sourceType: UIImagePickerController.SourceType) -> Bool {
        if let availabelMediaTypes = UIImagePickerController.availableMediaTypes(for: sourceType) {
            for type in availabelMediaTypes {
                if type == mediaType{
                    return true
                }
            }
        }
        return false
    }
    ///摄像头可用
    func isCameraAvailable() -> Bool {
        return UIImagePickerController.isSourceTypeAvailable(.camera)
    }
    ///支持摄像
    func doesCameraSupportShootingVideos() -> Bool {
        return cameraSuportsMedia(mediaType: (kUTTypeMovie as NSString) as String, sourceType: .camera)
    }
    ///支持照相
    func doesCameraSupportTakingPhotos() -> Bool {
        return cameraSuportsMedia(mediaType: (kUTTypeImage as NSString) as String, sourceType: .camera)
    }
    ///前置摄像头可用
    func isFrontCameraAvailable() -> Bool {
        return UIImagePickerController.isCameraDeviceAvailable(.front)
    }
    ///后置摄像头可用
    func isRearCameraAvailable() -> Bool {
        return UIImagePickerController.isCameraDeviceAvailable(.rear)
    }
    ///前置闪光灯
    func isFlashAvailableOnFrontCamera() -> Bool {
        return UIImagePickerController.isFlashAvailable(for: .front)
    }
    ///后置闪光灯
    func isFlashAvailableOnRearCamera() -> Bool {
        return UIImagePickerController.isFlashAvailable(for: .rear)
    }
}

oc

@implementation CameraPrivateObj

///相机授权
+ (void)extCameraPermissions:(OperationBlock)authedBlock failed:(FailedBlock)failedBlock deniedBlock:(OperationBlock)deniedBlock {
    
    //1.设备是否支持
    if (![UIImagePickerController isSourceTypeAvailable:(UIImagePickerControllerSourceTypeCamera)]) {
        if (failedBlock) {
            failedBlock(NSLocalizedString(@"cameraUnable", @"设备相机不可用"));
        }
        return;
    }
    
    //2.是否已授权
    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
        
        AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        if( status == AVAuthorizationStatusAuthorized) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (authedBlock) {
                    authedBlock();
                }
            });
        } else if( status == AVAuthorizationStatusNotDetermined) {
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (deniedBlock) {
                    deniedBlock();
                }
            });
        }
    }];
}

///相册授权
+ (void)extPhotoPermissions:(OperationBlock)authedBlock failed:(FailedBlock)failedBlock deniedBlock:(OperationBlock)deniedBlock {
    
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        switch (status) {
            case PHAuthorizationStatusNotDetermined:
                break;
            case PHAuthorizationStatusAuthorized:
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (authedBlock) {
                        authedBlock();
                    }
                });
                break;
            default:
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (deniedBlock) {
                        deniedBlock();
                    }
                });
                break;
        }
    }];
}

@end

Demo

- (void)privateObjAuth {
    [CameraPrivateObj extCameraPermissions:^{
        [self xxx];
    } failed:^(NSString *tip) {
        [SVProgressHUD showErrorWithStatus:NSLocalizedString(@"cameraUnable", tip)];
    } deniedBlock:^{
        NSString *tips = NSLocalizedString(@"AVAuthorization", @"您没有权限访问相机");
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:tips message:nil preferredStyle:UIAlertControllerStyleAlert];
        [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
            // 点击取消
        }]];
        [alert addAction:[UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            // 点击确定
            if (@available(iOS 10.0, *)) {
                [UIApplication.sharedApplication openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
            } else {
                [UIApplication.sharedApplication openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
            }
        }]];
        [self presentViewController:alert animated:YES completion:nil];
    }];
}
上一篇 下一篇

猜你喜欢

热点阅读