导入<AVFoundation/AVFoundation.h>和 <Photos/Photos.h>
遵守协议AVCaptureMetadataOutputObjectsDelegate,AVCaptureVideoDataOutputSampleBufferDelegate
@property (nonatomic, strong) AVCaptureSession *session;//会话 @property (nonatomic, strong) AVCaptureVideoDataOutput *videoDataOutput;//摄像输出流 @property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;//预览图层
在视图即将显示的方法里(viewDidAppear)判断用户是否开启相机权限,若开启调用下面的方法
-(void)isAgreePhoto {
// 1、创建device
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// 2、创建摄像设备输入流
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
// 3、创建元数据输出流
AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
[metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// 4、创建会话对象
_session = [[AVCaptureSession alloc] init];
// 并设置会话采集率
_session.sessionPreset = AVCaptureSessionPreset1920x1080;
// 5、添加元数据输出流到会话对象
[_session addOutput:metadataOutput];
// 创建摄像数据输出流并将其添加到会话对象上--> 用于识别光线强弱
self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
[_videoDataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
[_session addOutput:_videoDataOutput];
// 6、添加摄像设备输入流到会话对象
[_session addInput:deviceInput];
// 7、设置数据输出类型(如下设置为条形码和二维码兼容),需要将数据输出添加到会话后,才能指定元数据类型,否则会报错
metadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
// 8、实例化预览图层, 用于显示会话对象
_videoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
// 保持纵横比;填充层边界
_videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
CGFloat x = 0;
CGFloat y = 0;
CGFloat w = [UIScreen mainScreen].bounds.size.width;
CGFloat h = [UIScreen mainScreen].bounds.size.height;
_videoPreviewLayer.frame = CGRectMake(x, y, w, h);
[self.view.layer insertSublayer:_videoPreviewLayer atIndex:0];
// 9、启动会话
[_session startRunning];
} //在已经输出的代理方法中实现回调 (我使用的是block回调"scanBlock")
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { if (metadataObjects != nil && metadataObjects.count > 0) { AVMetadataMachineReadableCodeObject *obj = metadataObjects[0]; [_session stopRunning]; if (self.scanBlock) { self.scanBlock([obj stringValue]); [self.navigationController popViewControllerAnimated:YES]; } } else { NSLog(@"暂未识别出扫描的二维码"); } }