QR Code in iOS7

iOS7 之後內建 QR code/Bar code 功能,
不用再安裝 ZBar 等第三方 library,方便許多,
使用流程如下:

  • configure device
  • create session(協助處理input/output)
  • add input
  • add output
configure device
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]){
    if([device lockForConfiguration:&error]) {
        CGPoint autofocusPoint = CGPointMake(0.5f, 0.5f);
        [device setFocusPointOfInterest:autofocusPoint];
        [device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
        [device unlockForConfiguration];
    }
    else{
        NSLog(@"configuration error");
    }
}
create session
AVCaptureSession *session = [[AVCaptureSession alloc]init];
add input
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if ([session canAddInput:input]) {
    [session addInput:input];
}
else {
    NSLog(@"can not add input");
}
add output

setMetadataObjectTypes 必需在 addOutput 之後,不然會噴 error[1]。

AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
if([session canAddOutput:output]){
    [session addOutput:output];
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    // setMetadataObjectTypes must be call after addOutput
    [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
}

大致上這樣就完成了,但真正執行時,空白一片,
加個 preview layer 把 camera video 顯示出來,這樣感覺好多了...:D

AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.view.frame;
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:captureVideoPreviewLayer];

[session startRunning];

20150731 更新:
回來看兩年前的 code 居然還是花了不少時間,決定包成 BarcodeManager 方便以後使用,詳見 github

[1]*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVCaptureMetadataOutput setMetadataObjectTypes:] - unsupported type found. Use -availableMetadataObjectTypes.'

Reference