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];
}];
}
网友评论