From 74040349faf1633e50730128ab47b146d63cb165 Mon Sep 17 00:00:00 2001 From: phlippieb Date: Tue, 2 Jul 2019 10:38:46 +0200 Subject: [PATCH 1/2] Add support for scanning QR codes --- camera/CameraManager.swift | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/camera/CameraManager.swift b/camera/CameraManager.swift index 41022fd..4f2f69a 100644 --- a/camera/CameraManager.swift +++ b/camera/CameraManager.swift @@ -799,6 +799,54 @@ open class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate, UIGest } } + /** + The signature for a handler. + The success value is the string representation of a scanned QR code, if any. + */ + public typealias QRCodeDetectionHandler = (Result) -> Void + + /** + Start detecting QR codes. + */ + open func startQRCodeDetection(_ handler: @escaping QRCodeDetectionHandler) { + guard let captureSession = self.captureSession + else { return } + + let output = AVCaptureMetadataOutput() + + guard captureSession.canAddOutput(output) + else { return } + + self.qrCodeDetectionHandler = handler + captureSession.addOutput(output) + + // Note: The object types must be set after the output was added to the capture session. + output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) + output.metadataObjectTypes = [.qr, .ean8, .ean13, .pdf417] + } + + /** + Stop detecting QR codes. + */ + open func stopQRCodeDetection() { + self.qrCodeDetectionHandler = nil + + if let output = self.qrOutput { + self.captureSession?.removeOutput(output) + } + self.qrOutput = nil + } + + /** + The stored handler for QR codes. + */ + private var qrCodeDetectionHandler: QRCodeDetectionHandler? + + /** + The stored meta data output; used to detect QR codes. + */ + private var qrOutput: AVCaptureOutput? = nil + /** Check if the device rotation is locked */ @@ -2097,3 +2145,23 @@ extension PHPhotoLibrary { } } +extension CameraManager: AVCaptureMetadataOutputObjectsDelegate { + /** + Called when a QR code is detected. + */ + public func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { + // Check if there is a registered handler. + guard let handler = self.qrCodeDetectionHandler + else { return } + + // Get the detection result. + let stringValues = metadataObjects + .compactMap { $0 as? AVMetadataMachineReadableCodeObject } + .compactMap { $0.stringValue } + + guard let stringValue = stringValues.first + else { return } + + handler(.success(stringValue)) + } +} From c31fb645895778c1867b3261e73ff0a622e9f8e6 Mon Sep 17 00:00:00 2001 From: phlippieb Date: Tue, 2 Jul 2019 11:31:04 +0200 Subject: [PATCH 2/2] When setting metadata object types, only use supported types --- camera/CameraManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camera/CameraManager.swift b/camera/CameraManager.swift index 4f2f69a..afc698f 100644 --- a/camera/CameraManager.swift +++ b/camera/CameraManager.swift @@ -822,7 +822,7 @@ open class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate, UIGest // Note: The object types must be set after the output was added to the capture session. output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) - output.metadataObjectTypes = [.qr, .ean8, .ean13, .pdf417] + output.metadataObjectTypes = [.qr, .ean8, .ean13, .pdf417].filter { output.availableMetadataObjectTypes.contains($0) } } /**