1// Copyright 2016-present 650 Industries. All rights reserved.
2
3#import <ABI47_0_0EXBarCodeScanner/ABI47_0_0EXBarCodeScannerModule.h>
4#import <ABI47_0_0EXBarCodeScanner/ABI47_0_0EXBarCodeScannerUtils.h>
5#import <ABI47_0_0EXBarCodeScanner/ABI47_0_0EXBarCodeCameraRequester.h>
6#import <ABI47_0_0ExpoModulesCore/ABI47_0_0EXImageLoaderInterface.h>
7#import <ABI47_0_0ExpoModulesCore/ABI47_0_0EXPermissionsInterface.h>
8#import <ABI47_0_0ExpoModulesCore/ABI47_0_0EXPermissionsMethodsDelegate.h>
9
10@interface ABI47_0_0EXBarCodeScannerModule ()
11
12@property (nonatomic, weak) ABI47_0_0EXModuleRegistry *moduleRegistry;
13@property (nonatomic, weak) id<ABI47_0_0EXImageLoaderInterface> imageLoader;
14@property (nonatomic, weak) id<ABI47_0_0EXPermissionsInterface> permissionsManager;
15
16@end
17
18@implementation ABI47_0_0EXBarCodeScannerModule
19
20ABI47_0_0EX_EXPORT_MODULE(ExpoBarCodeScannerModule);
21
22- (void)setModuleRegistry:(ABI47_0_0EXModuleRegistry *)moduleRegistry
23{
24  _moduleRegistry = moduleRegistry;
25  _imageLoader = [moduleRegistry getModuleImplementingProtocol:@protocol(ABI47_0_0EXImageLoaderInterface)];
26  _permissionsManager = [moduleRegistry getModuleImplementingProtocol:@protocol(ABI47_0_0EXPermissionsInterface)];
27  [ABI47_0_0EXPermissionsMethodsDelegate registerRequesters:@[[ABI47_0_0EXBareCodeCameraRequester new]] withPermissionsManager:_permissionsManager];
28}
29
30- (NSDictionary *)constantsToExport
31{
32  return @{
33           @"Type": @{
34               @"front": @(ABI47_0_0EXCameraTypeFront),
35               @"back" : @(ABI47_0_0EXCameraTypeBack),
36               },
37           @"BarCodeType": [ABI47_0_0EXBarCodeScannerUtils validBarCodeTypes],
38           };
39}
40
41ABI47_0_0EX_EXPORT_METHOD_AS(getPermissionsAsync,
42                    getPermissionsAsync:(ABI47_0_0EXPromiseResolveBlock)resolve
43                    rejecter:(ABI47_0_0EXPromiseRejectBlock)reject)
44{
45  [ABI47_0_0EXPermissionsMethodsDelegate getPermissionWithPermissionsManager:_permissionsManager
46                                                      withRequester:[ABI47_0_0EXBareCodeCameraRequester class]
47                                                            resolve:resolve
48                                                             reject:reject];
49}
50
51ABI47_0_0EX_EXPORT_METHOD_AS(requestPermissionsAsync,
52                    requestPermissionsAsync:(ABI47_0_0EXPromiseResolveBlock)resolve
53                    rejecter:(ABI47_0_0EXPromiseRejectBlock)reject)
54{
55  [ABI47_0_0EXPermissionsMethodsDelegate askForPermissionWithPermissionsManager:_permissionsManager
56                                                         withRequester:[ABI47_0_0EXBareCodeCameraRequester class]
57                                                               resolve:resolve
58                                                                reject:reject];
59}
60
61ABI47_0_0EX_EXPORT_METHOD_AS(scanFromURLAsync,
62                    scanFromURLAsync:(NSString *)url
63                    barCodeTypes:(NSArray *)barCodeTypes
64                    resolver:(ABI47_0_0EXPromiseResolveBlock)resolve
65                    rejecter:(ABI47_0_0EXPromiseRejectBlock)reject)
66{
67  // We only support QR codes, so barCodeTypes is ignored
68  NSURL *imageURL = [NSURL URLWithString:url];
69  [_imageLoader loadImageForURL:imageURL completionHandler:^(NSError *error, UIImage *loadedImage) {
70    if (error != nil) {
71      reject(@"E_IMAGE_RETRIEVAL_ERROR", @"Could not get the image", error);
72      return;
73    }
74
75    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode
76                                              context:nil
77                                              options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
78    if (detector)  {
79      NSArray *features = [detector featuresInImage:[[CIImage alloc] initWithCGImage:loadedImage.CGImage]];
80
81      NSMutableArray *result = [NSMutableArray arrayWithCapacity:1];
82      for (CIQRCodeFeature *feature in features)  {
83        [result addObject:[ABI47_0_0EXBarCodeScannerUtils ciQRCodeFeatureToDicitionary:feature barCodeType:AVMetadataObjectTypeQRCode]];
84      }
85
86      resolve(result);
87    } else {
88      reject(@"E_SCANNER_INIT_FAILED", @"Could not initialize the barcode scanner", nil);
89    }
90  }];
91}
92
93@end
94