anyline-ocr-react-native-module 42.2.0 → 43.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/android/build.gradle +7 -3
  2. package/android/src/main/AndroidManifest.xml +9 -8
  3. package/android/src/main/assets/cow_tag_scanner.ale +46 -0
  4. package/android/src/main/java/com/anyline/reactnative/AnylinePackage.java +1 -2
  5. package/android/src/main/java/com/anyline/reactnative/AnylineSDKPlugin.java +25 -71
  6. package/android/src/main/java/com/anyline/reactnative/RotateButtonConfig.java +12 -2
  7. package/android/src/main/java/com/anyline/reactnative/ScanActivity.java +206 -0
  8. package/android/src/main/res/drawable/rotate_screen_background.xml +18 -0
  9. package/android/src/main/res/drawable/rotate_screen_white.png +0 -0
  10. package/android/src/main/res/layout/activity_scan.xml +27 -0
  11. package/android/src/main/res/values/anyline_sdk_plugin_strings.xml +2 -28
  12. package/ios/ALJsonUIConfiguration.h +29 -36
  13. package/ios/ALJsonUIConfiguration.m +136 -76
  14. package/ios/ALNFCScanViewController.h +3 -16
  15. package/ios/ALNFCScanViewController.m +361 -232
  16. package/ios/ALPluginHelper.h +19 -62
  17. package/ios/ALPluginHelper.m +208 -529
  18. package/ios/ALPluginScanViewController.h +5 -32
  19. package/ios/ALPluginScanViewController.m +339 -287
  20. package/ios/AnylineReact.podspec +4 -3
  21. package/ios/AnylineSDKPlugin.m +39 -82
  22. package/package.json +8 -8
  23. package/android/.gradle/6.7/executionHistory/executionHistory.lock +0 -0
  24. package/android/.gradle/6.7/fileChanges/last-build.bin +0 -0
  25. package/android/.gradle/6.7/fileHashes/fileHashes.bin +0 -0
  26. package/android/.gradle/6.7/fileHashes/fileHashes.lock +0 -0
  27. package/android/.gradle/6.7/gc.properties +0 -0
  28. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  29. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  30. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  31. package/android/.gradle/checksums/checksums.lock +0 -0
  32. package/android/.gradle/checksums/md5-checksums.bin +0 -0
  33. package/android/.gradle/checksums/sha1-checksums.bin +0 -0
  34. package/android/.gradle/configuration-cache/gc.properties +0 -0
  35. package/android/.gradle/vcs-1/gc.properties +0 -0
  36. package/android/.idea/compiler.xml +0 -6
  37. package/android/.idea/gradle.xml +0 -18
  38. package/android/.idea/jarRepositories.xml +0 -35
  39. package/android/.idea/misc.xml +0 -10
  40. package/android/.idea/vcs.xml +0 -6
  41. package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
  42. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  43. package/android/local.properties +0 -8
  44. package/android/src/main/java/com/anyline/reactnative/Anyline4Activity.java +0 -621
  45. package/android/src/main/java/com/anyline/reactnative/AnylineBaseActivity.java +0 -267
  46. package/android/src/main/java/com/anyline/reactnative/AnylinePluginHelper.java +0 -324
  47. package/android/src/main/java/com/anyline/reactnative/AnylineUIConfig.java +0 -88
  48. package/android/src/main/java/com/anyline/reactnative/Document4Activity.java +0 -595
  49. package/android/src/main/res/layout/activity_scan_document.xml +0 -63
  50. package/android/src/main/res/layout/activity_scan_scanview.xml +0 -52
  51. package/android/src/main/res/values/com_crashlytics_export_strings.xml +0 -10
@@ -1,85 +1,73 @@
1
- //
2
- // ALPluginHelper.m
3
- // Anyline React-Native Example
4
- //
5
- // Created by Daniel Albertini on 30.10.18.
6
- //
7
-
8
1
  #import "ALPluginHelper.h"
2
+ #import "ALNFCScanViewController.h" // because NFC-specific code is there
3
+ #import <Anyline/Anyline.h>
4
+ #import <objc/runtime.h>
9
5
 
10
- @implementation ALPluginHelper
11
-
12
- #pragma mark - String convertions
6
+ // Predefined domain for errors from most AppKit and Foundation APIs.
7
+ NSErrorDomain const ALFlutterDomain = @"ALFlutterDomain";
13
8
 
14
- + (NSString *)barcodeFormatFromString:(NSString *)barcodeFormat {
15
- return (barcodeFormat == nil && barcodeFormat.length == 0) ? @"unkown" : barcodeFormat;
16
- }
9
+ @implementation ALPluginHelper
17
10
 
18
- + (ALScanMode)scanModeFromString:(NSString *)scanMode {
19
- NSDictionary<NSString *, NSNumber *> *scanModes = [ALPluginHelper scanModesDict];
20
-
21
- return [scanModes[scanMode] integerValue];
22
- }
11
+ #pragma mark - Launch Anyline
23
12
 
24
- + (NSString *)stringFromScanMode:(ALScanMode)scanMode {
25
- NSDictionary<NSString *, NSNumber *> *scanModes = [ALPluginHelper scanModesDict];
13
+ + (void)startScan:(NSDictionary *)config finished:(ALPluginCallback)callback {
26
14
 
27
- return [scanModes allKeysForObject:@(scanMode)][0];
28
- }
29
-
30
- + (NSString *)stringForOutline:(ALSquare *)square {
31
- return [NSString stringWithFormat:@"outline : { upLeft : { x : %f, y : %f }, upRight : { x : %f, y : %f }, downRight : { x : %f, y : %f }, downLeft : { x : %f, y : %f } }",square.upLeft.x,square.upLeft.y,square.upRight.x,square.upRight.y,square.downRight.x,square.downRight.y,square.downLeft.x,square.downLeft.y];
32
- }
33
-
34
- + (NSDictionary<NSString *, NSNumber *> *)scanModesDict {
35
- static NSDictionary<NSString *, NSNumber *> * scanModes = nil;
15
+ NSDictionary *pluginConf = config;
36
16
 
37
- static dispatch_once_t onceToken;
38
- dispatch_once(&onceToken, ^{
39
- scanModes = @{
40
- @"AUTO_ANALOG_DIGITAL_METER" : @(ALAutoAnalogDigitalMeter),
41
- @"DIAL_METER" : @(ALDialMeter),
42
- @"ANALOG_METER" : @(ALAnalogMeter),
43
- @"BARCODE" : @(ALMeterBarcode),
44
- @"SERIAL_NUMBER" : @(ALSerialNumber),
45
- @"DOT_MATRIX_METER" : @(ALDotMatrixMeter),
46
- @"DIGITAL_METER" : @(ALDigitalMeter),
47
- @"HEAT_METER_4" : @(ALHeatMeter4),
48
- @"HEAT_METER_5" : @(ALHeatMeter5),
49
- @"HEAT_METER_6" : @(ALHeatMeter6),
50
- };
51
- });
17
+ NSString *licenseKey = [config objectForKey:@"licenseKey"];
52
18
 
53
- return scanModes;
54
- }
55
-
56
- + (NSString *)barcodeFormatForNativeString:(NSString *)barcodeType {
19
+ [[UIApplication sharedApplication] keyWindow].rootViewController.modalPresentationStyle = UIModalPresentationFullScreen;
57
20
 
58
- static NSDictionary<NSString *, NSString *> * barcodeFormats = nil;
21
+ NSDictionary *optionsDict = [config objectForKey:@"options"];
22
+ ALJSONUIConfiguration *jsonUIConf = [[ALJSONUIConfiguration alloc] initWithDictionary:optionsDict];
59
23
 
60
- static dispatch_once_t onceToken;
61
- dispatch_once(&onceToken, ^{
62
- #pragma clang diagnostic push
63
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
64
- barcodeFormats = @{
65
- @"AVMetadataObjectTypeUPCECode" : kCodeTypeUPCE,
66
- @"AVMetadataObjectTypeCode39Code" : kCodeTypeCode39,
67
- @"AVMetadataObjectTypeCode39Mod43Code" : kCodeTypeCode39,
68
- @"AVMetadataObjectTypeEAN13Code" : kCodeTypeEAN13,
69
- @"AVMetadataObjectTypeEAN8Code" : kCodeTypeEAN8,
70
- @"AVMetadataObjectTypeCode93Code" : kCodeTypeCode93,
71
- @"AVMetadataObjectTypeCode128Code" : kCodeTypeCode128,
72
- @"AVMetadataObjectTypePDF417Code" : kCodeTypePDF417,
73
- @"AVMetadataObjectTypeQRCode" : kCodeTypeQR,
74
- @"AVMetadataObjectTypeAztecCode" : kCodeTypeAztec,
75
- @"AVMetadataObjectTypeInterleaved2of5Code" : kCodeTypeITF,
76
- @"AVMetadataObjectTypeITF14Code" : kCodeTypeITF,
77
- @"AVMetadataObjectTypeDataMatrixCode" : kCodeTypeDataMatrix,
78
- };
79
- #pragma clang diagnostic pop
80
- });
24
+ BOOL isNFC = [optionsDict[@"enableNFCWithMRZ"] boolValue];
81
25
 
82
- return barcodeFormats[barcodeType];
26
+ if (isNFC) {
27
+ if (@available(iOS 13.0, *)) {
28
+
29
+ if (![ALNFCDetector readingAvailable]) {
30
+ callback(nil, @"NFC passport reading is not supported on this device or app.");
31
+ return;
32
+ }
33
+
34
+ ALNFCScanViewController *nfcScanViewController = [[ALNFCScanViewController alloc] initWithLicensekey:licenseKey
35
+ configuration:pluginConf
36
+ uiConfig:jsonUIConf
37
+ finished:callback];
38
+ if (nfcScanViewController != nil) {
39
+ [nfcScanViewController setModalPresentationStyle:UIModalPresentationFullScreen];
40
+ [[[UIApplication sharedApplication] keyWindow].rootViewController presentViewController:nfcScanViewController
41
+ animated:YES
42
+ completion:nil];
43
+ }
44
+ } else {
45
+ callback(nil, @"NFC passport reading is only supported on iOS 13 and later.");
46
+ return;
47
+ }
48
+ } else {
49
+ ALPluginScanViewController *pluginScanViewController = [[ALPluginScanViewController alloc] initWithLicensekey:licenseKey
50
+ configuration:pluginConf
51
+ uiConfiguration:jsonUIConf
52
+ finished:callback];
53
+
54
+ // TODO: should remove these extras
55
+ if ([pluginConf valueForKey:@"quality"]){
56
+ pluginScanViewController.quality = [[pluginConf valueForKey:@"quality"] integerValue];
57
+ }
58
+
59
+ if ([pluginConf valueForKey:@"cropAndTransformErrorMessage"]) {
60
+ NSString *str = [pluginConf objectForKey:@"cropAndTransformErrorMessage"];
61
+ pluginScanViewController.cropAndTransformErrorMessage = str;
62
+ }
63
+
64
+ if (pluginScanViewController) {
65
+ [pluginScanViewController setModalPresentationStyle:UIModalPresentationFullScreen];
66
+ [[[UIApplication sharedApplication] keyWindow].rootViewController presentViewController:pluginScanViewController
67
+ animated:YES
68
+ completion:nil];
69
+ }
70
+ }
83
71
  }
84
72
 
85
73
  #pragma mark - Filesystem handling
@@ -89,30 +77,30 @@
89
77
  }
90
78
 
91
79
  + (NSString *)saveImageToFileSystem:(UIImage *)image compressionQuality:(CGFloat)compressionQuality {
92
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
93
- NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
94
-
95
-
80
+ NSString *basePath = [self applicationCachePath];
96
81
  NSData *binaryImageData = UIImageJPEGRepresentation(image, compressionQuality);
97
82
  NSString *uuid = [NSUUID UUID].UUIDString;
98
83
  NSString *imagePath = [NSString stringWithFormat:@"%@.jpg",uuid];
99
-
100
84
  NSString *fullPath = [basePath stringByAppendingPathComponent:imagePath];
101
85
  [binaryImageData writeToFile:fullPath atomically:YES];
102
-
103
86
  return fullPath;
104
87
  }
105
88
 
89
+ + (NSString *)applicationCachePath {
90
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
91
+ return ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
92
+ }
93
+
106
94
  #pragma mark - UI helpers
107
95
 
108
96
  + (UILabel *)createLabelForView:(UIView *)view {
109
97
 
110
98
  UILabel *scannedLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, view.frame.size.width, 44)];
111
- scannedLabel.center = CGPointMake(view.center.x, view.center.y+166);
112
-
99
+ scannedLabel.center = CGPointMake(view.center.x, view.center.y + 166);
113
100
  scannedLabel.alpha = 0.0;
114
- scannedLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:33];
101
+ scannedLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:32];
115
102
  scannedLabel.textColor = [UIColor whiteColor];
103
+ scannedLabel.numberOfLines = 0;
116
104
  scannedLabel.textAlignment = NSTextAlignmentCenter;
117
105
 
118
106
  [view addSubview:scannedLabel];
@@ -121,16 +109,28 @@
121
109
  }
122
110
 
123
111
  + (UISegmentedControl *)createSegmentForViewController:(UIViewController *)viewController
124
- config:(ALJsonUIConfiguration *)config
125
- scanMode:(ALScanMode)scanMode {
112
+ config:(ALJSONUIConfiguration *)config
113
+ initialScanMode:(NSString *)initialScanMode {
126
114
  UISegmentedControl *segment = [[UISegmentedControl alloc] initWithItems:config.segmentTitles];
127
-
128
- segment.tintColor = config.segmentTintColor;
115
+
116
+ // This doesn't appear to be changing the color
117
+ // segment.tintColor = ...
118
+
119
+ segment.backgroundColor = [UIColor colorWithWhite:1 alpha:0.6];
120
+ if (@available(iOS 13.0, *)) {
121
+ segment.selectedSegmentTintColor = config.segmentTintColor;
122
+ }
123
+
129
124
  segment.hidden = YES;
130
125
 
131
- NSInteger index = [config.segmentModes indexOfObject:[ALPluginHelper stringFromScanMode:scanMode]];
126
+ NSUInteger index = [config.segmentModes indexOfObject:initialScanMode];
127
+ if (index == NSNotFound) {
128
+ return nil;
129
+ }
130
+
132
131
  [segment setSelectedSegmentIndex:index];
133
132
 
133
+ // has a warning here but is okay as long as the target implements this selector.
134
134
  [segment addTarget:viewController action:@selector(segmentChange:) forControlEvents:UIControlEventValueChanged];
135
135
 
136
136
  [viewController.view addSubview:segment];
@@ -139,13 +139,16 @@
139
139
  }
140
140
 
141
141
  + (UIButton *)createButtonForViewController:(UIViewController *)viewController
142
- config:(ALJsonUIConfiguration *)config {
142
+ config:(ALJSONUIConfiguration *)config {
143
143
 
144
144
  UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
145
- [doneButton setTitle:config.buttonDoneTitle
146
- forState:UIControlStateNormal];
145
+ [doneButton setTitle:config.buttonDoneTitle forState:UIControlStateNormal];
146
+
147
+ // NOTE: there'll be a warning here from Xcode but just have to make sure
148
+ // doneButtonPressed: is a valid selector in the target
149
+ [doneButton addTarget:viewController action:@selector(doneButtonPressed:)
150
+ forControlEvents:UIControlEventTouchUpInside];
147
151
 
148
- [doneButton addTarget:viewController action:@selector(doneButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
149
152
  [viewController.view addSubview:doneButton];
150
153
 
151
154
  [ALPluginHelper updateButtonPosition:doneButton
@@ -161,35 +164,31 @@
161
164
  roundedView.textLabel.text = @"";
162
165
  roundedView.alpha = 0;
163
166
  [viewController.view addSubview:roundedView];
164
-
165
167
  return roundedView;
166
168
  }
167
169
 
168
- + (void)updateButtonPosition:(UIButton *)button
169
- withConfiguration:(ALJsonUIConfiguration *)conf
170
+ + (void)updateButtonPosition:(UIButton *)button withConfiguration:(ALJSONUIConfiguration *)config
170
171
  onView:(UIView *)view {
171
172
 
172
- button.titleLabel.font = [UIFont fontWithName:conf.buttonDoneFontName size:conf.buttonDoneFontSize];
173
- [button setTitleColor:conf.buttonDoneTextColor forState:UIControlStateNormal];
174
- [button setTitleColor:conf.buttonDoneTextColorHighlighted forState:UIControlStateHighlighted];
173
+ button.titleLabel.font = [UIFont fontWithName:config.buttonDoneFontName size:config.buttonDoneFontSize];
174
+ [button setTitleColor:config.buttonDoneTextColor forState:UIControlStateNormal];
175
+ [button setTitleColor:config.buttonDoneTextColorHighlighted forState:UIControlStateHighlighted];
176
+ button.contentEdgeInsets = UIEdgeInsetsMake(6, 10, 6, 10);
175
177
 
176
- button.backgroundColor = conf.buttonDoneBackgroundColor;
178
+
179
+ button.backgroundColor = config.buttonDoneBackgroundColor;
177
180
  button.translatesAutoresizingMaskIntoConstraints = NO;
178
- button.layer.cornerRadius = conf.buttonDoneCornerRadius;
179
181
 
180
- switch (conf.buttonType) {
181
- case ALButtonTypeFullWidth:
182
- // Width constraint
183
- [view addConstraint:[NSLayoutConstraint constraintWithItem:button
184
- attribute:NSLayoutAttributeWidth
185
- relatedBy:NSLayoutRelationEqual
186
- toItem:view
187
- attribute:NSLayoutAttributeWidth
188
- multiplier:1.0
189
- constant:0]];
182
+ // corner radius is overridden to 0 when "full-width" type is used
183
+ button.layer.cornerRadius = config.buttonDoneCornerRadius;
184
+
185
+ switch (config.buttonType) {
186
+ case ALButtonTypeFullWidth: // "FULLWIDTH"
187
+ [view addConstraint:[button.leftAnchor constraintEqualToAnchor:view.leftAnchor constant:0]];
188
+ [view addConstraint:[button.rightAnchor constraintEqualToAnchor:view.rightAnchor constant:0]];
189
+ button.layer.cornerRadius = 0;
190
190
  break;
191
-
192
- case ALButtonTypeRect:
191
+ case ALButtonTypeRect: // "RECT"
193
192
  [button sizeToFit];
194
193
  break;
195
194
 
@@ -197,7 +196,7 @@
197
196
  break;
198
197
  }
199
198
 
200
- switch (conf.buttonDoneXAlignment) {
199
+ switch (config.buttonDoneXAlignment) {
201
200
  case ALButtonXAlignmentCenter:
202
201
  [view addConstraint:[NSLayoutConstraint constraintWithItem:button
203
202
  attribute:NSLayoutAttributeCenterX
@@ -205,7 +204,7 @@
205
204
  toItem:view
206
205
  attribute:NSLayoutAttributeCenterX
207
206
  multiplier:1.0
208
- constant:conf.buttonDoneXPositionOffset]];
207
+ constant:config.buttonDoneXPositionOffset]];
209
208
  break;
210
209
  case ALButtonXAlignmentLeft:
211
210
  [view addConstraint:[NSLayoutConstraint constraintWithItem:button
@@ -214,7 +213,7 @@
214
213
  toItem:view
215
214
  attribute:NSLayoutAttributeLeft
216
215
  multiplier:1.0
217
- constant:MAX(conf.buttonDoneXPositionOffset,0)]];
216
+ constant:MAX(config.buttonDoneXPositionOffset, 0)]];
218
217
  break;
219
218
  case ALButtonXAlignmentRight:
220
219
  [view addConstraint:[NSLayoutConstraint constraintWithItem:button
@@ -223,14 +222,14 @@
223
222
  toItem:view
224
223
  attribute:NSLayoutAttributeRight
225
224
  multiplier:1.0
226
- constant:MIN(conf.buttonDoneXPositionOffset,0)]];
225
+ constant:MIN(config.buttonDoneXPositionOffset, 0)]];
227
226
  break;
228
227
 
229
228
  default:
230
229
  break;
231
230
  }
232
231
 
233
- switch (conf.buttonDoneYAlignment) {
232
+ switch (config.buttonDoneYAlignment) {
234
233
  case ALButtonYAlignmentTop:
235
234
  // Align Top
236
235
  [view addConstraint:[NSLayoutConstraint constraintWithItem:button
@@ -239,7 +238,7 @@
239
238
  toItem:view
240
239
  attribute:NSLayoutAttributeTop
241
240
  multiplier:1.0
242
- constant:MAX(conf.buttonDoneYPositionOffset,0)]];
241
+ constant:MAX(config.buttonDoneYPositionOffset, 0)]];
243
242
  break;
244
243
  case ALButtonYAlignmentBottom:
245
244
  // Align Bottom
@@ -249,18 +248,14 @@
249
248
  toItem:view
250
249
  attribute:NSLayoutAttributeBottom
251
250
  multiplier:1.0
252
- constant:MIN(conf.buttonDoneYPositionOffset,0)]];
251
+ constant:MIN(config.buttonDoneYPositionOffset, 0)]];
253
252
 
254
253
  break;
255
254
  case ALButtonYAlignmentCenter:
256
255
  // Center vertically
257
- [view addConstraint:[NSLayoutConstraint constraintWithItem:button
258
- attribute:NSLayoutAttributeCenterY
259
- relatedBy:NSLayoutRelationEqual
260
- toItem:view
261
- attribute:NSLayoutAttributeCenterY
262
- multiplier:1.0
263
- constant:conf.buttonDoneYPositionOffset]];
256
+ [view addConstraint:
257
+ [button.centerYAnchor constraintEqualToAnchor:view.centerYAnchor constant:config.buttonDoneYPositionOffset]
258
+ ];
264
259
  break;
265
260
 
266
261
  default:
@@ -268,431 +263,115 @@
268
263
  }
269
264
  }
270
265
 
271
- #pragma mark - Create Result Dictionaries
272
-
273
- + (NSDictionary *)dictionaryForBarcodeResults:(NSMutableArray<NSDictionary *> *)detectedBarcodes
274
- barcodeType:(NSString *)barcodeType
275
- scanResult:(NSString *)scanResult {
276
- for (NSMutableDictionary<NSString *, NSString *> *barcode in detectedBarcodes) {
277
- if ([[barcode objectForKey:@"value"] isEqualToString:scanResult]) {
278
- return nil;
279
- }
280
- }
281
-
282
- NSMutableDictionary *barcode = [NSMutableDictionary dictionaryWithCapacity:2];
283
-
284
- barcode[@"value"] = scanResult;
285
- barcode[@"format"] = [ALPluginHelper barcodeFormatForNativeString:barcodeType];
286
-
287
- return barcode;
288
- }
289
-
290
- + (NSDictionary *)dictionaryForMeterResult:(ALMeterResult *)scanResult
291
- detectedBarcodes:(NSMutableArray<NSDictionary *> *)detectedBarcodes
292
- outline:(ALSquare *)outline
293
- quality:(NSInteger)quality {
294
- CGFloat dividedCompRate = (CGFloat)quality/100;
295
-
296
- NSMutableDictionary *dictResult = [NSMutableDictionary dictionaryWithCapacity:4];
297
-
298
- switch (scanResult.scanMode) {
299
- case ALDigitalMeter:
300
- [dictResult setObject:@"Digital Meter" forKey:@"meterType"];
301
- break;
302
- case ALDialMeter:
303
- [dictResult setObject:@"Dial Meter" forKey:@"meterType"];
304
- break;
305
- case ALHeatMeter4:
306
- case ALHeatMeter5:
307
- case ALHeatMeter6:
308
- [dictResult setObject:@"Heat Meter" forKey:@"meterType"];
309
- break;
310
- case ALSerialNumber:
311
- [dictResult setObject:@"Serial Number" forKey:@"meterType"];
312
- break;
313
- default:
314
- [dictResult setObject:@"Electric Meter" forKey:@"meterType"];
315
- break;
316
- }
317
-
318
- [dictResult setObject:[ALPluginHelper stringFromScanMode:scanResult.scanMode] forKey:@"scanMode"];
319
-
320
- [dictResult setObject:scanResult.result forKey:@"reading"];
321
-
322
- NSString *imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.image compressionQuality:dividedCompRate];
323
-
324
- [dictResult setValue:imagePath forKey:@"imagePath"];
325
-
326
- NSString *fullImagePath = [ALPluginHelper saveImageToFileSystem:scanResult.fullImage compressionQuality:dividedCompRate];
327
-
328
- [dictResult setValue:fullImagePath forKey:@"fullImagePath"];
329
-
330
- if (detectedBarcodes && detectedBarcodes.count != 0) {
331
- [dictResult setObject:detectedBarcodes forKey:@"detectedBarcodes"];
332
- }
333
-
334
- [dictResult setValue:@(scanResult.confidence) forKey:@"confidence"];
335
- [dictResult setValue:[ALPluginHelper stringForOutline:outline] forKey:@"outline"];
336
-
337
- return dictResult;
266
+ #pragma mark - Date Parsing Utils
267
+ //
268
+ //+ (NSString *)stringForDate:(NSDate *)date {
269
+ // if (!date) {
270
+ // return nil;
271
+ // }
272
+ //
273
+ // NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
274
+ // [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC+0:00"]];
275
+ // [dateFormatter setDateFormat:@"EEE MMM d hh:mm:ss ZZZZ yyyy"];
276
+ //
277
+ // //Date will be formatted to string - e.g.: "Fri Jan 11 12:00:00 GMT+0:00 1980"
278
+ // NSString *dateString = [dateFormatter stringFromDate:date];
279
+ //
280
+ // return dateString;
281
+ //}
282
+
283
+ // MARK: Utilities
284
+
285
+ + (void)showErrorAlertWithTitle:(NSString *)title
286
+ message:(NSString *)message
287
+ presentingViewController:(UIViewController *)presentingViewController {
288
+
289
+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
290
+ message:message
291
+ preferredStyle:UIAlertControllerStyleAlert];
292
+ UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
293
+ [alertController addAction:dismissAction];
294
+ [presentingViewController presentViewController:alertController animated:YES completion:nil];
338
295
  }
339
296
 
340
- + (NSDictionary *)dictionaryForIDResult:(ALIDResult *)scanResult
341
- detectedBarcodes:(NSMutableArray<NSDictionary *> *)detectedBarcodes
342
- outline:(ALSquare *)outline
343
- quality:(NSInteger)quality {
344
- CGFloat dividedCompRate = (CGFloat)quality/100;
345
-
346
- NSMutableDictionary *dictResult = [[NSMutableDictionary alloc] init];
347
-
348
- NSString *imagePath = [self saveImageToFileSystem:scanResult.image compressionQuality:dividedCompRate];
349
-
350
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
351
- [formatter setDateFormat:@"yyyy.MM.dd"];
352
-
353
- if ([scanResult.result isKindOfClass:[ALUniversalIDIdentification class]]) {
354
- ALUniversalIDIdentification *identification = (ALUniversalIDIdentification *)scanResult.result;
355
-
356
- [[identification fieldNames] enumerateObjectsUsingBlock:^(NSString *fieldName, NSUInteger idx, BOOL *stop) {
357
- [dictResult setValue:[identification valueForField:fieldName] forKey:fieldName];
358
- }];
359
- }
360
-
361
- if ([scanResult.result isKindOfClass:[ALMRZIdentification class]]) {
362
- ALMRZIdentification *mrzIdentification = (ALMRZIdentification *)scanResult.result;
363
- NSMutableArray<NSString *> *keys=[@[
364
- @"surname",
365
- @"givenNames",
366
- @"dateOfBirth",
367
- @"dateOfExpiry",
368
- @"documentNumber",
369
- @"documentType",
370
- @"issuingCountryCode",
371
- @"nationalityCountryCode",
372
- @"sex",
373
- @"personalNumber",
374
- @"optionalData",
375
- @"mrzString",
376
- @"checkDigitDateOfExpiry",
377
- @"checkDigitDocumentNumber",
378
- @"checkDigitDateOfBirth",
379
- @"checkDigitFinal",
380
- @"checkDigitPersonalNumber",
381
- @"allCheckDigitsValid"
382
- ] mutableCopy];
383
- dictResult = [[scanResult.result dictionaryWithValuesForKeys:keys] mutableCopy];
384
- //there's no confidence for allCheckDigitsValid
385
- [keys removeObject:@"allCheckDigitsValid"];
386
- NSMutableDictionary *confidences=[[[scanResult.result fieldConfidences]
387
- dictionaryWithValuesForKeys:keys] mutableCopy];
388
-
389
- //VIZ Fields
390
- if ([mrzIdentification vizGivenNames] && [mrzIdentification vizGivenNames].length > 0) {
391
- [dictResult setValue:mrzIdentification.vizGivenNames forKey:@"vizGivenNames"];
392
- }
393
- [confidences setValue:@(mrzIdentification.fieldConfidences.vizGivenNames) forKey:@"vizGivenNames"];
394
-
395
- if ([mrzIdentification vizSurname] && [mrzIdentification vizSurname].length > 0) {
396
- [dictResult setValue:mrzIdentification.vizSurname forKey:@"vizSurname"];
397
- }
398
- [confidences setValue:@(mrzIdentification.fieldConfidences.vizSurname) forKey:@"vizSurname"];
399
-
400
- if ([mrzIdentification vizAddress] && [mrzIdentification vizAddress].length > 0) {
401
- [dictResult setValue:mrzIdentification.vizAddress forKey:@"vizAddress"];
402
- }
403
- [confidences setValue:@(mrzIdentification.fieldConfidences.vizAddress) forKey:@"vizAddress"];
404
-
405
- if ([mrzIdentification vizDateOfBirth] && [mrzIdentification vizDateOfBirth].length > 0) {
406
- [dictResult setValue:mrzIdentification.vizDateOfBirth forKey:@"vizDateOfBirth"];
407
- [dictResult setValue:[ALPluginHelper stringForDate:mrzIdentification.vizDateOfBirthObject] forKey:@"vizDateOfBirthObject"];
408
- }
409
- [confidences setValue:@(mrzIdentification.fieldConfidences.vizDateOfBirth) forKey:@"vizDateOfBirth"];
410
-
411
- if ([mrzIdentification vizDateOfExpiry] && [mrzIdentification vizDateOfExpiry].length > 0) {
412
- [dictResult setValue:mrzIdentification.vizDateOfExpiry forKey:@"vizDateOfExpiry"];
413
- [dictResult setValue:[ALPluginHelper stringForDate:mrzIdentification.vizDateOfExpiryObject] forKey:@"vizDateOfExpiryObject"];
414
- }
415
- [confidences setValue:@(mrzIdentification.fieldConfidences.vizDateOfExpiry) forKey:@"vizDateOfExpiry"];
416
-
417
- if ([mrzIdentification vizDateOfIssue] && [mrzIdentification vizDateOfIssue].length > 0) {
418
- [dictResult setValue:mrzIdentification.vizDateOfIssue forKey:@"vizDateOfIssue"];
419
- [dictResult setValue:[ALPluginHelper stringForDate:mrzIdentification.vizDateOfIssueObject] forKey:@"vizDateOfIssueObject"];
420
- }
421
- [confidences setValue:@(mrzIdentification.fieldConfidences.vizDateOfIssue) forKey:@"vizDateOfIssue"];
422
-
423
- [dictResult setValue:[ALPluginHelper stringForDate:[scanResult.result dayOfBirthDateObject]] forKey:@"dateOfBirthObject"];
424
- [dictResult setValue:[ALPluginHelper stringForDate:[scanResult.result dateOfExpiryObject]] forKey:@"dateOfExpiryObject"];
425
- [dictResult setValue:confidences forKey:@"fieldConfidences"];
297
+ + (BOOL)showErrorAlertIfNeeded:(NSError *)error pluginCallback:(ALPluginCallback)callback {
298
+ if (!error) {
299
+ return NO;
426
300
  }
427
-
428
- [dictResult setValue:imagePath forKey:@"imagePath"];
429
-
430
- NSString *fullImagePath = [ALPluginHelper saveImageToFileSystem:scanResult.fullImage compressionQuality:dividedCompRate];
431
- [dictResult setValue:fullImagePath forKey:@"fullImagePath"];
432
-
433
- [dictResult setValue:@(scanResult.confidence) forKey:@"confidence"];
434
- [dictResult setValue:[self stringForOutline:outline] forKey:@"outline"];
435
-
436
- return dictResult;
437
- }
438
301
 
302
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Could not start scanning"
303
+ message:error.localizedDescription
304
+ preferredStyle:UIAlertControllerStyleAlert];
439
305
 
440
- + (NSDictionary *)dictionaryForNFCResult:(ALNFCResult *)scanResult
441
- quality:(NSInteger)quality API_AVAILABLE(ios(13)) {
442
- CGFloat dividedCompRate = (CGFloat)quality/100;
443
-
444
- NSMutableDictionary *dictResult = [[NSMutableDictionary alloc] init];
445
-
446
-
447
- //DataGroup1
448
- NSMutableDictionary *dictResultDataGroup1 = [[NSMutableDictionary alloc] init];
449
-
450
- [dictResultDataGroup1 setValue:[ALPluginHelper stringForDate:scanResult.dataGroup1.dateOfBirth] forKey:@"dateOfBirth"];
451
- [dictResultDataGroup1 setValue:[ALPluginHelper stringForDate:scanResult.dataGroup1.dateOfExpiry] forKey:@"dateOfExpiry"];
452
- [dictResultDataGroup1 setValue:scanResult.dataGroup1.documentNumber forKey:@"documentNumber"];
453
- [dictResultDataGroup1 setValue:scanResult.dataGroup1.documentType forKey:@"documentType"];
454
- [dictResultDataGroup1 setValue:scanResult.dataGroup1.firstName forKey:@"firstName"];
455
- [dictResultDataGroup1 setValue:scanResult.dataGroup1.gender forKey:@"gender"];
456
- [dictResultDataGroup1 setValue:scanResult.dataGroup1.issuingStateCode forKey:@"issuingStateCode"];
457
- [dictResultDataGroup1 setValue:scanResult.dataGroup1.lastName forKey:@"lastName"];
458
- [dictResultDataGroup1 setValue:scanResult.dataGroup1.nationality forKey:@"nationality"];
459
-
460
- [dictResult setObject:dictResultDataGroup1 forKey:@"dataGroup1"];
461
-
462
-
463
- //DataGroup2 (= Image)
464
- NSMutableDictionary *dictResultDataGroup2 = [[NSMutableDictionary alloc] initWithCapacity:1];
465
- NSString *imagePath = [self saveImageToFileSystem:scanResult.dataGroup2.faceImage compressionQuality:dividedCompRate];
466
- [dictResultDataGroup2 setValue:imagePath forKey:@"imagePath"];
467
-
468
- [dictResult setObject:dictResultDataGroup2 forKey:@"dataGroup2"];
469
-
470
- //SOB
471
- NSMutableDictionary *dictResultSOB = [[NSMutableDictionary alloc] init];
472
-
473
- [dictResultSOB setValue:scanResult.sod.issuerCertificationAuthority forKey:@"issuerCertificationAuthority"];
474
- [dictResultSOB setValue:scanResult.sod.issuerCountry forKey:@"issuerCountry"];
475
- [dictResultSOB setValue:scanResult.sod.issuerOrganization forKey:@"issuerOrganization"];
476
- [dictResultSOB setValue:scanResult.sod.issuerOrganizationalUnit forKey:@"issuerOrganizationalUnit"];
477
- [dictResultSOB setValue:scanResult.sod.ldsHashAlgorithm forKey:@"ldsHashAlgorithm"];
478
- [dictResultSOB setValue:scanResult.sod.signatureAlgorithm forKey:@"signatureAlgorithm"];
479
- [dictResultSOB setValue:scanResult.sod.validFromString forKey:@"validFromString"];
480
- [dictResultSOB setValue:scanResult.sod.validUntilString forKey:@"validUntilString"];
481
-
482
- [dictResult setObject:dictResultSOB forKey:@"sob"];
483
-
484
- return dictResult;
485
- }
486
-
306
+ UIAlertAction *action = [UIAlertAction actionWithTitle:@"Ok"
307
+ style:UIAlertActionStyleDefault
308
+ handler:^(UIAlertAction * _Nonnull action) {
487
309
 
488
- + (NSDictionary *)dictionaryForOCRResult:(ALOCRResult *)scanResult
489
- detectedBarcodes:(NSMutableArray<NSDictionary *> *)detectedBarcodes
490
- outline:(ALSquare *)outline
491
- quality:(NSInteger)quality {
492
- CGFloat dividedCompRate = (CGFloat)quality/100;
493
-
494
- NSMutableDictionary *dictResult = [NSMutableDictionary dictionaryWithCapacity:4];
495
-
496
- [dictResult setObject:scanResult.result forKey:@"text"];
497
-
498
- NSString *imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.image compressionQuality:dividedCompRate];
499
-
500
- [dictResult setValue:imagePath forKey:@"imagePath"];
501
-
502
- NSString *fullImagePath = [ALPluginHelper saveImageToFileSystem:scanResult.fullImage compressionQuality:dividedCompRate];
503
- [dictResult setValue:fullImagePath forKey:@"fullImagePath"];
504
-
505
- [dictResult setValue:[ALPluginHelper stringForOutline:outline] forKey:@"outline"];
506
-
507
- if (detectedBarcodes && detectedBarcodes.count != 0) {
508
- [dictResult setObject:detectedBarcodes forKey:@"detectedBarcodes"];
509
- }
510
-
511
- return dictResult;
512
- }
310
+ [[UIApplication sharedApplication].keyWindow.rootViewController
311
+ dismissViewControllerAnimated:YES completion:^{
312
+ callback(nil, @"Canceled");
313
+ }];
314
+ }];
513
315
 
514
- + (NSDictionary *)dictionaryForBarcodeResult:(ALBarcodeResult *)scanResult
515
- outline:(ALSquare *)outline
516
- quality:(NSInteger)quality {
517
- CGFloat dividedCompRate = (CGFloat)quality/100;
518
-
519
- NSMutableDictionary *dictResult = [NSMutableDictionary dictionaryWithCapacity:2];
520
-
521
- NSMutableArray *barcodeArray = [[NSMutableArray alloc] init];
522
-
523
-
524
- for(ALBarcode *barcode in scanResult.result) {
525
- NSMutableDictionary *barcodeDictionary = @{ @"value":barcode.value,
526
- @"barcodeFormat": [ALPluginHelper barcodeFormatFromString:barcode.barcodeFormat]}.mutableCopy;
527
- if (barcode.parsedPDF417 != nil) {
528
- NSString *newValueWithPDF417 = [NSString stringWithFormat:@"{\"rawPDF417\" : \"%@\", \"parsedPDF417\" : \"%@\"}", barcode.value, [barcode.parsedPDF417[kPDF417ParsedBody] description]];
529
- [barcodeDictionary setValue:newValueWithPDF417 forKey:@"value"];
530
- }
531
- [barcodeArray addObject:barcodeDictionary];
532
- }
533
-
534
- [dictResult setValue:barcodeArray forKey:@"barcodes"];
535
-
536
- NSString *imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.image compressionQuality:dividedCompRate];
537
-
538
- [dictResult setValue:imagePath forKey:@"imagePath"];
539
-
540
- NSString *fullImagePath = [ALPluginHelper saveImageToFileSystem:scanResult.fullImage compressionQuality:dividedCompRate];
541
- [dictResult setValue:fullImagePath forKey:@"fullImagePath"];
542
-
543
- [dictResult setValue:@(scanResult.confidence) forKey:@"confidence"];
544
- [dictResult setValue:[ALPluginHelper stringForOutline:outline] forKey:@"outline"];
545
-
546
- return dictResult;
316
+ [alert addAction:action];
317
+ [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert
318
+ animated:YES
319
+ completion:NULL];
320
+ return YES;
547
321
  }
548
322
 
549
- + (NSDictionary *)dictionaryForLicensePlateResult:(ALLicensePlateResult *)scanResult
550
- detectedBarcodes:(NSMutableArray<NSDictionary *> *)detectedBarcodes
551
- outline:(ALSquare *)outline
552
- quality:(NSInteger)quality {
553
- CGFloat dividedCompRate = (CGFloat)quality/100;
554
- // Get the imagepath from result
555
- NSString *imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.image compressionQuality:dividedCompRate];
556
-
557
- //Create the result Object
558
- NSMutableDictionary *dictResult = [NSMutableDictionary dictionaryWithCapacity:5];
559
- [dictResult setValue:scanResult.country forKey:@"country"];
560
- [dictResult setValue:scanResult.area forKey:@"area"];
561
- [dictResult setValue:scanResult.result forKey:@"licensePlate"];
562
- [dictResult setValue:[ALPluginHelper stringForOutline:outline] forKey:@"outline"];
563
- [dictResult setValue:@(scanResult.confidence) forKey:@"confidence"];
564
- [dictResult setValue:imagePath forKey:@"imagePath"];
565
-
566
- NSString *fullImagePath = [ALPluginHelper saveImageToFileSystem:scanResult.fullImage compressionQuality:dividedCompRate];
567
- [dictResult setValue:fullImagePath forKey:@"fullImagePath"];
568
-
569
- if (detectedBarcodes && detectedBarcodes.count != 0) {
570
- [dictResult setObject:detectedBarcodes forKey:@"detectedBarcodes"];
571
- }
572
-
573
- return dictResult;
323
+ + (NSError *)errorWithMessage:(NSString *)message {
324
+ return [NSError errorWithDomain:ALFlutterDomain code:1000 userInfo:@{ NSLocalizedDescriptionKey: message }];
574
325
  }
575
326
 
576
- + (NSDictionary *)dictionaryForTransformedImage:(UIImage *)transformedImage
577
- fullFrame:(UIImage *)fullFrame
578
- quality:(NSInteger)quality
579
- detectedBarcodes:(NSMutableArray<NSDictionary *> *)detectedBarcodes
580
- outline:(ALSquare *)outline {
581
- NSMutableDictionary *dictResult = [NSMutableDictionary dictionaryWithCapacity:4];
582
-
583
- CGFloat dividedCompRate = (CGFloat)quality/100;
584
- NSString *imagePath = [ALPluginHelper saveImageToFileSystem:transformedImage compressionQuality:dividedCompRate];
585
- NSString *fullImagePath = [ALPluginHelper saveImageToFileSystem:fullFrame compressionQuality:dividedCompRate];
586
- NSString *outlineString = [ALPluginHelper stringForOutline:outline];
587
-
588
-
589
- [dictResult setValue:imagePath forKey:@"imagePath"];
590
- [dictResult setValue:fullImagePath forKey:@"fullImagePath"];
591
- [dictResult setValue:outlineString forKey:@"outline"];
592
-
593
- if (detectedBarcodes && detectedBarcodes.count != 0) {
594
- [dictResult setObject:detectedBarcodes forKey:@"detectedBarcodes"];
595
- }
596
-
597
- return dictResult;
598
- }
327
+ // MARK: - Date Utils
599
328
 
600
- + (NSDictionary *)dictionaryForCompositeResult:(ALCompositeResult *)scanResult
601
- detectedBarcodes:(NSMutableArray<NSDictionary *> *)detectedBarcodes
602
- quality:(NSInteger)quality {
603
-
604
-
605
- NSMutableDictionary *dictResult = [[NSMutableDictionary alloc] init];
606
-
607
- for (NSString *pluginID in [scanResult.result allKeys]) {
608
-
609
- NSDictionary *singleResultDict = [ALPluginHelper dictForResult:[scanResult.result objectForKey:pluginID]
610
- detectedBarcodes:detectedBarcodes
611
- quality:quality];
612
-
613
- [dictResult setObject:singleResultDict forKey:pluginID];
614
-
615
- }
616
- return dictResult;
329
+ + (NSDate *)formattedStringToDate:(NSString *)formattedStr {
330
+ // From this: "Sun Apr 12 00:00:00 UTC 1977" to this: "04/12/1977"
331
+ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
332
+ [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT+0:00"]];
333
+ dateFormatter.dateFormat = @"E MMM d HH:mm:ss zzz yyyy";
334
+ NSDate *d = [dateFormatter dateFromString:formattedStr];
335
+ return d;
617
336
  }
618
337
 
619
- + (NSDictionary *)dictionaryForTireResult:(ALTireResult *)scanResult
620
- quality:(NSInteger)quality {
621
- CGFloat dividedCompRate = (CGFloat)quality/100;
622
-
623
- NSMutableDictionary *dictResult = [NSMutableDictionary dictionaryWithCapacity:4];
624
-
625
- [dictResult setObject:scanResult.result forKey:@"text"];
626
-
627
- NSString *imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.image compressionQuality:dividedCompRate];
628
-
629
- [dictResult setValue:imagePath forKey:@"imagePath"];
630
-
631
- NSString *fullImagePath = [ALPluginHelper saveImageToFileSystem:scanResult.fullImage compressionQuality:dividedCompRate];
632
- [dictResult setValue:fullImagePath forKey:@"fullImagePath"];
633
- [dictResult setValue:@(scanResult.confidence) forKey:@"confidence"];
634
- [dictResult setValue:scanResult.pluginID forKey:@"pluginID"];
635
- return dictResult;
338
+ + (NSString *)stringForDate:(NSDate *)date {
339
+ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
340
+ [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT+0:00"]];
341
+ dateFormatter.dateStyle = NSDateFormatterMediumStyle;
342
+ dateFormatter.timeStyle = NSDateFormatterNoStyle;
343
+ return [dateFormatter stringFromDate:date];
636
344
  }
637
345
 
638
- + (NSDictionary *)dictForResult:(ALScanResult *)result
639
- detectedBarcodes:(NSMutableArray<NSDictionary *> *)detectedBarcodes
640
- quality:(NSInteger)quality {
641
- if ([result isKindOfClass:[ALMeterResult class]]) {
642
- return [ALPluginHelper dictionaryForMeterResult:(ALMeterResult *)result
643
- detectedBarcodes:detectedBarcodes
644
- outline:[[ALSquare alloc] init]
645
- quality:quality];
646
-
647
- } else if ([result isKindOfClass:[ALLicensePlateResult class]]) {
648
- return [ALPluginHelper dictionaryForLicensePlateResult:(ALLicensePlateResult *)result
649
- detectedBarcodes:detectedBarcodes
650
- outline:[[ALSquare alloc] init]
651
- quality:quality];
652
- } else if ([result isKindOfClass:[ALIDResult class]]) {
653
- return [ALPluginHelper dictionaryForIDResult:(ALIDResult *)result
654
- detectedBarcodes:detectedBarcodes
655
- outline:[[ALSquare alloc] init]
656
- quality:quality];
657
-
658
- } else if ([result isKindOfClass:[ALBarcodeResult class]]) {
659
- return [ALPluginHelper dictionaryForBarcodeResult:(ALBarcodeResult *)result
660
- outline:[[ALSquare alloc] init]
661
- quality:quality];
662
-
663
- } else if ([result isKindOfClass:[ALOCRResult class]]) {
664
- return [ALPluginHelper dictionaryForOCRResult:(ALOCRResult *)result
665
- detectedBarcodes:detectedBarcodes
666
- outline:[[ALSquare alloc] init]
667
- quality:quality];
668
-
669
- } else if ([result.result isKindOfClass:[UIImage class]]) {
670
- return [ALPluginHelper dictionaryForTransformedImage:(UIImage *)result.result
671
- fullFrame:result.fullImage
672
- quality:quality
673
- detectedBarcodes:detectedBarcodes
674
- outline:[[ALSquare alloc] init]];
675
-
346
+ // MARK: - Plugin Reflection
347
+
348
+ // return the ALPluginConfig property whose name ends with 'Config', is nonnull, AND which has a `scanMode` property
349
+ + (NSString * _Nullable)confPropKeyWithScanModeForPluginConfig:(ALPluginConfig *)pluginConfig {
350
+ unsigned int count;
351
+ Ivar *ivars = class_copyIvarList(ALPluginConfig.class, &count);
352
+ for (int i = 0; i < count; i++) {
353
+ const char *ivarName = ivar_getName(((Ivar * _Nonnull)ivars)[i]);
354
+ NSString *key = [NSString stringWithCString:(const char * _Nonnull)ivarName encoding:NSUTF8StringEncoding];
355
+ key = [key stringByTrimmingCharactersInSet:NSCharacterSet.punctuationCharacterSet];
356
+
357
+ // Looking for "Config" at the end of the property name.
358
+ NSRange range = [key rangeOfString:@"Config"];
359
+ if (range.location == NSNotFound) { continue; }
360
+ if (range.location + @"Config".length == key.length) {
361
+ id obj;
362
+ if ((obj = [pluginConfig valueForKey:key])) { // config property is non-null
363
+ // one last check: does the value associated with this key have a scanMode property (that is a string type)?
364
+ if ([obj respondsToSelector:NSSelectorFromString(@"scanMode")]) {
365
+ return key; // this key is valid for self.pluginConfig, obj is the object tied to this key
366
+ }
367
+ // the rest wouldn't meet the requirements, so don't bother with them.
368
+ return nil;
369
+ }
370
+ }
676
371
  }
677
-
372
+ free(ivars);
678
373
  return nil;
679
374
  }
680
375
 
681
- #pragma mark - Date Parsing Utils
682
-
683
- + (NSString *)stringForDate:(NSDate *)date {
684
- if (!date) {
685
- return nil;
686
- }
687
-
688
- NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
689
- [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC+0:00"]];
690
- [dateFormatter setDateFormat:@"EEE MMM d hh:mm:ss ZZZZ yyyy"];
691
-
692
- //Date will be formatted to string - e.g.: "Fri Jan 11 12:00:00 GMT+0:00 1980"
693
- NSString *dateString = [dateFormatter stringFromDate:date];
694
-
695
- return dateString;
696
- }
697
376
 
698
377
  @end