iOS开发-五步完成二维码扫描
2016-06-23 本文已影响3404人
for_in
由于各种第三方二维码扫描组件都不支持64位,并且已经停止更新很久了,所以现在一般都使用AVFoundation
去实现二维码/条码的扫描。
基本所有app的扫一扫要跳转一个新的界面去,所以最好新建一个控制器ScanViewController
第一步
导入AVFoundation
框架和遵守协议<AVCaptureMetadataOutputObjectsDelegate>
#import <AVFoundation/AVFoundation.h>
@interface ScanViewController ()<AVCaptureMetadataOutputObjectsDelegate>
第二步
初始化捕捉设备AVCaptureDevice
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
创建输入
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"%@", [error localizedDescription]);
return;
}
创建输出
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
创建一个会话,并添加输入和输出
self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession addInput:input];
[self.captureSession addOutput:captureMetadataOutput];
设置输出数据的类型,AVMetadataObjectTypeQRCode
为二维码类型,其他类型可以到这个头文件AVMetadataObject.h
里面查看
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
第三步
创建图层,摄像头捕捉到的画面都会在这个图层显示
self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
设置图层填充方式
[self.videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
设置图层的frame
[self.videoPreviewLayer setFrame:self.view.layer.bounds];
将图层添加到预览view的图层上
[self.view.layer addSublayer:self.videoPreviewLayer];
第四步
创建一个串行队列,并设置代理
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
第五步
设置扫码范围
captureMetadataOutput.rectOfInterest = CGRectMake(0.2f, 0.2f, 0.8f, 0.8f);
开始扫码
[self.captureSession startRunning];
实现代理方法获取扫描到的数据
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
//判断是否有数据
if (metadataObjects != nil && [metadataObjects count] > 0) {
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
//判断回传的数据类型
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
self.license = [metadataObj stringValue];
[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
}
}
}