Swift4 QR阅读器可运行但无结果,扫描时captureOutput未触发且弹窗不显示
Swift 4 QR码阅读器:captureOutput()未触发的排查与修复
嘿,我之前也碰到过类似的问题,Swift4里AVFoundation的代理坑还真不少!你的问题核心是captureOutput(_:didOutput:from:)没被触发,大概率是这几个地方没做好:
1. 代理设置错误或内存被释放
- 首先要确保你把AVCaptureMetadataOutput的delegate设为当前ViewController,别随便用
weak var(刚启动时如果代理被提前释放,就不会触发回调)。示例代码:let metadataOutput = AVCaptureMetadataOutput() metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) - 还要确认你已经把这个metadataOutput添加到AVCaptureSession中:
if session.canAddOutput(metadataOutput) { session.addOutput(metadataOutput) } else { print("无法添加Metadata输出模块") return }
2. 未正确设置识别的元数据类型
Swift4里AVFoundation用枚举替代了旧的字符串常量,如果你没明确指定要识别QR码,系统不会触发回调。一定要加上:
metadataOutput.metadataObjectTypes = [.qr]
注意:别用AVMetadataObjectTypeQRCode这种旧写法,Swift4里必须用枚举值.qr。
3. 代理方法签名完全匹配
这是最容易踩的坑!如果方法签名哪怕差一点点,系统都不会调用它。Swift4里正确的签名应该是:
func captureOutput(_ output: AVCaptureOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { // 在这里处理扫描到的QR码,比如弹出弹窗 guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject else { return } if metadataObject.type == .qr { if let qrCodeString = metadataObject.stringValue { print("扫描到QR码:\(qrCodeString)") // 弹出提示弹窗 let alert = UIAlertController(title: "扫描成功", message: qrCodeString, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) present(alert, animated: true) // 可选:暂停扫描 session.stopRunning() } } }
检查一下你的方法参数名、类型有没有写错,比如是不是把[AVMetadataObject]写成了[Any],或者参数顺序搞反了?
4. 相机权限与会话运行状态
- 确保你已经在
Info.plist里添加了NSCameraUsageDescription权限描述,否则相机可能无法正常启动,哪怕你调用了session.startRunning()。 - 确认
session.startRunning()是在主线程调用的,或者在相机权限获取成功后才执行:AVCaptureDevice.requestAccess(for: .video) { granted in if granted { DispatchQueue.main.async { self.session.startRunning() } } else { print("用户拒绝了相机权限") } }
快速排查技巧
- 在
session.startRunning()之后加print("会话已启动:\(session.isRunning)"),确认会话真的在运行。 - 在
captureOutput方法开头加print("触发了回调!"),看控制台有没有输出,就能直接判断是不是方法没被调用。
内容的提问来源于stack exchange,提问作者Eric Chong
相关产品推荐
相关产品推荐

