Newer
Older
XinYang_IOS / XYSW / YHScanQRTool / YHAlbumScanQRManager.m
@zhangfeng zhangfeng on 7 Dec 2023 6 KB 1.8.0
//
//  YH_AlbumScanQRManager.m
//  YHScanQR
//
//  Created by Foxconn on 2018/1/20.
//  Copyright © 2018年 Foxconn. All rights reserved.
//

#import "YHAlbumScanQRManager.h"
#import <AVFoundation/AVFoundation.h>
#import <Photos/Photos.h>
#import "UIImage+YHImageSize.h"


@interface YHAlbumScanQRManager () <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
@property (nonatomic, strong) UIViewController *currentVC;
@property (nonatomic, strong) NSString *detectorString;
@end

@implementation YHAlbumScanQRManager

+ (instancetype)sharedManager {
    static YHAlbumScanQRManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[YHAlbumScanQRManager alloc] init];
    });
    return manager;
}

- (void)initialization {
    _isOpenAlret = YES;
}

- (void)readQRCodeFromAlbumWithCurrentController:(UIViewController *)currentController {
    [self initialization];
    self.currentVC = currentController;
    
    if (currentController == nil) {
        NSException *excp = [NSException exceptionWithName:@"YHScanQR" reason:@"readQRCodeFromAlbumWithCurrentController: 方法中的 currentController 参数不能为空" userInfo:nil];
        [excp raise];
    }
    
    // 1、 获取摄像设备
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    if (device) {
        // 判断授权状态
        PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
        if (status == PHAuthorizationStatusNotDetermined) { // 用户还没有做出选择
            // 弹框请求用户授权
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                if (status == PHAuthorizationStatusAuthorized) { // 用户第一次同意了访问相册权限
                    self.isAlbumAccessAuthorization = YES;
                    dispatch_sync(dispatch_get_main_queue(), ^{
                        [self enterImagePickerController];
                    });
                    
                } else { // 用户第一次拒绝了访问相机权限
                    if (self.isOpenAlret) {
                        [self createAlertViewWithMessage:@"您拒绝了访问相册权限"];
                    }
                }
            }];
            
        } else if (status == PHAuthorizationStatusAuthorized) { // 用户允许当前应用访问相册
            self.isAlbumAccessAuthorization = YES;
            [self enterImagePickerController];
        } else if (status == PHAuthorizationStatusDenied) { // 用户拒绝当前应用访问相册
            if (self.isOpenAlret) {
            NSString *message = @"请去-> [设置 - 隐私 - 照片 ] 打开访问开关";
                UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:message preferredStyle:(UIAlertControllerStyleAlert)];
                UIAlertAction *alertsure = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
                    //跳转到系统类
                    NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                    if([[UIApplication sharedApplication] canOpenURL:url]) {
                        
                        NSURL*url =[NSURL URLWithString:UIApplicationOpenSettingsURLString];
                        [[UIApplication sharedApplication] openURL:url];
                        
                    }
                }];
                
                [alertVC addAction:alertsure];
                [self.currentVC presentViewController:alertVC animated:YES completion:nil];
            }
        } else if (status == PHAuthorizationStatusRestricted) {
            if (self.isOpenAlret) {
            [self createAlertViewWithMessage:@"由于系统原因, 无法访问相册"];
            }
        }
    }
}

// 进入 UIImagePickerController
- (void)enterImagePickerController {
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    imagePicker.delegate = self;
    [self.currentVC presentViewController:imagePicker animated:YES completion:nil];
}

#pragma mark - - - UIImagePickerControllerDelegate
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [self.currentVC dismissViewControllerAnimated:YES completion:nil];
    if (self.delegate && [self.delegate respondsToSelector:@selector(YHAlbumScanQRManagerDidCancelWithImagePickerController:)]) {
        [self.delegate YHAlbumScanQRManagerDidCancelWithImagePickerController:self];
    }
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    // 对选取照片的处理,如果选取的图片尺寸过大,则压缩选取图片,否则不作处理
    UIImage *image = [UIImage imageSizeWithScreenImage:info[UIImagePickerControllerOriginalImage]];
    // CIDetector(CIDetector可用于人脸识别)进行图片解析,从而使我们可以便捷的从相册中获取到二维码
    // 声明一个 CIDetector,并设定识别类型 CIDetectorTypeQRCode
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
    
    // 取得识别结果
    NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
    
    if (features.count == 0) {
        if (self.isOpenAlret) {
             [self createAlertViewWithMessage:@"暂未识别出扫描的二维码"];
        }
        [self.currentVC dismissViewControllerAnimated:YES completion:nil];
        return;
        
    } else {
        for (int index = 0; index < [features count]; index ++) {
            CIQRCodeFeature *feature = [features objectAtIndex:index];
            NSString *resultStr = feature.messageString;
            self.detectorString = resultStr;
        }
        
        
        [self.currentVC dismissViewControllerAnimated:YES completion:^{
            if (self.delegate && [self.delegate respondsToSelector:@selector(YHAlbumScanQRManager:didFinishPickingMediaWithResult:)]) {
                [self.delegate YHAlbumScanQRManager:self didFinishPickingMediaWithResult:self.detectorString];
            }
        }];
    }
}

#pragma mark - - - set
- (void)setisOpenAlret:(BOOL)isOpenAlret {
    _isOpenAlret = isOpenAlret;
}
-(void) createAlertViewWithMessage:(NSString *)message{
    UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:message preferredStyle:(UIAlertControllerStyleAlert)];
    UIAlertAction *alertA = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
        
    }];
    
    [alertC addAction:alertA];
    [self.currentVC presentViewController:alertC animated:YES completion:nil];
}

@end