Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: [AVCaptureMetadataOutput setMetadataObjectTypes:] Unsupported type found - use -availableMetadataObjectTypes'
5、创建并设置AVCaptureVideoPreviewLayer对象来显示捕获到的视频。
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[previewLayer setFrame:self.view.bounds];
[self.view.layer addSublayer:previewLayer];
6、给AVCaptureSession对象发送startRunning消息以启动视频捕获。
[captureSession startRunning];
7、实现AVCaptureMetadataOutputObjectsDelegate的captureOutput:didOutputMetadataObjects:fromConnection:方法来处理捕获到的元数据,并将其读取出来。
- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects != nil && metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects.firstObject;
if ([[metadataObject type] isEqualToString:AVMetadataObjectTypeQRCode]) {
NSString *message = [metadataObject stringValue];
[self.label performSelectorOnMainThread:@selector(setText:) withObject:message waitUntilDone:NO];
}
}
}
需要提醒的是,由于AVCaptureMetaDataOutput对象代理的设置,该代理方法会在setMetadataObjectsDelegate:queue:指定的队列上调用,如果需要更新用户界面,则必须在主线程中进行。
2 应用示例
下面,我们就做一个如下图所示的二维码阅读器:

其中主要实现的功能有:
-
通过摄像头实时扫描并读取二维码。
解析从相册中选择的二维码图片。
由于二维码的扫描是基于实时的视频捕获,因此相关的操作无法在模拟器上进行测试,也不能在没有相机的设备上进行测试。如果想要查看该应用,需要连接自己的iPhone设备来运行。
2.1 创建项目
打开Xcode,创建一个新的项目(FileNewProject...),选择iOS一栏下的Application中的Single View Application模版,然后点击Next,填写项目选项。在Product Name中填写QRCodeReaderDemo,选择Objective-C语言,点击Next,选择文件位置,并单击Create创建项目。

2.2 构建界面
打开Main.storyboard文件,在当前控制器中嵌入导航控制器,并添加标题QR Code Reader:










