Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 AVCaptureMetadataOutputObjectsDelegate method.

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 AVCaptureVideoDataOutput validates my session setup.

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

Interface:

@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;

@end

Setup:

- (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:

// DELEGATE METHOD NOT CALLED
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    NSLog(@"Metadata");
}

Any help is greatly appreciated!

like image 867
Ricardo RendonCepeda Avatar asked Sep 25 '13 02:09

Ricardo RendonCepeda


2 Answers

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.

Edit:

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];
like image 69
Ned Zepplin Avatar answered Oct 27 '22 01:10

Ned Zepplin


iOS 10 caused the same problem for me. I currently have the developer edition released at WWDC 2016. When I ran the app on a phone with iOS 9 the captureOutput:didOutputMetadataObjects: method was called again.

like image 21
Stan James Avatar answered Oct 27 '22 01:10

Stan James