【问题标题】:Xcode 9/Swift 4 AVCaptureMetadataOutput setMetadataObjectTypes use availableMetadataObjectTypesXcode 9/Swift 4 AVCaptureMetadataOutput setMetadataObjectTypes 使用 availableMetadataObjectTypes
【发布时间】:2018-03-06 09:50:47
【问题描述】:

似乎有很多类似于我遇到的问题:

AVmetadata changes with swift 4 xcode 9

AVCaptureMetadataOutput setMetadataObjectTypes unsupported type found

还有一个处理 AVFoundation 的 Apple 错误:

https://forums.developer.apple.com/thread/86810#259270

但这些似乎都不是我真正的答案。
我的代码在 swift 3 中运行良好,但只会在 swift 4 中出错。使用上述链接中的解决方案根本不会产生任何变化。

代码:

import UIKit
import AVFoundation

class BarCodeScanViewController: UIViewController,     AVCaptureMetadataOutputObjectsDelegate {
weak var delegate: FlowControllerDelegate?

var captureSession: AVCaptureSession = AVCaptureSession()
var previewLayer: AVCaptureVideoPreviewLayer = 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 {
        return
    }

    if (captureSession.canAddInput(videoInput)) {
        captureSession.canAddInput(videoInput)
    } else {
        failed()

        return
    }

    // let captureMetadataOutput = AVCaptureMetadataOutput()
    let metadataOutput = AVCaptureMetadataOutput()

    if captureSession.canAddOutput(metadataOutput) {
        captureSession.addOutput(metadataOutput)

        // Check status of camera permissions
        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
//            metadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.upce]
        metadataOutput.metadataObjectTypes = [.ean8, .ean13, .pdf417, .upce]
    } 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: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
    ac.addAction(UIAlertAction(title: "OK", 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) {
    if captureSession.isRunning == true {
        captureSession.stopRunning()
    }

    super.viewWillDisappear(animated)
}

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
    captureSession.stopRunning()

    if let metatdataObject = metadataObjects.first {
        guard let readableObject = metatdataObject 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
}
}

当我在 Xcode 8 和 swift 3 中构建此代码时,它工作正常。当我在 Xcode 9 swift 4 中运行它时,它会在添加媒体类型时崩溃:

metadataOutput.metadataObjectTypes = [.ean8, .ean13, .pdf417, .upce]

在这两种情况下,我都在构建一个之前没有测试版的 iOS 11 设备。

我已经尝试了“__”来查看它是否是上面提到的 Apple 错误。 如果我将这一行注释掉,代码会运行但没有捕获。

Apple 是否还引入了其他一些错误?其他人有这个问题吗?

任何帮助将不胜感激。

谢谢

【问题讨论】:

标签: ios avfoundation swift4 xcode9


【解决方案1】:

Clarity 的更多信息

Leevi Graham 是正确的,Apple 在没有适当文档的情况下更改了堆栈也是事实。这导致它看起来好像有一个错误。

Barcode on swift 4

澄清对我有帮助的 cmets:

委托回调已从:

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!)

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)

但是,我遇到的真正问题是您不再设置一长串类型来获取您的metadataObjectTypes。您现在只需为所有可用类型设置:

metadataOutput.metadataObjectTypes = 
metadataOutput.availableMetadataObjectTypes

所以...

这实际上是一个 API 问题。为此提出了几个雷达问题。但 Apple 已更改其 AVFoundation 文档以解决此问题。

【讨论】:

  • 在 iPhone 11 Pro 上的 iOS 13.0 和 13.1 中,我们遇到了必须再次显式设置 metadataObjectTypes 的问题。
  • 所以如果你想将它限制为 .qr 对象类型,你会怎么做?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多