二维码扫描
随着时间的发展,现在越来越多的app都添加了二维码扫描的功能,最近在项目中需要使用二维码扫描功能去获取商品信息,所以找网上的代码研究了一下,iOS原生API是支持扫描的,但是最关键的一点就是限制扫描区域。
二维码扫描步骤
- 创建捕捉会话
- 添加输入设备
- 添加输出数据
- 设置扫描区域(这个可以省略,如果你想全屏扫描的话)
- 设置输入元数据类型
- 添加扫描图层
- 开始扫面
注意:需要引入#import <AVFoundation/AVFoundation.h>
//会话和图层需要声明成属性,因为代理方法中需要使用
@property (nonatomic, weak) AVCaptureSession *session;
@property (nonatomic, weak) AVCaptureVideoPreviewLayer *layer;
// 1.创建捕捉会话
AVCaptureSession *session = [[AVCaptureSession alloc] init];
self.session = session;
// 2.添加输入设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
[session addInput:input];
// 3.添加输出数据
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
//设置扫描敏感区域,frame为想要扫描的敏感区域
output.rectOfInterest =[self rectOfInterestByScanViewRect:frame];
// 3.1.设置输入元数据的类型(类型是二维码数据和条形码)
output.metadataObjectTypes =@[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode];
// 4.添加扫描图层
AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
layer.frame = self.view.bounds;
[self.view.layer addSublayer:layer];
self.layer = layer;
// 5.开始扫描
[session startRunning];
- (CGRect)rectOfInterestByScanViewRect:(CGRect)rect {
CGFloat width = CGRectGetWidth(self.view.frame);
CGFloat height = CGRectGetHeight(self.view.frame);
// 注意这里的x,y, w,h计算方法
CGFloat x = rect.origin.y / height;
CGFloat y = rect.origin.x / width;
CGFloat w = rect.size.height / height;
CGFloat h = rect.size.width / width;
return CGRectMake(x, y, w, h);
}
控制器遵守协议AVCaptureMetadataOutputObjectsDelegate
,实现代理方法进行监听扫描到的数据
// 当扫描到数据时就会执行该方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *object = [metadataObjects lastObject];
NSLog(@"%@", object.stringValue);
// 停止扫描
[self.session stopRunning];
// 将预览图层移除
[self.layer removeFromSuperlayer];
} else {
NSLog(@"没有扫描到数据");
}
}