2017-09-02 3 views
23

Ich versuche, mi App zu Swift 4 zu aktualisieren, aber der Barcode-Leser funktioniert nicht.Barcode auf Swift 4

Ich habe den Barcode-Leser-Code isoliert und funktioniert immer noch nicht. Die Kamera funktioniert, aber der Barcode wird nicht erkannt.

Der Code funktionierte gut auf schnellen 3 iOS 10.

Dies ist der vollständige Code

import AVFoundation 
import UIKit 

class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 
var captureSession: AVCaptureSession! 
var previewLayer: AVCaptureVideoPreviewLayer! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    view.backgroundColor = UIColor.black 
    captureSession = AVCaptureSession() 

    let videoCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video) 
    let videoInput: AVCaptureDeviceInput 

    do { 
     videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice!) 
    } catch { 
     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 = [AVMetadataObject.ObjectType.ean8, AVMetadataObject.ObjectType.ean13, AVMetadataObject.ObjectType.pdf417] 
    } else { 
     failed() 
     return 
    } 

    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession); 
    previewLayer.frame = view.layer.bounds; 
    previewLayer.videoGravity = AVLayerVideoGravity.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) { 
    super.viewWillDisappear(animated) 

    if (captureSession?.isRunning == true) { 
     captureSession.stopRunning(); 
    } 
} 

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

    if let metadataObject = metadataObjects.first { 
     let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject; 

     AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate)) 
     found(code: readableObject.stringValue!); 
    } 

    dismiss(animated: true) 
} 

func found(code: String) { 
    print(code) 
} 

override var prefersStatusBarHidden: Bool { 
    return true 
} 

override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 
    return .portrait 
} 
} 
Beta

Ich bin mit iOS 11 auf meinem iPhone, aktualisiert 9.

ist

Irgendeine Idee? Vielen Dank.

+2

So ist es schön zu wissen, dass dieses Problem nicht nur passiert, nachdem ich auf iOS 11 und Swift 4 für mein Projekt aktualisiert habe. Ich habe auch einen sehr einfachen QR-Code-Leser in meiner App, der ein AVCaptureMetadataOutput-Objekt und den AVCaptureMetadataOutputObjectsDelegate-Delegaten verwendet. Ich habe festgestellt, dass alles konstant und konstant läuft und nicht unterbrochen wird. Ich denke an dieser Stelle ist es an der Zeit, Apple einen Bug einzureichen (beide sollten nutzen). Das einzige, was sich änderte, waren die Namen der Eigenschaften/Funktionen in Swift 4, aber sonst nichts. Seltsam, dass wir keine Delegierten-Rückrufe erhalten. –

+1

Wenn Sie sich Ihren Code ansehen, müssen Sie eine serielle Warteschlange für Ihren AVCaptureMetadataOutputObjectsDelegate-Callback erstellen. metadataOutput.setMetadataObjectsDelegate (self, Warteschlange: DispatchQueue.main). Erstellen Sie statt der Hauptwarteschlange eine serielle Warteschlange als eine Eigenschaft in Ihrem Ansichtscontroller, und verwenden Sie sie statt der Hauptwarteschlange. –

Antwort

63

Ich habe es herausgefunden, aber Apple hat es nicht so offensichtlich gemacht. Die Callback-Funktion vom Delegaten AVCaptureMetadataOutputObjectsDelegate wurde umbenannt und die Parameternamen sind anders!

So

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

zu

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

My-View-Controller jetzt ersetzen wird Codes wie vor nach diesen QR scannen. Es hat die gleichen Parameter, aber der erste Parametername ist anders. Ändern Sie die Funktions- und Parameternamen und Build/run.

Hoffe, das hilft!

+0

Das war die Lösung! Die Funktion ist anders, danke! –

+2

Ich habe eine Verbesserungsanfrage an Apple geschickt, damit Xcode den Entwicklern einen Überblick gibt, wenn sich eine Funktion ändert. Ich habe so lange keine Lösung gefunden, bis ich zur API kam und Zeile für Zeile gelesen habe, weil mein Code nicht falsch war. Und es war nicht! Da wurde mir klar, dass der Funktionsname anders war. –

+1

Ich musste zusätzlich eine nicht-Haupt-DispatchQueue verwenden, wenn ich metadataObjectsDelegate gesetzt habe, um den Callback aufzurufen: 'output.setMetadataObjectsDelegate (self, queue: DispatchQueue.global (qos: .userInteractive))' –

5

nach dem Code ändert:

func metadataOutput(captureOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {} 

zu:

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

alles funktioniert wieder.

+0

Warum hast du mit den gleichen Informationen wie Mario geantwortet? – Leon

+0

Bestätigung der richtigen Antwort von Mario, bitte nächstes Mal einfach die richtige Antwort abstimmen. Vielen Dank! –

+0

Diese Antwort funktionierte besser für mich, da es offensichtlicher ist, dass die Funktionssignatur geändert wurde, nicht nur der Funktionsname. – mbonness