iPadOS 17.4部分机型AVCaptureMetadataOutput代理未触发(二维码扫描)
iPadOS 17.4下iPad 6/7代AVCaptureMetadataOutput代理未触发问题及解决方案
问题概述
在运行iPadOS 17.4的iPad 6代、7代设备上,使用AVCaptureMetadataOutput实现二维码扫描时,代理方法完全未被调用,扫描功能失效。但相同系统版本的iPad 10代、iPhone15系列、iPad8代等新机型可正常工作。
复现情况
下载苹果官方AVCam项目测试,发现其Swift版本中同样存在该问题,但项目中的人脸识别功能可正常运行。
相关代码与尝试操作
原AVCaptureMetadataOutput实现代码:
captureObject = [[AVCaptureMetadataOutput alloc]init]; objectQueue = dispatch_queue_create("VideoDataOutputQueue", NULL); [captureObject setMetadataObjectsDelegate:self queue:objectQueue];
尝试切换至主队列,仍无法触发代理方法:
// 修改队列为主队列,依旧无效 objectQueue = dispatch_get_main_queue(); [captureObject setMetadataObjectsDelegate:self queue:objectQueue];
核心问题在于以下代理方法始终未被触发:
- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection { if (metadataObjects != nil && metadataObjects.count > 0) { NSLog(@"%@", [metadataObjects objectAtIndex:0]); } }
临时解决方案
使用AVCaptureVideoDataOutputSampleBufferDelegate替代AVCaptureMetadataOutputObjectsDelegate,通过手动解析视频帧实现二维码检测:
1. 初始化AVCaptureVideoDataOutput
self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; dispatch_queue_t dispatchQueue = dispatch_queue_create("VideoDataQueue", NULL); [self.videoDataOutput setSampleBufferDelegate:self queue:dispatchQueue]; if ([_captureSession canAddOutput:self.videoDataOutput]) { [_captureSession addOutput:self.videoDataOutput]; }
2. 实现代理方法与二维码检测
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); if (imageBuffer == NULL) { return; } CIImage *ciImage = [CIImage imageWithCVImageBuffer:imageBuffer]; [self detectQRCode:ciImage]; } -(void)detectQRCode:(CIImage *)image { CIContext* context = [CIContext context]; NSDictionary* options = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh }; CIDetector* qrDetector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:context options:options]; NSArray * features = [qrDetector featuresInImage:image options:options]; if (features == nil || [features count] == 0) { return; } CIQRCodeFeature *metadataObj = [features firstObject]; NSString *qrString = metadataObj.messageString; NSLog(@"扫描到二维码内容: %@",qrString); }
官方修复更新
iOS 17.4.1版本已修复AVCaptureMetadataOutputObjectsDelegate在iPad 6/7代上的触发问题,升级系统后可恢复原方案使用。
内容的提问来源于stack exchange,提问作者jacorl
相关产品推荐
相关产品推荐

