2017-09-02 45 views
23

Próbuję zaktualizować aplikację mi do wersji szybkiej 4, ale czytnik kodów kreskowych nie działa.Kod kreskowy na szybkim 4

Wyodrębniłem kod czytnika kodów kreskowych i nadal nie działa. Kamera działa, ale nie wykrywa kodu kreskowego.

Kod pracował dobrze na szybkiej 3 iOS 10.

Jest to kompletny kod

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 
} 
} 

używam iOS 11 na moim iPhone, uaktualniony do wersji beta 9.

Każdy pomysł? Dziękuję Ci.

+2

Miło jest wiedzieć, że problem ten nie dotyczy mnie po aktualizacji do systemu iOS 11 i Swift 4 w przypadku mojego projektu. Mam bardzo prostego czytnika kodów QR również w mojej aplikacji przy użyciu obiektu AVCaptureMetadataOutput i delegata AVCaptureMetadataOutputObjectsDelegate. Weryfikowałem, że wszystko jest nieprzerwanie i konsekwentnie działa i nie jest przerwane. Myślę, że w tym momencie nadszedł czas, aby zgłosić błąd do Apple (oba powinny). Jedyne, co się zmieniło, to nazwy właściwości/funkcji w Swift 4, ale nic poza tym. Dziwne, że nie otrzymujemy żadnych odwołań od delegatów. –

+1

Ponadto, patrząc na swój kod, należy utworzyć kolejkę szeregową dla wywołania zwrotnego AVCaptureMetadataOutputObjectsDelegate. metadataOutput.setMetadataObjectsDelegate (self, queue: DispatchQueue.main). Zamiast używać głównej kolejki, utwórz kolejkę szeregową jako właściwość kontrolera widoku i użyj jej zamiast głównej kolejki. –

Odpowiedz

63

Wyjaśniałem to, ale Apple nie sprawiło, że było to tak oczywiste. Funkcja oddzwaniania od delegata AVCaptureMetadataOutputObjectsDelegate została zmieniona, a nazwy parametrów są różne!

więc zastąpić

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

do

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

Mój widok kontroler jest teraz skanowanie kodów QR, jak wcześniej po tym. Ma te same parametry, ale pierwsza nazwa parametru jest inna. Zmień nazwy funkcji i parametrów oraz buduj/uruchom.

Mam nadzieję, że to pomoże!

+0

To było rozwiązanie! Funkcja jest inna, dziękuję! –

+2

Przesłałem prośbę o ulepszenie do Apple, aby Xcode dał programistom głowy, jeśli taka funkcja się zmieni. Tak długo nie znajdowałem rozwiązania, dopóki nie dotarłem do API i przeczytałem je wiersz po wierszu, ponieważ żaden sposób nie był błędny. I nie było! Wtedy zdałem sobie sprawę, że nazwa funkcji jest inna. –

+1

Podczas ustawiania metadataObjectsDelegate musiałem dodatkowo używać innego niż główny DispatchQueue, aby uzyskać wywołanie zwrotne: 'output.setMetadataObjectsDelegate (self, queue: DispatchQueue.global (qos: .userInteractive))' –

5

Po zmianie kodu z:

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

do:

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

wszystko znowu działa.

+0

Dlaczego odpowiedziałeś z tymi samymi informacjami co Mario? – Leon

+0

Potwierdzenie poprawnej odpowiedzi przez Mario, proszę następnym razem po prostu głosuj poprawną odpowiedzią. Dzięki! –

+0

Ta odpowiedź sprawdziła się lepiej, ponieważ jest bardziej oczywiste, że podpis funkcji został zmieniony, a nie tylko nazwa funkcji. – mbonness