anyline-ocr-react-native-module 53.2.0 → 54.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.
- package/android/.gradle/7.6/checksums/checksums.lock +0 -0
- package/android/.gradle/7.6/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/7.6/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/7.6/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/7.6/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/7.6/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/7.6/fileChanges/last-build.bin +0 -0
- package/android/.gradle/7.6/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/7.6/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.6/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/android/.gradle/config.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/.idea/compiler.xml +6 -0
- package/android/.idea/gradle.xml +17 -0
- package/android/.idea/migrations.xml +10 -0
- package/android/.idea/misc.xml +10 -0
- package/android/.idea/other.xml +296 -0
- package/android/.idea/vcs.xml +6 -0
- package/android/build.gradle +1 -1
- package/android/local.properties +8 -0
- package/android/src/main/java/com/anyline/reactnative/AnylineSDKPlugin.java +16 -2
- package/android/src/main/java/com/anyline/reactnative/ScanActivity.java +15 -2
- package/ios/ALJsonUIConfiguration.m +3 -0
- package/ios/ALPluginHelper.h +1 -3
- package/ios/ALPluginHelper.m +27 -59
- package/ios/ALPluginScanViewController.h +1 -0
- package/ios/ALPluginScanViewController.m +23 -1
- package/ios/AnylineReact.podspec +3 -3
- package/ios/AnylineSDKPlugin.m +31 -42
- package/package.json +8 -8
- package/ios/ALNFCScanViewController.h +0 -14
- package/ios/ALNFCScanViewController.m +0 -452
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
#import <Anyline/Anyline.h>
|
|
2
|
-
#import "ALNFCScanViewController.h"
|
|
3
|
-
#import "ALPluginHelper.h"
|
|
4
|
-
#import "AnylineSDKPlugin.h"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
API_AVAILABLE(ios(13.0))
|
|
8
|
-
@interface ALNFCScanViewController () <ALNFCDetectorDelegate, ALScanPluginDelegate, ALScanViewDelegate>
|
|
9
|
-
|
|
10
|
-
@property (nonatomic, strong) ALPluginCallback callback;
|
|
11
|
-
|
|
12
|
-
@property (nonatomic, strong) NSDictionary *config;
|
|
13
|
-
|
|
14
|
-
@property (nonatomic, copy) NSString *licenseKey;
|
|
15
|
-
|
|
16
|
-
@property (nonatomic, strong) ALScanView *scanView;
|
|
17
|
-
|
|
18
|
-
@property (nonatomic, strong) ALScanViewPlugin *mrzScanViewPlugin;
|
|
19
|
-
|
|
20
|
-
@property (nonatomic, strong) ALNFCDetector *nfcDetector;
|
|
21
|
-
|
|
22
|
-
// the result from NFC scanning is retained while NFC reading is initiated, and the results aggregated later
|
|
23
|
-
@property (nonatomic, strong) NSMutableDictionary *resultDict;
|
|
24
|
-
|
|
25
|
-
@property (nonatomic, strong) ALJSONUIConfiguration *uiConfig;
|
|
26
|
-
|
|
27
|
-
@property (nonatomic, strong) UIView *hintView;
|
|
28
|
-
|
|
29
|
-
@property (nonatomic, strong) UILabel *hintViewLabel;
|
|
30
|
-
|
|
31
|
-
@property (nonatomic, strong) NSLayoutConstraint *labelHorizontalOffsetConstraint;
|
|
32
|
-
|
|
33
|
-
@property (nonatomic, strong) NSLayoutConstraint *labelVerticalOffsetConstraint;
|
|
34
|
-
|
|
35
|
-
@property (nonatomic, strong) UIButton *doneButton;
|
|
36
|
-
|
|
37
|
-
// keep the last values we read from the MRZ so we can retry reading NFC
|
|
38
|
-
// if NFC failed for reasons other than getting these details wrong
|
|
39
|
-
@property (nonatomic, copy) NSString *passportNumberForNFC;
|
|
40
|
-
|
|
41
|
-
@property (nonatomic, strong) NSDate *dateOfBirth;
|
|
42
|
-
|
|
43
|
-
@property (nonatomic, strong) NSDate *dateOfExpiry;
|
|
44
|
-
|
|
45
|
-
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *detectedBarcodes;
|
|
46
|
-
|
|
47
|
-
// JPEG compression quality 0-100
|
|
48
|
-
@property (nonatomic, assign) NSUInteger quality;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@end
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
@implementation ALNFCScanViewController
|
|
55
|
-
|
|
56
|
-
- (instancetype)initWithLicensekey:(NSString *)licensekey
|
|
57
|
-
configuration:(NSDictionary *)anylineConfig
|
|
58
|
-
uiConfig:(ALJSONUIConfiguration *)uiConfig
|
|
59
|
-
finished:(ALPluginCallback)callback {
|
|
60
|
-
if (self = [super init]) {
|
|
61
|
-
_licenseKey = licensekey;
|
|
62
|
-
_callback = callback;
|
|
63
|
-
_config = anylineConfig;
|
|
64
|
-
_uiConfig = uiConfig;
|
|
65
|
-
|
|
66
|
-
self.quality = 90;
|
|
67
|
-
}
|
|
68
|
-
return self;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
- (void)viewDidLoad {
|
|
72
|
-
[super viewDidLoad];
|
|
73
|
-
|
|
74
|
-
// NOTE: NFCDetector can throw an exception if the AnylineSDK isn't initialized
|
|
75
|
-
// first as it will check the scope value of the license.
|
|
76
|
-
//
|
|
77
|
-
// If already initialized, happily move along. Otherwise, make a license key
|
|
78
|
-
// check here.
|
|
79
|
-
NSError *error;
|
|
80
|
-
BOOL isInitialized = [ALLicenseUtil sharedInstance].isLicenseValid;
|
|
81
|
-
if (!isInitialized) {
|
|
82
|
-
[AnylineSDK setupWithLicenseKey:self.licenseKey cacheConfig:nil wrapperConfig:wrapperConfig error:&error];
|
|
83
|
-
if ([self showErrorAlertIfNeeded:error]) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (@available(iOS 13.0, *)) {
|
|
89
|
-
self.nfcDetector = [self.class getNFCDetectorWithDelegate:self error:&error];
|
|
90
|
-
} else {
|
|
91
|
-
error = [ALPluginHelper errorWithMessage:@"iOS 13.0 or newer is required to scan with MRZ / NFC."];
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if ([self showErrorAlertIfNeeded:error]) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
[self.view addSubview:self.scanView];
|
|
99
|
-
|
|
100
|
-
self.resultDict = [[NSMutableDictionary alloc] init];
|
|
101
|
-
self.detectedBarcodes = [NSMutableArray array];
|
|
102
|
-
|
|
103
|
-
self.scanView = [ALScanViewFactory withJSONDictionary:self.config delegate:self error:&error];
|
|
104
|
-
self.scanView.delegate = self;
|
|
105
|
-
|
|
106
|
-
[self configureMRZPlugin];
|
|
107
|
-
|
|
108
|
-
if ([self showErrorAlertIfNeeded:error]) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
self.mrzScanViewPlugin = (ALScanViewPlugin *)self.scanView.viewPlugin;
|
|
113
|
-
|
|
114
|
-
self.scanView.supportedNativeBarcodeFormats = self.uiConfig.nativeBarcodeFormats;
|
|
115
|
-
self.scanView.delegate = self;
|
|
116
|
-
self.detectedBarcodes = [NSMutableArray array];
|
|
117
|
-
|
|
118
|
-
[self.view addSubview:self.scanView];
|
|
119
|
-
|
|
120
|
-
self.scanView.translatesAutoresizingMaskIntoConstraints = false;
|
|
121
|
-
[self.scanView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
|
|
122
|
-
[self.scanView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;
|
|
123
|
-
[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].active = YES;
|
|
124
|
-
[self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
|
|
125
|
-
|
|
126
|
-
[self.scanView startCamera];
|
|
127
|
-
|
|
128
|
-
[self setupHintView];
|
|
129
|
-
|
|
130
|
-
self.doneButton = [ALPluginHelper createButtonForViewController:self config:self.uiConfig];
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
- (void)viewDidAppear:(BOOL)animated {
|
|
134
|
-
[super viewDidAppear:animated];
|
|
135
|
-
|
|
136
|
-
NSError *error;
|
|
137
|
-
[self startMRZScanning:&error];
|
|
138
|
-
[self showErrorAlertIfNeeded:error];
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
- (void)viewDidDisappear:(BOOL)animated {
|
|
142
|
-
[self stopMRZScanning];
|
|
143
|
-
[super viewDidDisappear:animated];
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
- (void)startMRZScanning:(NSError **)error {
|
|
147
|
-
[self.mrzScanViewPlugin startWithError:error];
|
|
148
|
-
self.hintView.hidden = NO;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
- (void)stopMRZScanning {
|
|
152
|
-
[self.mrzScanViewPlugin stop];
|
|
153
|
-
self.hintView.hidden = YES;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
- (void)configureMRZPlugin {
|
|
157
|
-
|
|
158
|
-
ALScanViewPlugin *scanViewPlugin = (ALScanViewPlugin *)self.scanView.viewPlugin;
|
|
159
|
-
if (![scanViewPlugin isKindOfClass:ALScanViewPlugin.class]) {
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
ALCutoutConfig *cutoutConfig = scanViewPlugin.scanViewPluginConfig.cutoutConfig;
|
|
164
|
-
ALScanFeedbackConfig *scanFeedbackConfig = scanViewPlugin.scanViewPluginConfig.scanFeedbackConfig;
|
|
165
|
-
|
|
166
|
-
ALPluginConfig *pluginConfig = scanViewPlugin.scanPlugin.pluginConfig;
|
|
167
|
-
ALMrzConfig *mrzConfig = pluginConfig.mrzConfig;
|
|
168
|
-
|
|
169
|
-
// a bit lengthy but this is how you properly change the config (mrzFieldScanOptions and mrzMinFieldConfidences)
|
|
170
|
-
// taking into account the readonly config fields
|
|
171
|
-
mrzConfig.mrzFieldScanOptions = [[ALMrzFieldScanOptions alloc] init];
|
|
172
|
-
|
|
173
|
-
mrzConfig.mrzFieldScanOptions.vizAddress = ALMrzScanOption.mrzScanOptionDefault;
|
|
174
|
-
mrzConfig.mrzFieldScanOptions.vizDateOfIssue = ALMrzScanOption.mrzScanOptionDefault;
|
|
175
|
-
mrzConfig.mrzFieldScanOptions.vizSurname = ALMrzScanOption.mrzScanOptionDefault;
|
|
176
|
-
mrzConfig.mrzFieldScanOptions.vizGivenNames = ALMrzScanOption.mrzScanOptionDefault;
|
|
177
|
-
mrzConfig.mrzFieldScanOptions.vizDateOfBirth = ALMrzScanOption.mrzScanOptionDefault;
|
|
178
|
-
mrzConfig.mrzFieldScanOptions.vizDateOfExpiry = ALMrzScanOption.mrzScanOptionDefault;
|
|
179
|
-
|
|
180
|
-
mrzConfig.mrzMinFieldConfidences = [[ALMrzMinFieldConfidences alloc] init];
|
|
181
|
-
mrzConfig.mrzMinFieldConfidences.documentNumber = @(90);
|
|
182
|
-
mrzConfig.mrzMinFieldConfidences.dateOfBirth = @(90);
|
|
183
|
-
mrzConfig.mrzMinFieldConfidences.dateOfExpiry = @(90);
|
|
184
|
-
|
|
185
|
-
NSError *error;
|
|
186
|
-
|
|
187
|
-
ALViewPluginConfig *scanViewPluginConfig = scanViewPlugin.scanViewPluginConfig;
|
|
188
|
-
[self.scanView setViewPluginConfig:scanViewPluginConfig error:&error];
|
|
189
|
-
|
|
190
|
-
// the delegate binding was lost when you recreated the ScanPlugin it so you have to bring it back here
|
|
191
|
-
scanViewPlugin = (ALScanViewPlugin *)self.scanView.viewPlugin;
|
|
192
|
-
scanViewPlugin.scanPlugin.delegate = self;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// MARK: - ALIDPluginDelegate
|
|
196
|
-
|
|
197
|
-
- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult {
|
|
198
|
-
|
|
199
|
-
CGFloat compressionQuality = self.quality / 100.0f;
|
|
200
|
-
|
|
201
|
-
// ACO just a failsafe for when cancelOnResult is not true
|
|
202
|
-
[self stopMRZScanning];
|
|
203
|
-
|
|
204
|
-
self.resultDict = [NSMutableDictionary dictionaryWithDictionary:scanResult.resultDictionary];
|
|
205
|
-
|
|
206
|
-
NSString *imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.croppedImage
|
|
207
|
-
compressionQuality:compressionQuality];
|
|
208
|
-
self.resultDict[@"imagePath"] = imagePath;
|
|
209
|
-
|
|
210
|
-
imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.fullSizeImage
|
|
211
|
-
compressionQuality:compressionQuality];
|
|
212
|
-
|
|
213
|
-
self.resultDict[@"fullImagePath"] = imagePath;
|
|
214
|
-
|
|
215
|
-
ALMrzResult *MRZResult = scanResult.pluginResult.mrzResult;
|
|
216
|
-
NSString *passportNumber = [MRZResult.documentNumber stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
|
217
|
-
|
|
218
|
-
self.dateOfBirth = [ALPluginHelper formattedStringToDate:MRZResult.dateOfBirthObject];
|
|
219
|
-
|
|
220
|
-
self.dateOfExpiry = [ALPluginHelper formattedStringToDate:MRZResult.dateOfExpiryObject];
|
|
221
|
-
|
|
222
|
-
NSMutableString *passportNumberForNFC = [passportNumber mutableCopy];
|
|
223
|
-
NSRange passportNumberRange = [MRZResult.mrzString rangeOfString:passportNumber];
|
|
224
|
-
if (passportNumberRange.location != NSNotFound) {
|
|
225
|
-
if ([MRZResult.mrzString characterAtIndex:NSMaxRange(passportNumberRange)] == '<') {
|
|
226
|
-
[passportNumberForNFC appendString:@"<"];
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
self.passportNumberForNFC = passportNumberForNFC;
|
|
231
|
-
|
|
232
|
-
[self.nfcDetector startNfcDetectionWithPassportNumber:self.passportNumberForNFC
|
|
233
|
-
dateOfBirth:self.dateOfBirth
|
|
234
|
-
expirationDate:self.dateOfExpiry];
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
- (void)handleResult:(id _Nullable)resultObj {
|
|
238
|
-
|
|
239
|
-
NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionaryWithDictionary:resultObj];
|
|
240
|
-
if (self.detectedBarcodes.count) {
|
|
241
|
-
resultDictionary[@"nativeBarcodesDetected"] = self.detectedBarcodes;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
NSObject<ALViewPluginBase> *scanViewPluginBase = self.scanView.viewPlugin;
|
|
245
|
-
if ([scanViewPluginBase isKindOfClass:ALScanViewPlugin.class]) {
|
|
246
|
-
ALScanViewPlugin *scanViewPlugin = (ALScanViewPlugin *)scanViewPluginBase;
|
|
247
|
-
BOOL cancelOnResult = scanViewPlugin.scanPlugin.pluginConfig.cancelOnResult;
|
|
248
|
-
if (cancelOnResult) {
|
|
249
|
-
[self dismissViewControllerAnimated:YES completion:nil];
|
|
250
|
-
}
|
|
251
|
-
} else if ([scanViewPluginBase isKindOfClass:ALViewPluginComposite.class]) {
|
|
252
|
-
// for composites, the cancelOnResult values for each child don't matter
|
|
253
|
-
[self dismissViewControllerAnimated:YES completion:nil];
|
|
254
|
-
}
|
|
255
|
-
self.callback(resultDictionary, nil);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
- (void)doneButtonPressed:(id)sender {
|
|
259
|
-
[self stopMRZScanning];
|
|
260
|
-
|
|
261
|
-
__weak __block typeof(self) weakSelf = self;
|
|
262
|
-
[self dismissViewControllerAnimated:YES completion:^{
|
|
263
|
-
weakSelf.callback(nil, @"Canceled");
|
|
264
|
-
}];
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// MARK: - ALNFCDetectorDelegate
|
|
268
|
-
|
|
269
|
-
- (void)nfcSucceededWithResult:(ALNFCResult * _Nonnull)nfcResult API_AVAILABLE(ios(13.0)) {
|
|
270
|
-
|
|
271
|
-
// DataGroup1
|
|
272
|
-
NSMutableDictionary *dictResultDataGroup1 = [[NSMutableDictionary alloc] init];
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
[dictResultDataGroup1 setValue:[ALPluginHelper stringForDate:nfcResult.dataGroup1.dateOfBirth]
|
|
276
|
-
forKey:@"dateOfBirth"];
|
|
277
|
-
[dictResultDataGroup1 setValue:[ALPluginHelper stringForDate:nfcResult.dataGroup1.dateOfExpiry]
|
|
278
|
-
forKey:@"dateOfExpiry"];
|
|
279
|
-
[dictResultDataGroup1 setValue:nfcResult.dataGroup1.documentNumber forKey:@"documentNumber"];
|
|
280
|
-
[dictResultDataGroup1 setValue:nfcResult.dataGroup1.documentType forKey:@"documentType"];
|
|
281
|
-
[dictResultDataGroup1 setValue:nfcResult.dataGroup1.firstName forKey:@"firstName"];
|
|
282
|
-
[dictResultDataGroup1 setValue:nfcResult.dataGroup1.gender forKey:@"gender"];
|
|
283
|
-
[dictResultDataGroup1 setValue:nfcResult.dataGroup1.issuingStateCode forKey:@"issuingStateCode"];
|
|
284
|
-
[dictResultDataGroup1 setValue:nfcResult.dataGroup1.lastName forKey:@"lastName"];
|
|
285
|
-
[dictResultDataGroup1 setValue:nfcResult.dataGroup1.nationality forKey:@"nationality"];
|
|
286
|
-
|
|
287
|
-
[self.resultDict setObject:dictResultDataGroup1 forKey:@"dataGroup1"];
|
|
288
|
-
|
|
289
|
-
// DataGroup2
|
|
290
|
-
// ACO: we don't put the path into a separate 'dataGroup' category for the wrapper
|
|
291
|
-
NSString *imagePath = [ALPluginHelper saveImageToFileSystem:nfcResult.dataGroup2.faceImage
|
|
292
|
-
compressionQuality:self.quality / (CGFloat)100.0f];
|
|
293
|
-
if (imagePath) {
|
|
294
|
-
[self.resultDict setValue:imagePath forKey:@"imagePath"];
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// SOD (Passport metadata)
|
|
298
|
-
NSMutableDictionary *dictResultSOD = [[NSMutableDictionary alloc] init];
|
|
299
|
-
|
|
300
|
-
[dictResultSOD setValue:nfcResult.sod.issuerCertificationAuthority forKey:@"issuerCertificationAuthority"];
|
|
301
|
-
[dictResultSOD setValue:nfcResult.sod.issuerCountry forKey:@"issuerCountry"];
|
|
302
|
-
[dictResultSOD setValue:nfcResult.sod.issuerOrganization forKey:@"issuerOrganization"];
|
|
303
|
-
[dictResultSOD setValue:nfcResult.sod.issuerOrganizationalUnit forKey:@"issuerOrganizationalUnit"];
|
|
304
|
-
[dictResultSOD setValue:nfcResult.sod.ldsHashAlgorithm forKey:@"ldsHashAlgorithm"];
|
|
305
|
-
|
|
306
|
-
// ACO need to disable this because AppStoreConnect produces a warning with this enabled:
|
|
307
|
-
// https://anyline.atlassian.net/browse/SDKY-1509?focusedCommentId=71554
|
|
308
|
-
// [dictResultSOB setValue:nfcResult.sod.signatureAlgorithm forKey:@"signatureAlgorithm"];
|
|
309
|
-
|
|
310
|
-
[dictResultSOD setValue:nfcResult.sod.validFromString forKey:@"validFromString"];
|
|
311
|
-
[dictResultSOD setValue:nfcResult.sod.validUntilString forKey:@"validUntilString"];
|
|
312
|
-
|
|
313
|
-
[self.resultDict setObject:dictResultSOD forKey:@"sod"];
|
|
314
|
-
|
|
315
|
-
__weak __block typeof(self) weakSelf = self;
|
|
316
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
317
|
-
[weakSelf handleResult:weakSelf.resultDict];
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
- (void)nfcFailedWithError:(NSError * _Nonnull)error {
|
|
322
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
323
|
-
if (error.code == ALNFCTagErrorNFCNotSupported) {
|
|
324
|
-
[self showAlertWithTitle:@"NFC Not Supported"
|
|
325
|
-
message:@"NFC passport reading is not supported on this device."];
|
|
326
|
-
}
|
|
327
|
-
if (error.code == ALNFCTagErrorResponseError || // MRZ key was likely wrong
|
|
328
|
-
error.code == ALNFCTagErrorUnexpectedError) {
|
|
329
|
-
// can mean the user pressed the 'Cancel' button while scanning, or the phone lost the
|
|
330
|
-
// connection with the NFC chip because it was moved
|
|
331
|
-
[self startMRZScanning:nil]; //run the MRZ scanner so we can try again.
|
|
332
|
-
} else {
|
|
333
|
-
// the MRZ details are correct, but something else went wrong. We can try reading
|
|
334
|
-
// the NFC chip again without rescanning the MRZ.
|
|
335
|
-
__weak __block typeof(self) weakSelf = self;
|
|
336
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
337
|
-
[weakSelf.nfcDetector startNfcDetectionWithPassportNumber:weakSelf.passportNumberForNFC
|
|
338
|
-
dateOfBirth:weakSelf.dateOfBirth
|
|
339
|
-
expirationDate:weakSelf.dateOfExpiry];
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// MARK: - ALScanViewDelegate
|
|
346
|
-
|
|
347
|
-
- (void)scanView:(ALScanView *)scanView updatedCutoutWithPluginID:(NSString *)pluginID
|
|
348
|
-
frame:(CGRect)frame {
|
|
349
|
-
|
|
350
|
-
if (CGRectIsEmpty(frame)) {
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
self.hintView.hidden = NO;
|
|
355
|
-
|
|
356
|
-
CGFloat xOffset = self.uiConfig.labelXPositionOffset;
|
|
357
|
-
CGFloat yOffset = self.uiConfig.labelYPositionOffset;
|
|
358
|
-
|
|
359
|
-
// takes into account that frame reported for a cutout is in relation to
|
|
360
|
-
// its scan view's coordinate system
|
|
361
|
-
yOffset += [self.scanView convertRect:frame toView:self.scanView.superview].origin.y;
|
|
362
|
-
|
|
363
|
-
self.labelHorizontalOffsetConstraint.constant = xOffset;
|
|
364
|
-
self.labelVerticalOffsetConstraint.constant = yOffset;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
- (void)scanView:(ALScanView *)scanView didReceiveNativeBarcodeResult:(ALScanResult *)scanResult {
|
|
368
|
-
// for this implementation we just take the last detected (we can show a list of it)
|
|
369
|
-
[self.detectedBarcodes removeAllObjects];
|
|
370
|
-
[self.detectedBarcodes addObject:scanResult.resultDictionary];
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
// MARK: - ALNFCDetector
|
|
375
|
-
|
|
376
|
-
+ (ALNFCDetector * _Nullable)getNFCDetectorWithDelegate:(id<ALNFCDetectorDelegate> _Nonnull)delegate
|
|
377
|
-
error:(NSError * _Nullable * _Nullable)error API_AVAILABLE(ios(13.0)) {
|
|
378
|
-
ALNFCDetector *NFCDetector;
|
|
379
|
-
if (![ALNFCDetector readingAvailable]) {
|
|
380
|
-
if (error) {
|
|
381
|
-
*error = [ALPluginHelper errorWithMessage:@"NFC is not available for this device."];
|
|
382
|
-
}
|
|
383
|
-
return nil;
|
|
384
|
-
}
|
|
385
|
-
NFCDetector = [[ALNFCDetector alloc] initWithDelegate:delegate error:error];
|
|
386
|
-
if (!NFCDetector) {
|
|
387
|
-
return nil;
|
|
388
|
-
}
|
|
389
|
-
return NFCDetector;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// MARK: - Alerts
|
|
393
|
-
|
|
394
|
-
- (void)showAlertWithTitle:(NSString *)title message:(NSString *)message {
|
|
395
|
-
[ALPluginHelper showErrorAlertWithTitle:title message:message
|
|
396
|
-
presentingViewController:self.navigationController];
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
- (BOOL)showErrorAlertIfNeeded:(NSError *)error {
|
|
400
|
-
return [ALPluginHelper showErrorAlertIfNeeded:error pluginCallback:self.callback];
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// MARK: - User Interface
|
|
404
|
-
|
|
405
|
-
- (void)setupHintView {
|
|
406
|
-
|
|
407
|
-
UIView *hintView = [[UIView alloc] initWithFrame:CGRectZero];
|
|
408
|
-
hintView.layer.cornerRadius = 8;
|
|
409
|
-
hintView.layer.masksToBounds = true;
|
|
410
|
-
hintView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
|
|
411
|
-
|
|
412
|
-
hintView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
413
|
-
[self.view addSubview:hintView];
|
|
414
|
-
|
|
415
|
-
self.labelHorizontalOffsetConstraint = [hintView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant:0];
|
|
416
|
-
|
|
417
|
-
// at 0, the bottom of the label (container) should be touching the cutout top when the updatedCutoutRect report
|
|
418
|
-
// is made
|
|
419
|
-
self.labelVerticalOffsetConstraint = [hintView.bottomAnchor constraintEqualToAnchor:self.view.topAnchor constant:0];
|
|
420
|
-
|
|
421
|
-
self.labelHorizontalOffsetConstraint.active = YES;
|
|
422
|
-
self.labelVerticalOffsetConstraint.active = YES;
|
|
423
|
-
|
|
424
|
-
UILabel *hintViewLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
|
425
|
-
|
|
426
|
-
hintViewLabel.text = @"Scan MRZ";
|
|
427
|
-
if (self.uiConfig.labelText.length) {
|
|
428
|
-
hintViewLabel.text = self.uiConfig.labelText;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
hintViewLabel.font = [UIFont fontWithName:@"HelveticaNeue"
|
|
432
|
-
size:self.uiConfig.labelSize];
|
|
433
|
-
hintViewLabel.textColor = self.uiConfig.labelColor;
|
|
434
|
-
hintViewLabel.textAlignment = NSTextAlignmentCenter;
|
|
435
|
-
hintViewLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
|
436
|
-
[hintViewLabel sizeToFit];
|
|
437
|
-
[hintView addSubview:hintViewLabel];
|
|
438
|
-
|
|
439
|
-
[hintViewLabel.centerXAnchor constraintEqualToAnchor:hintView.centerXAnchor].active = YES;
|
|
440
|
-
[hintViewLabel.centerYAnchor constraintEqualToAnchor:hintView.centerYAnchor].active = YES;
|
|
441
|
-
|
|
442
|
-
NSLayoutConstraint *cnst = [hintView.widthAnchor constraintGreaterThanOrEqualToAnchor:hintViewLabel.widthAnchor
|
|
443
|
-
constant:20];
|
|
444
|
-
cnst.active = YES;
|
|
445
|
-
cnst = [hintView.heightAnchor constraintEqualToAnchor:hintViewLabel.heightAnchor constant:20];
|
|
446
|
-
cnst.active = YES;
|
|
447
|
-
|
|
448
|
-
self.hintView = hintView;
|
|
449
|
-
self.hintViewLabel = hintViewLabel;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
@end
|