1 import ExpoModulesCore 2 3 public final class BarCodeScannerModule: Module { definitionnull4 public func definition() -> ModuleDefinition { 5 Name("ExpoBarCodeScanner") 6 7 Constants([ 8 "Type": [ 9 "front": EXCameraType.front.rawValue, 10 "back": EXCameraType.back.rawValue 11 ], 12 "BarCodeType": EXBarCodeScannerUtils.validBarCodeTypes() 13 ]) 14 15 OnCreate { 16 let permissionsManager = self.appContext?.permissions 17 18 EXPermissionsMethodsDelegate.register( 19 [EXBareCodeCameraRequester()], 20 withPermissionsManager: permissionsManager 21 ) 22 } 23 24 AsyncFunction("getPermissionsAsync") { (promise: Promise) in 25 EXPermissionsMethodsDelegate.getPermissionWithPermissionsManager( 26 self.appContext?.permissions, 27 withRequester: EXBareCodeCameraRequester.self, 28 resolve: promise.resolver, 29 reject: promise.legacyRejecter 30 ) 31 } 32 33 AsyncFunction("requestPermissionsAsync") { (promise: Promise) in 34 EXPermissionsMethodsDelegate.askForPermission( 35 withPermissionsManager: self.appContext?.permissions, 36 withRequester: EXBareCodeCameraRequester.self, 37 resolve: promise.resolver, 38 reject: promise.legacyRejecter 39 ) 40 } 41 42 AsyncFunction("scanFromURLAsync") { (url: URL, _: [String], promise: Promise) in 43 guard let imageLoader = appContext?.imageLoader else { 44 throw ImageLoaderNotFound() 45 } 46 47 imageLoader.loadImage(for: url) { error, image in 48 if error != nil { 49 promise.reject(FailedToLoadImage()) 50 return 51 } 52 53 guard let cgImage = image?.cgImage else { 54 promise.reject(FailedToLoadImage()) 55 return 56 } 57 58 guard let detector = CIDetector( 59 ofType: CIDetectorTypeQRCode, 60 context: nil, 61 options: [CIDetectorAccuracy: CIDetectorAccuracyHigh] 62 ) else { 63 promise.reject(InitScannerFailed()) 64 return 65 } 66 67 let ciImage = CIImage(cgImage: cgImage) 68 let features = detector.features(in: ciImage) 69 promise.resolve(self.getResultFrom(features)) 70 } 71 } 72 73 View(EXBarCodeScannerView.self) { 74 Events("onBarCodeScanned") 75 76 Prop("type") { (view, type: Int) in 77 if view.presetCamera != type { 78 view.presetCamera = type 79 } 80 } 81 82 Prop("barCodeTypes") { (view, barcodeTypes: [String]) in 83 view.barCodeTypes = barcodeTypes 84 } 85 } 86 } 87 getResultFromnull88 private func getResultFrom(_ features: [CIFeature]) -> [[AnyHashable: Any]?] { 89 var result = [[AnyHashable: Any]?]() 90 91 for feature in features { 92 if let qrCodeFeature = feature as? CIQRCodeFeature { 93 let item = EXBarCodeScannerUtils.ciQRCodeFeature( 94 toDicitionary: qrCodeFeature, 95 barCodeType: AVMetadataObject.ObjectType.qr.rawValue 96 ) 97 result.append(item) 98 } 99 } 100 101 return result 102 } 103 } 104