iPad端Swift Playgrounds添加EAN13条码扫描功能运行失败求助
EAN13条码扫描功能运行报错修复方案
1 首要语法错误修复
你代码第一行的导入语句大小写不符合Swift语法规范:
错误写法:
Import AVFoundation
正确写法(首字母小写):
import AVFoundation
这是导致你直接运行报语法错误的核心原因。
2 Swift Playgrounds运行适配
不管是iPad端还是Xcode端的Swift Playgrounds,都不能直接运行单独的UIViewController子类,需要做如下适配:
- 导入
PlaygroundSupport框架,指定当前的Live View为你的扫描控制器 - 补充相机权限声明,iOS调用相机必须提前说明用途
3 适配后的完整可运行代码
import AVFoundation import UIKit import PlaygroundSupport class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { var captureSession: AVCaptureSession! var previewLayer: AVCaptureVideoPreviewLayer! override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.black captureSession = AVCaptureSession() guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return } let videoInput: AVCaptureDeviceInput do { videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice) } catch { failed() return } if (captureSession.canAddInput(videoInput)) { captureSession.addInput(videoInput) } else { failed() return } let metadataOutput = AVCaptureMetadataOutput() if (captureSession.canAddOutput(metadataOutput)) { captureSession.addOutput(metadataOutput) metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) metadataOutput.metadataObjectTypes = [.ean8, .ean13, .pdf417] } else { failed() return } previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer.frame = view.layer.bounds previewLayer.videoGravity = .resizeAspectFill view.layer.addSublayer(previewLayer) captureSession.startRunning() } func failed() { let ac = UIAlertController(title: "扫描不支持", message: "你的设备不支持扫码功能,请使用带相机的设备", preferredStyle: .alert) ac.addAction(UIAlertAction(title: "确定", style: .default)) present(ac, animated: true) captureSession = nil } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if (captureSession?.isRunning == false) { captureSession.startRunning() } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) if (captureSession?.isRunning == true) { captureSession.stopRunning() } } func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { captureSession.stopRunning() if let metadataObject = metadataObjects.first { guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return } guard let stringValue = readableObject.stringValue else { return } AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate)) found(code: stringValue) } dismiss(animated: true) } func found(code: String) { print("扫描到的编码:\(code)") } override var prefersStatusBarHidden: Bool { return true } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait } } // 指定Playground的实时展示视图 PlaygroundPage.current.liveView = ScannerViewController() // 开启Playground持续运行模式 PlaygroundPage.current.needsIndefiniteExecution = true
4 额外注意事项
- iPad端运行时需要在Playgrounds的系统设置中允许相机权限
- 如果是嵌入到正式项目中,需要在项目的Info.plist中添加
NSCameraUsageDescription键,填写相机使用说明(比如“需要访问相机以扫描条码”) - Xcode Playground运行时需要选择真机作为运行目标,模拟器没有相机硬件,会直接进入错误提示流程
内容的提问来源于stack exchange,提问作者Kemal007023 oz
相关产品推荐
相关产品推荐

