【问题标题】:I have stopped captureSession but Scanner is yet working. How to resolve this bug?我已停止 captureSession 但扫描仪仍在工作。如何解决这个错误?
【发布时间】:2017-08-18 11:05:51
【问题描述】:
func scan(){
    captureSession = AVCaptureSession()

    let videoInput: AVCaptureDeviceInput
    let videoCaptureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
    let metadataOutput = AVCaptureMetadataOutput()

    do {
        videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
    } catch {
        return
    }

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

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

        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeITF14Code, AVMetadataObjectTypeCode39Code]
    } else {
        failed()
        return
    }
    var capLayer = self.previewLayer
    capLayer = AVCaptureVideoPreviewLayer(session: captureSession);
    capLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    capLayer?.frame = self.cameraView.layer.bounds
    self.cameraView.layer.addSublayer(capLayer!)
    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, handler: nil))
    present(ac, animated: true, completion: nil)
    captureSession = nil
}
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
    captureSession.stopRunning()

    if let metadataObject: AnyObject = metadataObjects.first as AnyObject? {
        let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;
        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
        foundCode(readableObject.stringValue)
    }
    if (captureSession?.isRunning == true) {
        captureSession.stopRunning()
        captureSession = nil
    }

    dismiss(animated: true, completion: nil)
}
func foundCode(_ code: String) {
    captureSession.stopRunning()
    storeID = (UserDefaults.standard.value(forKey: DefaultsKey.storeID.rawValue) as? Int)!
    scannedCode = ("\(code)")
    if (captureSession?.isRunning == true) {
        captureSession.stopRunning()
        captureSession = nil
    }
    apiCall()
}

我的应用程序的结构:我在成功调用 API 后点击按钮触发扫描。一旦找到条形码,我就停止了捕获会话,但它会持续扫描并发送多个 api 调用。

建议如何在不触发的情况下停止相机扫描。

【问题讨论】:

    标签: ios swift xcode swift3 barcode-scanner


    【解决方案1】:

    我想在某些时候它仍然会停止,并且我们遇到了同样的问题。它的问题是捕获会话使用队列,当它设法扫描某些东西时,它仍然能够扫描几次,直到你的代码真正停止它。这就是您收到多个委托回调的原因。

    您可以在这里有 2 个选项:

    1. 在您第一次收到回调时将其设置为nil,并在您想开始时将其重新设置。(虽然我不确定它是否会起作用)
    2. 正如我们所做的...引入一个 bool 标志来过滤您的委托中不需要的回调。

    【讨论】:

    • 我已经尝试过你建议的第一个方法,它没有奏效。需要检查第二种方法。希望它运作良好
    【解决方案2】:

    我认为您应该尝试将停止扫描代码放在主队列中。

    dispatch_async(dispatch_get_main_queue(), ^{
                    // Your code here
    });
    

    这将强制您的扫描仪进入主队列并缩短您的处理时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2022-11-09
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 2012-01-25
      相关资源
      最近更新 更多