Ricardo RendonCepeda Ricardo RendonCepeda - 1 year ago 95
iOS Question

iOS 7 AVCaptureMetadataOutput delegate (QRCode scanner)

I'm trying to implement a QRCode scanner with the new iOS 7 features but my code isn't calling the main


I've used the AVFoundation camera before and with my current implementation I've got the preview layer running without a problem. Even switching my output back to
validates my session setup.

I'm using this NSHipster post as a guideline and here's my code so far:


@import AVFoundation;

@interface QRCodeViewController () <AVCaptureMetadataOutputObjectsDelegate>

@property (strong, nonatomic) AVCaptureDevice* device;
@property (strong, nonatomic) AVCaptureDeviceInput* input;
@property (strong, nonatomic) AVCaptureMetadataOutput* output;
@property (strong, nonatomic) AVCaptureSession* session;
@property (strong, nonatomic) AVCaptureVideoPreviewLayer* preview;



- (void)setupCamera
// Device
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

// Input
self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];

// Output
self.output = [[AVCaptureMetadataOutput alloc] init];
[self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

// Session
self.session = [[AVCaptureSession alloc] init];
[self.session addInput:self.input];
[self.session addOutput:self.output];

// Preview
self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.preview.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view.layer insertSublayer:self.preview atIndex:0];

// Start
[self.session startRunning];

Delegate Method:

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

Any help is greatly appreciated!

Answer Source

I am trying to figure this out myself. The documentation seems to say that if you don't set the type(s) you want in metadataObjectTypes, you won't get any calls. But my iPad Mini's back camera returns an empty array for availableMetadataObjectTypes. Let us know what you figure out.


I just figured out that if you add the AVCaptureMetadataOutput object to the session, the availableMetadataObjectTypes gets filled in and you can add the barcode detector to it. Then the captureOutput delegate will get called, so like this:

AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];