iOS 扫描条形码和二维码

使用 AVFoundation类 可以使相机识别二维码和条形码

Demo地址:

https://github.com/muyan091115/Scan

效果图:

Demo.gif

一、info.plist插入申请权限提示:

info.plist.png

或者以代码方式打开 加入

NSCameraUsageDescription
    需要扫描

二、请求相机权限

mediaType 选择 AVMediaTypeVideo 只需要录像的权限

#import 
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (granted) {
                
                [self setupScan];
                
            } else {
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"没有权限" message:@"" delegate:nil cancelButtonTitle:@"好" otherButtonTitles:nil];
                [alertView show];
            }
            
        });
    }];

三、设置相机属性 并 开始扫描

  • 获取相机设备
  • 创建输入输出流
  • 设置代理 并 指定刷新的线程
  • 创建session 设置其采集率 并为session添加输入输出流
  • 设置输出流支持的格式
    a、 二维码:AVMetadataObjectTypeQRCode
    b、 条形码:
    AVMetadataObjectTypeEAN13Code,
    AVMetadataObjectTypeEAN8Code,
    AVMetadataObjectTypeUPCECode,
    AVMetadataObjectTypeCode39Code,
    AVMetadataObjectTypeCode39Mod43Code,
    AVMetadataObjectTypeCode93Code,
    AVMetadataObjectTypeCode128Code,
    AVMetadataObjectTypePDF417Code
  • 根据session 创建相机layer
  • 把相机layer添加到vc试图中

⚠️ 注意:尽量不要把二维码和条形码的格式都支持到输出流,这样会影响扫描的性能。

- (void)setupScan {
   
   AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
   AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
   AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc]init];
   [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
   
   self.session = [[AVCaptureSession alloc]init];
   [self.session setSessionPreset:AVCaptureSessionPresetHigh];
   
   [self.session addInput:input];
   [self.session addOutput:output];
   
   //qrcode
   if ([self.type isEqualToString:@"01"]) {
       
       output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode];
       
   //barcode
   } else if ([self.type isEqualToString:@"02"]) {
       
       output.metadataObjectTypes=@[AVMetadataObjectTypeEAN13Code,
                                    AVMetadataObjectTypeEAN8Code,
                                    AVMetadataObjectTypeUPCECode,
                                    AVMetadataObjectTypeCode39Code,
                                    AVMetadataObjectTypeCode39Mod43Code,
                                    AVMetadataObjectTypeCode93Code,
                                    AVMetadataObjectTypeCode128Code,
                                    AVMetadataObjectTypePDF417Code];
       
   }
   
   AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
   layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
   layer.frame = self.view.layer.bounds;
   [self.view.layer insertSublayer:layer atIndex:10003];
   
   [self.session startRunning];
   
}

四、在代理方法中获取扫码结果

返回的类型是AVMetadataMachineReadableCodeObject的数组
获取第一个的stringValue属性,就是对应扫码的内容

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {

    if (metadataObjects.count > 0) {
        AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects[0];
        NSString *result = metadataObject.stringValue;
        
        self.hasScan(result);
        [self.session stopRunning];
        [self dismissViewControllerAnimated:YES completion:nil];
        
    }
}

获取结果后block 回传给上一级vc

你可能感兴趣的:(iOS 扫描条形码和二维码)