@@ -799,6 +799,54 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate, UIGe
799799 }
800800 }
801801
802+ /**
803+ The signature for a handler.
804+ The success value is the string representation of a scanned QR code, if any.
805+ */
806+ public typealias QRCodeDetectionHandler = ( Result < String , Error > ) -> Void
807+
808+ /**
809+ Start detecting QR codes.
810+ */
811+ open func startQRCodeDetection( _ handler: @escaping QRCodeDetectionHandler ) {
812+ guard let captureSession = self . captureSession
813+ else { return }
814+
815+ let output = AVCaptureMetadataOutput ( )
816+
817+ guard captureSession. canAddOutput ( output)
818+ else { return }
819+
820+ self . qrCodeDetectionHandler = handler
821+ captureSession. addOutput ( output)
822+
823+ // Note: The object types must be set after the output was added to the capture session.
824+ output. setMetadataObjectsDelegate ( self , queue: DispatchQueue . main)
825+ output. metadataObjectTypes = [ . qr, . ean8, . ean13, . pdf417] . filter { output. availableMetadataObjectTypes. contains ( $0) }
826+ }
827+
828+ /**
829+ Stop detecting QR codes.
830+ */
831+ open func stopQRCodeDetection( ) {
832+ self . qrCodeDetectionHandler = nil
833+
834+ if let output = self . qrOutput {
835+ self . captureSession? . removeOutput ( output)
836+ }
837+ self . qrOutput = nil
838+ }
839+
840+ /**
841+ The stored handler for QR codes.
842+ */
843+ private var qrCodeDetectionHandler : QRCodeDetectionHandler ?
844+
845+ /**
846+ The stored meta data output; used to detect QR codes.
847+ */
848+ private var qrOutput : AVCaptureOutput ? = nil
849+
802850 /**
803851 Check if the device rotation is locked
804852 */
@@ -2097,3 +2145,23 @@ extension PHPhotoLibrary {
20972145 }
20982146}
20992147
2148+ extension CameraManager : AVCaptureMetadataOutputObjectsDelegate {
2149+ /**
2150+ Called when a QR code is detected.
2151+ */
2152+ public func metadataOutput( _ output: AVCaptureMetadataOutput , didOutput metadataObjects: [ AVMetadataObject ] , from connection: AVCaptureConnection ) {
2153+ // Check if there is a registered handler.
2154+ guard let handler = self . qrCodeDetectionHandler
2155+ else { return }
2156+
2157+ // Get the detection result.
2158+ let stringValues = metadataObjects
2159+ . compactMap { $0 as? AVMetadataMachineReadableCodeObject }
2160+ . compactMap { $0. stringValue }
2161+
2162+ guard let stringValue = stringValues. first
2163+ else { return }
2164+
2165+ handler ( . success( stringValue) )
2166+ }
2167+ }
0 commit comments