title: Barcode Scanning in iOS 7
body: <p>I've written an application that takes advantage of the new <code>AVCaptureMetadataOutput</code> APIs in iOS 7 for barcode scanning. </p>
  
  <p>I have the following code in one of my view controllers:</p>
  
  <pre><code>- (void)viewDidLoad
  {
      [super viewDidLoad];
  
      highlightView = [[UIView alloc] init];
      [highlightView setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin];
      [[highlightView layer] setBorderColor:[[UIColor greenColor] CGColor]];
      [[highlightView layer] setBorderWidth:3.0];
      [[self view] addSubview:highlightView];
  
      session = [[AVCaptureSession alloc] init];
      device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
      input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
      [session addInput:input];
  
      output = [[AVCaptureMetadataOutput alloc] init];
      [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
      [session addOutput:output];
  
      [output setMetadataObjectTypes:[output availableMetadataObjectTypes]];
      [output setRectOfInterest:[[self view] bounds]];
  
      previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];
      [previewLayer setFrame:[[self view] bounds]];
      [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
      if ([[previewLayer connection] isVideoOrientationSupported]) {
          [[previewLayer connection] setVideoOrientation:(AVCaptureVideoOrientation)[[UIApplication sharedApplication] statusBarOrientation]];
      }
      [[[self view] layer] insertSublayer:previewLayer above:[[self view] layer]];
  
      [session startRunning];
      [[self view] bringSubviewToFront:highlightView];
  }
  
  - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
  {
      CGRect highlightViewRect = CGRectZero;
      AVMetadataMachineReadableCodeObject *barcode;
      NSArray *barCodeTypes = @[AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code,AVMetadataObjectTypeCode39Mod43Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];
  
      for (AVMetadataObject *metadata in metadataObjects) {
          if ([barCodeTypes containsObject:[metadata type]]) {
              barcode = (AVMetadataMachineReadableCodeObject *)[previewLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
              highlightViewRect = [barcode bounds];
              break;
          }
      }
  
      [highlightView setFrame:highlightViewRect];
      [delegate barcodeScannerController:self didFinishScanningWithBarcode:[barcode stringValue]];
  }
  </code></pre>
  
  <p>This code works in that it can detect various barcode types and convert barcodes into their string values. What I'm wondering why on iPhones, only barcodes near the center of the view are detected, while on iPads, only barcodes located near the bottom of the view are detected. It's a very peculiar behaviour, and in the case of the iPad, not intuitive at all.</p>