diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/AppDelegate.m b/AnylineExamples/Anyline Demo App/DemoApp Source/AppDelegate.m index a88bcd1cb..942c905d5 100755 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/AppDelegate.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/AppDelegate.m @@ -41,7 +41,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [[self class] applyAppearanceTweaks]; NSError *error; - [AnylineSDK setupWithLicenseKey:kDemoAppLicenseKey error:&error]; + + NSString *licenseKey = kDemoAppLicenseKey_Bundle; + [AnylineSDK setupWithLicenseKey:licenseKey error:&error]; if (error) { NSLog(@"Error with Anyline license: %@",error.localizedDescription); return NO; diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Components/ALScriptSelectionViewController.m b/AnylineExamples/Anyline Demo App/DemoApp Source/Components/ALScriptSelectionViewController.m index fd0c27517..7479d1869 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Components/ALScriptSelectionViewController.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Components/ALScriptSelectionViewController.m @@ -19,10 +19,8 @@ @interface ALScriptSelectionViewController () @implementation ALScriptSelectionViewController -+ (UIBarButtonItem*)createBarButtonForScriptSelection:(UIViewController *)viewController { - ++ (UIBarButtonItem *)createBarButtonForScriptSelection:(UIViewController *)viewController { UIButton *scriptSelectionButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 40)]; - [scriptSelectionButton setContentMode:UIViewContentModeScaleAspectFit]; [scriptSelectionButton.imageView setContentMode:UIViewContentModeScaleAspectFit]; [scriptSelectionButton setImage:[UIImage imageNamed:@"script_selection"] forState:UIControlStateNormal]; @@ -116,17 +114,17 @@ - (void)viewDidLoad { [self setArabicScriptButtonActions]; } --(void)viewDidDisappear:(BOOL)animated { +- (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } --(void)setLatinScriptButtonActions { +- (void)setLatinScriptButtonActions { [self.latinScriptButton addTarget:self action:@selector(selectedScriptSelected:) forControlEvents:UIControlEventTouchUpInside]; [self.latinScriptButton addTarget:self action:@selector(setUnselectedButton:) forControlEvents:UIControlEventTouchDown]; } --(void)setArabicScriptButtonActions { +- (void)setArabicScriptButtonActions { [self.arabicScriptbutton addTarget:self action:@selector(selectedScriptSelected:) forControlEvents:UIControlEventTouchUpInside]; [self.arabicScriptbutton addTarget:self action:@selector(setUnselectedButton:) forControlEvents:UIControlEventTouchDown]; } @@ -135,12 +133,12 @@ - (void)setUnselectedButton:(UIButton*)sender { [sender setSelected:NO]; } --(void)selectedScriptSelected:(UIButton*)sender { +- (void)selectedScriptSelected:(UIButton*)sender { [sender setSelected:YES]; [self dismissViewControllerAnimated:YES completion:nil]; } --(void)changeScript:(BOOL)isArabic { +- (void)changeScript:(BOOL)isArabic { if (self.delegate) { [self.delegate changeScript:isArabic]; } diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/GridViews/ALBaseGridCollectionViewController.m b/AnylineExamples/Anyline Demo App/DemoApp Source/GridViews/ALBaseGridCollectionViewController.m index f4e1ae733..04f075b6d 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/GridViews/ALBaseGridCollectionViewController.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/GridViews/ALBaseGridCollectionViewController.m @@ -7,6 +7,7 @@ // #import "ALBaseGridCollectionViewController.h" +#import #import "ALGridCollectionViewCell.h" #import "ALMeterCollectionViewController.h" #import "ALGridCollectionViewController.h" @@ -19,7 +20,8 @@ #import "NSUserDefaults+ALExamplesAdditions.h" #import "UIColor+ALExamplesAdditions.h" #import "ALHeaderCollectionReusableView.h" -#import "ALUniversalIDScanViewControllerFrontAndBack.h" +#import "ALUniversalIDScanViewController.h" +#import "ALLicensePlateScanViewController.h" NSString * const reuseIdentifier = @"gridCell"; NSString * const viewControllerIdentifier = @"gridViewController"; @@ -272,8 +274,12 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa #pragma mark - Utility Methods - (CGSize)collectionView:(UICollectionView *)collectionView - layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section { - return [self headerSize]; + layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section { + if ([self.exampleManager numberOfSections] > 1) { + return [self headerSize]; + } else { + return CGSizeZero; + } } - (CGSize)collectionView:(UICollectionView *)collectionView diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALExampleManager.m b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALExampleManager.m index 53cc511da..ae5600d79 100755 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALExampleManager.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALExampleManager.m @@ -11,7 +11,7 @@ #import "ALAutoAnalogDigitalMeterScanViewController.h" #import "ALDialMeterScanViewController.h" -#import "ALMultiformatBarcodeScanViewController.h" +#import "ALBarcodeScanViewController.h" #import "ALMRZScanViewController.h" #import "ALIBANScanViewController.h" #import "ALVoucherCodeScanViewController.h" @@ -20,7 +20,7 @@ #import "ALRBScanViewController.h" #import "ALScrabbleScanViewController.h" #import "ALDocumentScanViewController.h" -#import "ALLicensePlateViewController.h" +#import "ALLicensePlateScanViewController.h" NSString * const processTitle = @"Processes"; diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALIdentityDocumentsExampleManager.h b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALIdentityDocumentsExampleManager.h index bb9c4b1b0..91a980126 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALIdentityDocumentsExampleManager.h +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALIdentityDocumentsExampleManager.h @@ -11,9 +11,6 @@ #import "ALExample.h" #import "ALExampleManager.h" -extern NSString * const kDriversLicenseTitleString; -extern NSString * const kIDCardTitleString; - @interface ALIdentityDocumentsExampleManager : ALExampleManager @end diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALIdentityDocumentsExampleManager.m b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALIdentityDocumentsExampleManager.m index 2cc0e6dc0..069816449 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALIdentityDocumentsExampleManager.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALIdentityDocumentsExampleManager.m @@ -15,13 +15,7 @@ #import "ALMeterCollectionViewController.h" #import "ALPDF417ScanViewController.h" #import "ALNFCScanViewController.h" - #import "ALUniversalIDScanViewController.h" -#import "ALUniversalIDScanViewControllerFrontAndBack.h" - -NSString * const kDriversLicenseTitleString = @"Driver's License"; -NSString * const kIDCardTitleString = @"ID Card"; -NSString * const kPassportVisaTitleString = @"Passport / Visa"; @interface ALIdentityDocumentsExampleManager () @@ -46,18 +40,18 @@ - (void)initExampleData { ALExample *universalID = [[ALExample alloc] initWithName:NSLocalizedString(@"Universal ID", nil) image:[UIImage imageNamed:@"tile_universalid"] - viewController:[ALUniversalIDScanViewControllerFrontAndBack class]]; + viewController:[ALUniversalIDScanViewController class]]; self.canUpdate = YES; ALExample *drivingLicenseScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Driver's License", nil) image:[UIImage imageNamed:@"tile_driverslicense"] - viewController:[ALUniversalIDScanViewControllerFrontAndBack class] + viewController:[ALUniversalIDScanViewController class] title:kDriversLicenseTitleString]; ALExample *idCardScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"ID Card", nil) image:[UIImage imageNamed:@"tile_idcard"] - viewController:[ALUniversalIDScanViewControllerFrontAndBack class] + viewController:[ALUniversalIDScanViewController class] title:kIDCardTitleString]; ALExample *passportScanning = [[ALExample alloc] initWithName:NSLocalizedString(kPassportVisaTitleString, nil) diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALLicensePlateExampleManager.m b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALLicensePlateExampleManager.m index 653869ff0..939143ab3 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALLicensePlateExampleManager.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALLicensePlateExampleManager.m @@ -1,15 +1,5 @@ -// -// ALLicensePlateExampleManager.m -// AnylineExamples -// -// Created by Philipp Müller on 05/03/2021. -// Copyright © 2021 Anyline GmbH. All rights reserved. -// - #import "ALLicensePlateExampleManager.h" -#import "ALLicensePlateViewController.h" -#import "ALUSLicensePlateViewController.h" -#import "ALAFLicensePlateViewController.h" +#import "ALLicensePlateScanViewController.h" @interface ALLicensePlateExampleManager () @@ -19,11 +9,11 @@ @interface ALLicensePlateExampleManager () @end + @implementation ALLicensePlateExampleManager - (instancetype)init { - self = [super init]; - if (self) { + if (self = [super init]) { [self initExampleData]; } return self; @@ -33,17 +23,20 @@ - (void)initExampleData { self.title = @"License Plate"; ALExample *licensePlateEU = [[ALExample alloc] initWithName:NSLocalizedString(@"EU License Plate", nil) - image:[UIImage imageNamed:@"tile_licenseplate_eu"] - viewController:[ALLicensePlateViewController class]]; - ALExample *licensePlateUS = [[ALExample alloc] initWithName:NSLocalizedString(@"US License plate", nil) - image:[UIImage imageNamed:@"tile_licenseplate_us"] - viewController:[ALUSLicensePlateViewController class]]; - ALExample *licensePlateAF = [[ALExample alloc] initWithName:NSLocalizedString(@"African License plate", nil) + image:[UIImage imageNamed:@"tile_licenseplate_eu"] + viewController:[ALLicensePlateScanViewController class] + title:@"EU License Plate"]; + ALExample *licensePlateUS = [[ALExample alloc] initWithName:NSLocalizedString(@"US License Plate", nil) + image:[UIImage imageNamed:@"tile_licenseplate_us"] + viewController:[ALLicensePlateScanViewController class] + title:@"US License Plate"]; + ALExample *licensePlateAF = [[ALExample alloc] initWithName:NSLocalizedString(@"African License Plate", nil) image:[UIImage imageNamed:@"tile_licenseplate_af"] - viewController:[ALAFLicensePlateViewController class]]; + viewController:[ALLicensePlateScanViewController class] + title:@"African License Plate"]; self.sectionNames = @[@"License Plate"]; self.examples = [@{ - self.sectionNames[0] : @[licensePlateEU, licensePlateUS, licensePlateAF], + self.sectionNames[0] : @[ licensePlateEU, licensePlateUS, licensePlateAF ], } mutableCopy]; } diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALMROExampleManager.m b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALMROExampleManager.m index 409c045f5..1c18420bc 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALMROExampleManager.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALMROExampleManager.m @@ -11,8 +11,7 @@ #import "ALUniversalSerialNumberScanViewController.h" #import "ALVINScanViewController.h" #import "ALContainerScanViewController.h" -#import "ALVerticalContainerScanViewController.h" -#import "ALVehicleRegistrationCertificateViewController.h" +#import "ALVRCScanViewController.h" NSString * const kVehicleRegistrationCertificate = @"Vehicle Registration Certificate"; @@ -54,9 +53,9 @@ - (void)initExampleData { viewController:[CommercialTireIdViewController class] title:@"Commercial Tire Identification Number"]; ALExample *vehicleRegistrationCertificate = [[ALExample alloc] initWithName:NSLocalizedString(kVehicleRegistrationCertificate, nil) - image:[UIImage imageNamed:@""] - viewController:[ALVehicleRegistrationCertificateViewController class] - title:kVehicleRegistrationCertificate]; + image:[UIImage imageNamed:@"vrc"] + viewController:[ALVRCScanViewController class] + title:kVehicleRegistrationCertificate]; self.sectionNames = @[@"Vehicle",]; self.examples = @{ diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALMeterExampleManager.m b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALMeterExampleManager.m index 032ce70e7..050d5d9f8 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALMeterExampleManager.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALMeterExampleManager.m @@ -1,20 +1,9 @@ -// -// ALExampleManager.m -// AnylineExamples -// -// Created by Philipp Müller on 21/11/2017. -// Copyright © 2017 Anyline GmbH. All rights reserved. -// - #import "ALMeterExampleManager.h" - -//#import "ALAutoAnalogDigitalMeterScanViewController.h" #import "ALDialMeterScanViewController.h" #import "ALMeterSerialNumberScanViewController.h" #import "CustomerSelfReadingViewController.h" #import "WorkForceViewController.h" -#import "ALParallelMeterScanViewController.h" - +#import "AnylineExamples-Swift.h" @interface ALMeterExampleManager () @@ -36,24 +25,33 @@ - (instancetype)init { - (void)initExampleData { self.title = @"Meter Reading"; - ALExample *autoAnalogDigitalMeterScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Analog / Digital", nil) - image:[UIImage imageNamed:@"analog digital"] - viewController:[ALParallelMeterScanViewController class]]; - ALExample *dialMeterScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Dial", nil) - image:[UIImage imageNamed:@"dial meter"] - viewController:[ALDialMeterScanViewController class]]; + ALExample *analogDigitalMeterScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Analog / Digital", nil) + image:[UIImage imageNamed:@"analog digital"] + viewController:[ALMeterScanViewController class] + title:@"Analog / Digital"]; - ALExample *serialScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Serial Number", nil) - image:[UIImage imageNamed:@"serial number"] - viewController:[ALMeterSerialNumberScanViewController class]]; + ALExample *dialMeterScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Dial", nil) + image:[UIImage imageNamed:@"dial meter"] + viewController:[ALMeterScanViewController class] + title:@"Dial Meter"]; + + // this is merely a parallel meter/barcode scanner, like with Analog/Digital, but using the now-defunct + // ALSerialNumber meter scan mode. + // ALExample *serialScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Serial Number", nil) + // image:[UIImage imageNamed:@"serial number"] + // viewController:[ALMeterSerialNumberScanViewController class] + // title:@"Serial Number"]; - self.sectionNames = @[@"Meter Types"]; + self.sectionNames = @[ @"Meter Types" ]; // TODO: not showing on bundle + self.examples = @{ - self.sectionNames[0] : @[autoAnalogDigitalMeterScanning, - dialMeterScanning, - serialScanning] - }; + self.sectionNames[0] : @[ + analogDigitalMeterScanning, + dialMeterScanning, + // serialScanning + ] + }; } @end diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALOthersExampleManager.m b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALOthersExampleManager.m index 595a2391f..ca198d000 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALOthersExampleManager.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALOthersExampleManager.m @@ -1,27 +1,7 @@ -// -// ALOthersExampleManager.m -// AnylineExamples -// -// Created by Philipp Müller on 21/11/2017. -// Copyright © 2017 Anyline GmbH. All rights reserved. -// - #import "ALOthersExampleManager.h" - -#import "ALMRZScanViewController.h" -#import "ALIBANScanViewController.h" -#import "ALVoucherCodeScanViewController.h" -#import "ALISBNScanViewController.h" -#import "ALRecordNumberScanViewController.h" -#import "ALRBScanViewController.h" -#import "ALScrabbleScanViewController.h" -#import "ALDocumentScanViewController.h" #import "ALUniversalSerialNumberScanViewController.h" -#import "ALVINScanViewController.h" -#import "ALCattleTagScanViewController.h" #import "ALContainerScanViewController.h" -#import "ALVerticalContainerScanViewController.h" -#import "ALParallelMeterWithJSONScanViewController.h" +#import "ALBottlecapScanViewController.h" @interface ALOthersExampleManager () @@ -52,52 +32,22 @@ - (void)initExampleData { ALExample *containerScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Horizontal Shipping Container", nil) image:[UIImage imageNamed:@"container serial numbers"] - viewController:[ALContainerScanViewController class]]; + viewController:[ALContainerScanViewController class] + title:NSLocalizedString(@"Horizontal Shipping Container", nil)]; ALExample *verticalContainerScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Vertical Shipping Container", nil) image:[UIImage imageNamed:@"vertical container scanner"] - viewController:[ALVerticalContainerScanViewController class]]; - - ALExample *ibanScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"IBAN", nil) - image:[UIImage imageNamed:@"iban"] - viewController:[ALIBANScanViewController class]]; - - ALExample *rbScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"RedBull Mobile Collect", nil) - image:[UIImage imageNamed:@"red bull mobile collect"] - viewController:[ALRBScanViewController class]]; - - ALExample *voucherCodeScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Voucher Code", nil) - image:[UIImage imageNamed:@"voucher"] - viewController:[ALVoucherCodeScanViewController class]]; - - ALExample *documentScanner = [[ALExample alloc] initWithName:NSLocalizedString(@"Document Scanner", nil) - image:[UIImage imageNamed:@"document"] - viewController:[ALDocumentScanViewController class]]; - - ALExample *scrabbleScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Scrabble Anagram", nil) - image:[UIImage imageNamed:@"scrabble"] - viewController:[ALScrabbleScanViewController class]]; - - ALExample *recordScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Record Number", nil) - image:[UIImage imageNamed:@"vinyl record number"] - viewController:[ALRecordNumberScanViewController class]]; - - ALExample *isbnScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"ISBN", nil) - image:[UIImage imageNamed:@"isbn"] - viewController:[ALISBNScanViewController class]]; - - ALExample *cattleTagScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Cattle Tag", nil) - image:[UIImage imageNamed:@"cow-tag"] - viewController:[ALCattleTagScanViewController class]]; + viewController:[ALContainerScanViewController class] + title:NSLocalizedString(@"Vertical Shipping Container", nil)]; - ALExample *parallelScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Parallel Scanning (Meter + Barcode)", nil) - image:[UIImage imageNamed:@"parallel-scanning"] - viewController:[ALParallelMeterWithJSONScanViewController class]]; + ALExample *bottleCapScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Pepsi Code", nil) + image:[UIImage imageNamed:@"tile_pepsicode"] + viewController:[ALBottlecapScanViewController class]]; self.sectionNames = @[@"Others",]; self.examples = @{ - self.sectionNames[0] : @[serialNumberScanning, containerScanning, verticalContainerScanning, cattleTagScanning, ibanScanning, rbScanning, voucherCodeScanning, scrabbleScanning, recordScanning, isbnScanning, documentScanner, parallelScanning], + self.sectionNames[0] : @[serialNumberScanning, containerScanning, verticalContainerScanning, bottleCapScanning], }; } diff --git a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALProductExampleManager.m b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALProductExampleManager.m index b00a1b6d8..9cd773d54 100644 --- a/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALProductExampleManager.m +++ b/AnylineExamples/Anyline Demo App/DemoApp Source/Models/ALProductExampleManager.m @@ -11,7 +11,7 @@ #import "ALAutoAnalogDigitalMeterScanViewController.h" #import "ALDialMeterScanViewController.h" -#import "ALMultiformatBarcodeScanViewController.h" +#import "ALBarcodeScanViewController.h" #import "ALMRZScanViewController.h" #import "ALIBANScanViewController.h" #import "ALVoucherCodeScanViewController.h" @@ -21,7 +21,7 @@ #import "ALScrabbleScanViewController.h" #import "ALDocumentScanViewController.h" -#import "ALLicensePlateViewController.h" +#import "ALLicensePlateScanViewController.h" #import "ALOthersExampleManager.h" #import "ALMeterExampleManager.h" @@ -54,7 +54,7 @@ - (void)initExampleData { ALExample *barcodeScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Barcodes", nil) image:[UIImage imageNamed:@"tile_barcodes"] - viewController:[ALMultiformatBarcodeScanViewController class]]; + viewController:[ALBarcodeScanViewController class]]; ALExample *identityDocuments = [[ALExample alloc] initWithName:NSLocalizedString(@"Identity Documents", nil) image:[UIImage imageNamed:@"tile_identitydocuments"] diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/Settings.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/Settings.imageset/Contents.json new file mode 100644 index 000000000..29f76cfe7 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/Settings.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Settings.pdf", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/Settings.imageset/Settings.pdf b/AnylineExamples/Anyline Demo App/Images.xcassets/Settings.imageset/Settings.pdf new file mode 100644 index 000000000..e8b956ecd Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/Settings.imageset/Settings.pdf differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/100scan.imageset/100scan.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/100scan.imageset/100scan.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/100scan.imageset/100scan.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/100scan.imageset/100scan.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/100scan.imageset/100scan@2x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/100scan.imageset/100scan@2x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/100scan.imageset/100scan@2x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/100scan.imageset/100scan@2x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/100scan.imageset/100scan@3x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/100scan.imageset/100scan@3x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/100scan.imageset/100scan@3x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/100scan.imageset/100scan@3x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/100scan.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/100scan.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/100scan.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/100scan.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/10scan.imageset/10scan.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/10scan.imageset/10scan.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/10scan.imageset/10scan.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/10scan.imageset/10scan.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/10scan.imageset/10scan@2x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/10scan.imageset/10scan@2x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/10scan.imageset/10scan@2x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/10scan.imageset/10scan@2x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/10scan.imageset/10scan@3x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/10scan.imageset/10scan@3x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/10scan.imageset/10scan@3x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/10scan.imageset/10scan@3x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/10scan.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/10scan.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/10scan.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/10scan.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/1scan.imageset/1scan.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/1scan.imageset/1scan.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/1scan.imageset/1scan.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/1scan.imageset/1scan.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/1scan.imageset/1scan@2x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/1scan.imageset/1scan@2x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/1scan.imageset/1scan@2x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/1scan.imageset/1scan@2x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/1scan.imageset/1scan@3x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/1scan.imageset/1scan@3x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/1scan.imageset/1scan@3x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/1scan.imageset/1scan@3x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/1scan.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/1scan.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/1scan.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/1scan.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/30scan.imageset/30scan.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/30scan.imageset/30scan.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/30scan.imageset/30scan.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/30scan.imageset/30scan.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/30scan.imageset/30scan@2x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/30scan.imageset/30scan@2x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/30scan.imageset/30scan@2x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/30scan.imageset/30scan@2x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/30scan.imageset/30scan@3x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/30scan.imageset/30scan@3x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/30scan.imageset/30scan@3x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/30scan.imageset/30scan@3x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/30scan.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/30scan.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/30scan.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/30scan.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/50scan.imageset/50scan.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/50scan.imageset/50scan.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/50scan.imageset/50scan.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/50scan.imageset/50scan.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/50scan.imageset/50scan@2x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/50scan.imageset/50scan@2x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/50scan.imageset/50scan@2x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/50scan.imageset/50scan@2x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/50scan.imageset/50scan@3x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/50scan.imageset/50scan@3x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/50scan.imageset/50scan@3x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/50scan.imageset/50scan@3x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/50scan.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/50scan.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/50scan.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/50scan.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/80scan.imageset/80scan.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/80scan.imageset/80scan.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/80scan.imageset/80scan.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/80scan.imageset/80scan.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/80scan.imageset/80scan@2x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/80scan.imageset/80scan@2x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/80scan.imageset/80scan@2x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/80scan.imageset/80scan@2x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/80scan.imageset/80scan@3x.png b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/80scan.imageset/80scan@3x.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/80scan.imageset/80scan@3x.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/80scan.imageset/80scan@3x.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/80scan.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/80scan.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/80scan.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/awards/80scan.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/awards/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/awards/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-0.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-0.imageset/Contents.json new file mode 100644 index 000000000..a5fb2b023 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-0.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-0.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-0.imageset/flip-id-0.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-0.imageset/flip-id-0.png new file mode 100644 index 000000000..69c402751 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-0.imageset/flip-id-0.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-1.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-1.imageset/Contents.json new file mode 100644 index 000000000..8a6aee5a4 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-1.imageset/flip-id-1.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-1.imageset/flip-id-1.png new file mode 100644 index 000000000..dbae5ccce Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-1.imageset/flip-id-1.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-10.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-10.imageset/Contents.json new file mode 100644 index 000000000..1fb0f36aa --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-10.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-10.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-10.imageset/flip-id-10.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-10.imageset/flip-id-10.png new file mode 100644 index 000000000..7a1c06dcd Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-10.imageset/flip-id-10.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-100.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-100.imageset/Contents.json new file mode 100644 index 000000000..571a4ac24 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-100.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-100.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-100.imageset/flip-id-100.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-100.imageset/flip-id-100.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-100.imageset/flip-id-100.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-101.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-101.imageset/Contents.json new file mode 100644 index 000000000..af2be86c1 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-101.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-101.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-101.imageset/flip-id-101.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-101.imageset/flip-id-101.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-101.imageset/flip-id-101.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-102.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-102.imageset/Contents.json new file mode 100644 index 000000000..dadfca437 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-102.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-102.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-102.imageset/flip-id-102.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-102.imageset/flip-id-102.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-102.imageset/flip-id-102.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-103.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-103.imageset/Contents.json new file mode 100644 index 000000000..06af6df47 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-103.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-103.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-103.imageset/flip-id-103.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-103.imageset/flip-id-103.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-103.imageset/flip-id-103.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-104.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-104.imageset/Contents.json new file mode 100644 index 000000000..7d8aa9c28 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-104.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-104.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-104.imageset/flip-id-104.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-104.imageset/flip-id-104.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-104.imageset/flip-id-104.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-105.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-105.imageset/Contents.json new file mode 100644 index 000000000..855a909e2 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-105.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-105.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-105.imageset/flip-id-105.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-105.imageset/flip-id-105.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-105.imageset/flip-id-105.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-106.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-106.imageset/Contents.json new file mode 100644 index 000000000..3e2f07b37 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-106.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-106.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-106.imageset/flip-id-106.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-106.imageset/flip-id-106.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-106.imageset/flip-id-106.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-107.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-107.imageset/Contents.json new file mode 100644 index 000000000..51c899bed --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-107.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-107.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-107.imageset/flip-id-107.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-107.imageset/flip-id-107.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-107.imageset/flip-id-107.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-108.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-108.imageset/Contents.json new file mode 100644 index 000000000..1ab91361a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-108.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-108.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-108.imageset/flip-id-108.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-108.imageset/flip-id-108.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-108.imageset/flip-id-108.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-109.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-109.imageset/Contents.json new file mode 100644 index 000000000..6f3463139 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-109.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-109.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-109.imageset/flip-id-109.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-109.imageset/flip-id-109.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-109.imageset/flip-id-109.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-11.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-11.imageset/Contents.json new file mode 100644 index 000000000..2a2e98398 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-11.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-11.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-11.imageset/flip-id-11.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-11.imageset/flip-id-11.png new file mode 100644 index 000000000..540d95930 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-11.imageset/flip-id-11.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-110.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-110.imageset/Contents.json new file mode 100644 index 000000000..119983f67 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-110.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-110.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-110.imageset/flip-id-110.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-110.imageset/flip-id-110.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-110.imageset/flip-id-110.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-111.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-111.imageset/Contents.json new file mode 100644 index 000000000..7d3d22641 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-111.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-111.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-111.imageset/flip-id-111.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-111.imageset/flip-id-111.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-111.imageset/flip-id-111.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-112.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-112.imageset/Contents.json new file mode 100644 index 000000000..b415ff44e --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-112.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-112.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-112.imageset/flip-id-112.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-112.imageset/flip-id-112.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-112.imageset/flip-id-112.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-113.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-113.imageset/Contents.json new file mode 100644 index 000000000..033c3d2d4 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-113.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-113.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-113.imageset/flip-id-113.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-113.imageset/flip-id-113.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-113.imageset/flip-id-113.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-114.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-114.imageset/Contents.json new file mode 100644 index 000000000..24677ea9c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-114.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-114.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-114.imageset/flip-id-114.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-114.imageset/flip-id-114.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-114.imageset/flip-id-114.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-115.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-115.imageset/Contents.json new file mode 100644 index 000000000..bafce0d18 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-115.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-115.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-115.imageset/flip-id-115.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-115.imageset/flip-id-115.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-115.imageset/flip-id-115.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-116.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-116.imageset/Contents.json new file mode 100644 index 000000000..4a971dc15 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-116.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-116.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-116.imageset/flip-id-116.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-116.imageset/flip-id-116.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-116.imageset/flip-id-116.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-117.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-117.imageset/Contents.json new file mode 100644 index 000000000..edcda1871 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-117.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-117.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-117.imageset/flip-id-117.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-117.imageset/flip-id-117.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-117.imageset/flip-id-117.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-118.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-118.imageset/Contents.json new file mode 100644 index 000000000..1abd7cbbb --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-118.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-118.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-118.imageset/flip-id-118.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-118.imageset/flip-id-118.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-118.imageset/flip-id-118.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-119.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-119.imageset/Contents.json new file mode 100644 index 000000000..b219ebb30 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-119.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-119.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-119.imageset/flip-id-119.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-119.imageset/flip-id-119.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-119.imageset/flip-id-119.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-12.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-12.imageset/Contents.json new file mode 100644 index 000000000..724c1d372 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-12.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-12.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-12.imageset/flip-id-12.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-12.imageset/flip-id-12.png new file mode 100644 index 000000000..4a8f429b9 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-12.imageset/flip-id-12.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-120.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-120.imageset/Contents.json new file mode 100644 index 000000000..d4f9dbf4a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-120.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-120.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-120.imageset/flip-id-120.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-120.imageset/flip-id-120.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-120.imageset/flip-id-120.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-121.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-121.imageset/Contents.json new file mode 100644 index 000000000..50853e60b --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-121.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-121.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-121.imageset/flip-id-121.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-121.imageset/flip-id-121.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-121.imageset/flip-id-121.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-122.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-122.imageset/Contents.json new file mode 100644 index 000000000..700149ee8 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-122.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-122.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-122.imageset/flip-id-122.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-122.imageset/flip-id-122.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-122.imageset/flip-id-122.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-123.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-123.imageset/Contents.json new file mode 100644 index 000000000..2e8e2d2dd --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-123.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-123.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-123.imageset/flip-id-123.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-123.imageset/flip-id-123.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-123.imageset/flip-id-123.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-124.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-124.imageset/Contents.json new file mode 100644 index 000000000..17221c66c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-124.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-124.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-124.imageset/flip-id-124.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-124.imageset/flip-id-124.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-124.imageset/flip-id-124.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-125.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-125.imageset/Contents.json new file mode 100644 index 000000000..f9f8cb098 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-125.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-125.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-125.imageset/flip-id-125.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-125.imageset/flip-id-125.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-125.imageset/flip-id-125.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-126.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-126.imageset/Contents.json new file mode 100644 index 000000000..f98d96eb7 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-126.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-126.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-126.imageset/flip-id-126.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-126.imageset/flip-id-126.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-126.imageset/flip-id-126.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-127.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-127.imageset/Contents.json new file mode 100644 index 000000000..058cad985 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-127.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-127.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-127.imageset/flip-id-127.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-127.imageset/flip-id-127.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-127.imageset/flip-id-127.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-128.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-128.imageset/Contents.json new file mode 100644 index 000000000..ea83acb29 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-128.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-128.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-128.imageset/flip-id-128.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-128.imageset/flip-id-128.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-128.imageset/flip-id-128.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-129.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-129.imageset/Contents.json new file mode 100644 index 000000000..426a83975 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-129.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-129.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-129.imageset/flip-id-129.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-129.imageset/flip-id-129.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-129.imageset/flip-id-129.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-13.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-13.imageset/Contents.json new file mode 100644 index 000000000..3fab0d79f --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-13.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-13.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-13.imageset/flip-id-13.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-13.imageset/flip-id-13.png new file mode 100644 index 000000000..0a2eea6db Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-13.imageset/flip-id-13.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-130.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-130.imageset/Contents.json new file mode 100644 index 000000000..2ec23ca06 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-130.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-130.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-130.imageset/flip-id-130.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-130.imageset/flip-id-130.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-130.imageset/flip-id-130.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-131.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-131.imageset/Contents.json new file mode 100644 index 000000000..485040793 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-131.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-131.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-131.imageset/flip-id-131.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-131.imageset/flip-id-131.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-131.imageset/flip-id-131.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-132.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-132.imageset/Contents.json new file mode 100644 index 000000000..d5ea5f57d --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-132.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-132.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-132.imageset/flip-id-132.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-132.imageset/flip-id-132.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-132.imageset/flip-id-132.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-133.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-133.imageset/Contents.json new file mode 100644 index 000000000..5476ee78b --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-133.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-133.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-133.imageset/flip-id-133.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-133.imageset/flip-id-133.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-133.imageset/flip-id-133.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-134.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-134.imageset/Contents.json new file mode 100644 index 000000000..e2188a34e --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-134.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-134.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-134.imageset/flip-id-134.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-134.imageset/flip-id-134.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-134.imageset/flip-id-134.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-135.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-135.imageset/Contents.json new file mode 100644 index 000000000..e4979ac38 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-135.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-135.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-135.imageset/flip-id-135.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-135.imageset/flip-id-135.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-135.imageset/flip-id-135.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-136.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-136.imageset/Contents.json new file mode 100644 index 000000000..428561dfe --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-136.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-136.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-136.imageset/flip-id-136.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-136.imageset/flip-id-136.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-136.imageset/flip-id-136.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-137.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-137.imageset/Contents.json new file mode 100644 index 000000000..d31abaec5 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-137.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-137.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-137.imageset/flip-id-137.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-137.imageset/flip-id-137.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-137.imageset/flip-id-137.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-138.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-138.imageset/Contents.json new file mode 100644 index 000000000..cfeb040d9 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-138.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-138.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-138.imageset/flip-id-138.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-138.imageset/flip-id-138.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-138.imageset/flip-id-138.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-139.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-139.imageset/Contents.json new file mode 100644 index 000000000..834638f84 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-139.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-139.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-139.imageset/flip-id-139.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-139.imageset/flip-id-139.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-139.imageset/flip-id-139.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-14.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-14.imageset/Contents.json new file mode 100644 index 000000000..9fda5c380 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-14.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-14.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-14.imageset/flip-id-14.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-14.imageset/flip-id-14.png new file mode 100644 index 000000000..8f3124082 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-14.imageset/flip-id-14.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-140.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-140.imageset/Contents.json new file mode 100644 index 000000000..021699f71 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-140.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-140.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-140.imageset/flip-id-140.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-140.imageset/flip-id-140.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-140.imageset/flip-id-140.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-141.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-141.imageset/Contents.json new file mode 100644 index 000000000..4dc2f33f3 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-141.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-141.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-141.imageset/flip-id-141.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-141.imageset/flip-id-141.png new file mode 100644 index 000000000..e5a7ee52f Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-141.imageset/flip-id-141.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-142.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-142.imageset/Contents.json new file mode 100644 index 000000000..795ab0422 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-142.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-142.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-142.imageset/flip-id-142.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-142.imageset/flip-id-142.png new file mode 100644 index 000000000..ee61cb898 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-142.imageset/flip-id-142.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-143.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-143.imageset/Contents.json new file mode 100644 index 000000000..fde57d38b --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-143.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-143.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-143.imageset/flip-id-143.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-143.imageset/flip-id-143.png new file mode 100644 index 000000000..1d6c2ab48 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-143.imageset/flip-id-143.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-144.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-144.imageset/Contents.json new file mode 100644 index 000000000..465c60371 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-144.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-144.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-144.imageset/flip-id-144.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-144.imageset/flip-id-144.png new file mode 100644 index 000000000..097c7999c Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-144.imageset/flip-id-144.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-145.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-145.imageset/Contents.json new file mode 100644 index 000000000..13c5eb388 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-145.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-145.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-145.imageset/flip-id-145.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-145.imageset/flip-id-145.png new file mode 100644 index 000000000..02f8cef3f Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-145.imageset/flip-id-145.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-146.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-146.imageset/Contents.json new file mode 100644 index 000000000..c817e8031 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-146.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-146.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-146.imageset/flip-id-146.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-146.imageset/flip-id-146.png new file mode 100644 index 000000000..625307aae Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-146.imageset/flip-id-146.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-147.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-147.imageset/Contents.json new file mode 100644 index 000000000..d1907c9ed --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-147.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-147.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-147.imageset/flip-id-147.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-147.imageset/flip-id-147.png new file mode 100644 index 000000000..8fc860e95 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-147.imageset/flip-id-147.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-148.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-148.imageset/Contents.json new file mode 100644 index 000000000..86eaf117b --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-148.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-148.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-148.imageset/flip-id-148.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-148.imageset/flip-id-148.png new file mode 100644 index 000000000..a4caf65de Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-148.imageset/flip-id-148.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-149.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-149.imageset/Contents.json new file mode 100644 index 000000000..11eb79a30 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-149.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-149.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-149.imageset/flip-id-149.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-149.imageset/flip-id-149.png new file mode 100644 index 000000000..411cf0a8e Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-149.imageset/flip-id-149.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-15.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-15.imageset/Contents.json new file mode 100644 index 000000000..38d09016f --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-15.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-15.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-15.imageset/flip-id-15.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-15.imageset/flip-id-15.png new file mode 100644 index 000000000..1700bf76c Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-15.imageset/flip-id-15.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-150.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-150.imageset/Contents.json new file mode 100644 index 000000000..9de5ac460 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-150.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-150.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-150.imageset/flip-id-150.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-150.imageset/flip-id-150.png new file mode 100644 index 000000000..2a79a4c72 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-150.imageset/flip-id-150.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-16.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-16.imageset/Contents.json new file mode 100644 index 000000000..23a1cc282 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-16.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-16.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-16.imageset/flip-id-16.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-16.imageset/flip-id-16.png new file mode 100644 index 000000000..f9fb53d00 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-16.imageset/flip-id-16.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-17.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-17.imageset/Contents.json new file mode 100644 index 000000000..c3a75a467 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-17.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-17.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-17.imageset/flip-id-17.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-17.imageset/flip-id-17.png new file mode 100644 index 000000000..337ff5533 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-17.imageset/flip-id-17.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-18.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-18.imageset/Contents.json new file mode 100644 index 000000000..ecc8d7a34 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-18.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-18.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-18.imageset/flip-id-18.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-18.imageset/flip-id-18.png new file mode 100644 index 000000000..c6f2d3a38 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-18.imageset/flip-id-18.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-19.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-19.imageset/Contents.json new file mode 100644 index 000000000..a3113f02b --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-19.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-19.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-19.imageset/flip-id-19.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-19.imageset/flip-id-19.png new file mode 100644 index 000000000..00fc95228 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-19.imageset/flip-id-19.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-2.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-2.imageset/Contents.json new file mode 100644 index 000000000..9a5952307 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-2.imageset/flip-id-2.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-2.imageset/flip-id-2.png new file mode 100644 index 000000000..0a7c1a5cf Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-2.imageset/flip-id-2.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-20.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-20.imageset/Contents.json new file mode 100644 index 000000000..9ec40db0c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-20.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-20.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-20.imageset/flip-id-20.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-20.imageset/flip-id-20.png new file mode 100644 index 000000000..8745a826b Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-20.imageset/flip-id-20.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-21.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-21.imageset/Contents.json new file mode 100644 index 000000000..5f8b0bad4 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-21.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-21.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-21.imageset/flip-id-21.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-21.imageset/flip-id-21.png new file mode 100644 index 000000000..35a7eb057 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-21.imageset/flip-id-21.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-22.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-22.imageset/Contents.json new file mode 100644 index 000000000..6ea3a6328 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-22.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-22.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-22.imageset/flip-id-22.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-22.imageset/flip-id-22.png new file mode 100644 index 000000000..48af3fcc1 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-22.imageset/flip-id-22.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-23.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-23.imageset/Contents.json new file mode 100644 index 000000000..ef9a35cda --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-23.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-23.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-23.imageset/flip-id-23.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-23.imageset/flip-id-23.png new file mode 100644 index 000000000..34e3a9098 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-23.imageset/flip-id-23.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-24.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-24.imageset/Contents.json new file mode 100644 index 000000000..922b90859 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-24.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-24.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-24.imageset/flip-id-24.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-24.imageset/flip-id-24.png new file mode 100644 index 000000000..70514a2bd Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-24.imageset/flip-id-24.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-25.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-25.imageset/Contents.json new file mode 100644 index 000000000..78f60b79d --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-25.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-25.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-25.imageset/flip-id-25.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-25.imageset/flip-id-25.png new file mode 100644 index 000000000..d8e7864e2 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-25.imageset/flip-id-25.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-26.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-26.imageset/Contents.json new file mode 100644 index 000000000..ba887fe4c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-26.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-26.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-26.imageset/flip-id-26.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-26.imageset/flip-id-26.png new file mode 100644 index 000000000..77c279611 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-26.imageset/flip-id-26.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-27.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-27.imageset/Contents.json new file mode 100644 index 000000000..dc018fb16 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-27.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-27.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-27.imageset/flip-id-27.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-27.imageset/flip-id-27.png new file mode 100644 index 000000000..be862fadf Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-27.imageset/flip-id-27.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-28.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-28.imageset/Contents.json new file mode 100644 index 000000000..0709021ef --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-28.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-28.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-28.imageset/flip-id-28.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-28.imageset/flip-id-28.png new file mode 100644 index 000000000..eeafb3f1b Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-28.imageset/flip-id-28.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-29.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-29.imageset/Contents.json new file mode 100644 index 000000000..3d85af197 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-29.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-29.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-29.imageset/flip-id-29.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-29.imageset/flip-id-29.png new file mode 100644 index 000000000..53449d8c8 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-29.imageset/flip-id-29.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-3.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-3.imageset/Contents.json new file mode 100644 index 000000000..5a6778ef8 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-3.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-3.imageset/flip-id-3.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-3.imageset/flip-id-3.png new file mode 100644 index 000000000..2cb497f91 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-3.imageset/flip-id-3.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-30.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-30.imageset/Contents.json new file mode 100644 index 000000000..95a3d957b --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-30.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-30.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-30.imageset/flip-id-30.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-30.imageset/flip-id-30.png new file mode 100644 index 000000000..9a3407704 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-30.imageset/flip-id-30.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-31.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-31.imageset/Contents.json new file mode 100644 index 000000000..1d2f3196d --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-31.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-31.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-31.imageset/flip-id-31.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-31.imageset/flip-id-31.png new file mode 100644 index 000000000..17e1f024d Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-31.imageset/flip-id-31.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-32.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-32.imageset/Contents.json new file mode 100644 index 000000000..51594cdb5 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-32.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-32.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-32.imageset/flip-id-32.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-32.imageset/flip-id-32.png new file mode 100644 index 000000000..1eff9e1f9 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-32.imageset/flip-id-32.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-33.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-33.imageset/Contents.json new file mode 100644 index 000000000..a65b87f36 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-33.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-33.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-33.imageset/flip-id-33.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-33.imageset/flip-id-33.png new file mode 100644 index 000000000..d60ecd887 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-33.imageset/flip-id-33.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-34.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-34.imageset/Contents.json new file mode 100644 index 000000000..1335723d1 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-34.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-34.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-34.imageset/flip-id-34.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-34.imageset/flip-id-34.png new file mode 100644 index 000000000..f0ae18f14 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-34.imageset/flip-id-34.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-35.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-35.imageset/Contents.json new file mode 100644 index 000000000..9d26577a4 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-35.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-35.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-35.imageset/flip-id-35.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-35.imageset/flip-id-35.png new file mode 100644 index 000000000..1cef89abb Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-35.imageset/flip-id-35.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-36.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-36.imageset/Contents.json new file mode 100644 index 000000000..f60ee3add --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-36.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-36.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-36.imageset/flip-id-36.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-36.imageset/flip-id-36.png new file mode 100644 index 000000000..64e1c959d Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-36.imageset/flip-id-36.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-37.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-37.imageset/Contents.json new file mode 100644 index 000000000..102f5dd1d --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-37.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-37.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-37.imageset/flip-id-37.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-37.imageset/flip-id-37.png new file mode 100644 index 000000000..860e482f7 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-37.imageset/flip-id-37.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-38.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-38.imageset/Contents.json new file mode 100644 index 000000000..db64cb71d --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-38.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-38.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-38.imageset/flip-id-38.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-38.imageset/flip-id-38.png new file mode 100644 index 000000000..f0eb66288 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-38.imageset/flip-id-38.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-39.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-39.imageset/Contents.json new file mode 100644 index 000000000..9dd3e3e8e --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-39.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-39.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-39.imageset/flip-id-39.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-39.imageset/flip-id-39.png new file mode 100644 index 000000000..2bbff36b6 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-39.imageset/flip-id-39.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-4.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-4.imageset/Contents.json new file mode 100644 index 000000000..44d059151 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-4.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-4.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-4.imageset/flip-id-4.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-4.imageset/flip-id-4.png new file mode 100644 index 000000000..9121c97dd Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-4.imageset/flip-id-4.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-40.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-40.imageset/Contents.json new file mode 100644 index 000000000..e56558b05 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-40.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-40.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-40.imageset/flip-id-40.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-40.imageset/flip-id-40.png new file mode 100644 index 000000000..acb95e116 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-40.imageset/flip-id-40.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-41.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-41.imageset/Contents.json new file mode 100644 index 000000000..fc3d409d1 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-41.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-41.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-41.imageset/flip-id-41.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-41.imageset/flip-id-41.png new file mode 100644 index 000000000..1b4bf1fcd Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-41.imageset/flip-id-41.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-42.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-42.imageset/Contents.json new file mode 100644 index 000000000..8987a84a8 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-42.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-42.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-42.imageset/flip-id-42.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-42.imageset/flip-id-42.png new file mode 100644 index 000000000..3603bc566 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-42.imageset/flip-id-42.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-43.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-43.imageset/Contents.json new file mode 100644 index 000000000..2c046f909 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-43.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-43.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-43.imageset/flip-id-43.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-43.imageset/flip-id-43.png new file mode 100644 index 000000000..0f1dfe2be Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-43.imageset/flip-id-43.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-44.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-44.imageset/Contents.json new file mode 100644 index 000000000..f0e68c298 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-44.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-44.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-44.imageset/flip-id-44.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-44.imageset/flip-id-44.png new file mode 100644 index 000000000..aeaeaba3b Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-44.imageset/flip-id-44.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-45.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-45.imageset/Contents.json new file mode 100644 index 000000000..83ed4777e --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-45.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-45.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-45.imageset/flip-id-45.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-45.imageset/flip-id-45.png new file mode 100644 index 000000000..2c9f07fa6 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-45.imageset/flip-id-45.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-46.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-46.imageset/Contents.json new file mode 100644 index 000000000..ac5f7b55a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-46.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-46.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-46.imageset/flip-id-46.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-46.imageset/flip-id-46.png new file mode 100644 index 000000000..8084b7c15 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-46.imageset/flip-id-46.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-47.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-47.imageset/Contents.json new file mode 100644 index 000000000..b567a3a23 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-47.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-47.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-47.imageset/flip-id-47.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-47.imageset/flip-id-47.png new file mode 100644 index 000000000..571558b23 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-47.imageset/flip-id-47.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-48.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-48.imageset/Contents.json new file mode 100644 index 000000000..a14da4e11 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-48.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-48.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-48.imageset/flip-id-48.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-48.imageset/flip-id-48.png new file mode 100644 index 000000000..33543da42 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-48.imageset/flip-id-48.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-49.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-49.imageset/Contents.json new file mode 100644 index 000000000..8b4a10d67 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-49.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-49.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-49.imageset/flip-id-49.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-49.imageset/flip-id-49.png new file mode 100644 index 000000000..7984003f5 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-49.imageset/flip-id-49.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-5.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-5.imageset/Contents.json new file mode 100644 index 000000000..80773504c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-5.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-5.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-5.imageset/flip-id-5.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-5.imageset/flip-id-5.png new file mode 100644 index 000000000..15515d8f1 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-5.imageset/flip-id-5.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-50.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-50.imageset/Contents.json new file mode 100644 index 000000000..8c3a8f63b --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-50.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-50.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-50.imageset/flip-id-50.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-50.imageset/flip-id-50.png new file mode 100644 index 000000000..663cacee2 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-50.imageset/flip-id-50.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-51.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-51.imageset/Contents.json new file mode 100644 index 000000000..002cb6e10 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-51.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-51.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-51.imageset/flip-id-51.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-51.imageset/flip-id-51.png new file mode 100644 index 000000000..645b0343e Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-51.imageset/flip-id-51.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-52.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-52.imageset/Contents.json new file mode 100644 index 000000000..2ed8bb255 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-52.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-52.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-52.imageset/flip-id-52.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-52.imageset/flip-id-52.png new file mode 100644 index 000000000..25e434c3c Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-52.imageset/flip-id-52.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-53.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-53.imageset/Contents.json new file mode 100644 index 000000000..70faf6139 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-53.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-53.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-53.imageset/flip-id-53.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-53.imageset/flip-id-53.png new file mode 100644 index 000000000..bc36a116e Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-53.imageset/flip-id-53.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-54.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-54.imageset/Contents.json new file mode 100644 index 000000000..d2b93ee2d --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-54.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-54.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-54.imageset/flip-id-54.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-54.imageset/flip-id-54.png new file mode 100644 index 000000000..98ee0c49b Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-54.imageset/flip-id-54.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-55.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-55.imageset/Contents.json new file mode 100644 index 000000000..620d442df --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-55.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-55.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-55.imageset/flip-id-55.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-55.imageset/flip-id-55.png new file mode 100644 index 000000000..daf8704eb Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-55.imageset/flip-id-55.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-56.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-56.imageset/Contents.json new file mode 100644 index 000000000..c8a3c1092 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-56.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-56.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-56.imageset/flip-id-56.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-56.imageset/flip-id-56.png new file mode 100644 index 000000000..d119a105a Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-56.imageset/flip-id-56.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-57.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-57.imageset/Contents.json new file mode 100644 index 000000000..4c15da975 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-57.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-57.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-57.imageset/flip-id-57.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-57.imageset/flip-id-57.png new file mode 100644 index 000000000..c1d84f1a5 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-57.imageset/flip-id-57.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-58.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-58.imageset/Contents.json new file mode 100644 index 000000000..c62eec3c6 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-58.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-58.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-58.imageset/flip-id-58.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-58.imageset/flip-id-58.png new file mode 100644 index 000000000..5258f1635 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-58.imageset/flip-id-58.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-59.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-59.imageset/Contents.json new file mode 100644 index 000000000..6e5a5e5e0 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-59.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-59.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-59.imageset/flip-id-59.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-59.imageset/flip-id-59.png new file mode 100644 index 000000000..1a2166a53 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-59.imageset/flip-id-59.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-6.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-6.imageset/Contents.json new file mode 100644 index 000000000..44df52111 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-6.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-6.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-6.imageset/flip-id-6.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-6.imageset/flip-id-6.png new file mode 100644 index 000000000..2622fc5e2 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-6.imageset/flip-id-6.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-60.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-60.imageset/Contents.json new file mode 100644 index 000000000..b1b0dc259 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-60.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-60.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-60.imageset/flip-id-60.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-60.imageset/flip-id-60.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-60.imageset/flip-id-60.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-61.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-61.imageset/Contents.json new file mode 100644 index 000000000..7fd6dd411 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-61.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-61.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-61.imageset/flip-id-61.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-61.imageset/flip-id-61.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-61.imageset/flip-id-61.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-62.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-62.imageset/Contents.json new file mode 100644 index 000000000..2e2dd0849 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-62.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-62.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-62.imageset/flip-id-62.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-62.imageset/flip-id-62.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-62.imageset/flip-id-62.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-63.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-63.imageset/Contents.json new file mode 100644 index 000000000..f6c3def0c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-63.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-63.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-63.imageset/flip-id-63.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-63.imageset/flip-id-63.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-63.imageset/flip-id-63.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-64.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-64.imageset/Contents.json new file mode 100644 index 000000000..30caec3af --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-64.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-64.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-64.imageset/flip-id-64.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-64.imageset/flip-id-64.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-64.imageset/flip-id-64.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-65.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-65.imageset/Contents.json new file mode 100644 index 000000000..e5ead6df6 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-65.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-65.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-65.imageset/flip-id-65.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-65.imageset/flip-id-65.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-65.imageset/flip-id-65.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-66.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-66.imageset/Contents.json new file mode 100644 index 000000000..56733219a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-66.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-66.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-66.imageset/flip-id-66.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-66.imageset/flip-id-66.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-66.imageset/flip-id-66.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-67.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-67.imageset/Contents.json new file mode 100644 index 000000000..08c0df4af --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-67.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-67.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-67.imageset/flip-id-67.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-67.imageset/flip-id-67.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-67.imageset/flip-id-67.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-68.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-68.imageset/Contents.json new file mode 100644 index 000000000..ddf73325c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-68.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-68.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-68.imageset/flip-id-68.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-68.imageset/flip-id-68.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-68.imageset/flip-id-68.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-69.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-69.imageset/Contents.json new file mode 100644 index 000000000..331940fab --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-69.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-69.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-69.imageset/flip-id-69.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-69.imageset/flip-id-69.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-69.imageset/flip-id-69.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-7.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-7.imageset/Contents.json new file mode 100644 index 000000000..826087f18 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-7.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-7.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-7.imageset/flip-id-7.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-7.imageset/flip-id-7.png new file mode 100644 index 000000000..c67f216e2 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-7.imageset/flip-id-7.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-70.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-70.imageset/Contents.json new file mode 100644 index 000000000..0af0c40b0 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-70.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-70.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-70.imageset/flip-id-70.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-70.imageset/flip-id-70.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-70.imageset/flip-id-70.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-71.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-71.imageset/Contents.json new file mode 100644 index 000000000..c60971bca --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-71.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-71.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-71.imageset/flip-id-71.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-71.imageset/flip-id-71.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-71.imageset/flip-id-71.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-72.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-72.imageset/Contents.json new file mode 100644 index 000000000..d31890c21 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-72.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-72.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-72.imageset/flip-id-72.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-72.imageset/flip-id-72.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-72.imageset/flip-id-72.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-73.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-73.imageset/Contents.json new file mode 100644 index 000000000..e64fff043 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-73.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-73.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-73.imageset/flip-id-73.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-73.imageset/flip-id-73.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-73.imageset/flip-id-73.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-74.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-74.imageset/Contents.json new file mode 100644 index 000000000..ee3149774 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-74.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-74.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-74.imageset/flip-id-74.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-74.imageset/flip-id-74.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-74.imageset/flip-id-74.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-75.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-75.imageset/Contents.json new file mode 100644 index 000000000..22e2bbca1 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-75.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-75.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-75.imageset/flip-id-75.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-75.imageset/flip-id-75.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-75.imageset/flip-id-75.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-76.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-76.imageset/Contents.json new file mode 100644 index 000000000..b2dc3433c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-76.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-76.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-76.imageset/flip-id-76.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-76.imageset/flip-id-76.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-76.imageset/flip-id-76.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-77.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-77.imageset/Contents.json new file mode 100644 index 000000000..8e2bd4971 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-77.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-77.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-77.imageset/flip-id-77.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-77.imageset/flip-id-77.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-77.imageset/flip-id-77.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-78.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-78.imageset/Contents.json new file mode 100644 index 000000000..9a451f1c1 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-78.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-78.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-78.imageset/flip-id-78.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-78.imageset/flip-id-78.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-78.imageset/flip-id-78.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-79.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-79.imageset/Contents.json new file mode 100644 index 000000000..44f440c53 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-79.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-79.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-79.imageset/flip-id-79.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-79.imageset/flip-id-79.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-79.imageset/flip-id-79.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-8.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-8.imageset/Contents.json new file mode 100644 index 000000000..f791c7a60 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-8.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-8.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-8.imageset/flip-id-8.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-8.imageset/flip-id-8.png new file mode 100644 index 000000000..ddbb9dac9 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-8.imageset/flip-id-8.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-80.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-80.imageset/Contents.json new file mode 100644 index 000000000..93fb79143 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-80.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-80.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-80.imageset/flip-id-80.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-80.imageset/flip-id-80.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-80.imageset/flip-id-80.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-81.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-81.imageset/Contents.json new file mode 100644 index 000000000..739304309 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-81.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-81.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-81.imageset/flip-id-81.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-81.imageset/flip-id-81.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-81.imageset/flip-id-81.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-82.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-82.imageset/Contents.json new file mode 100644 index 000000000..caa226538 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-82.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-82.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-82.imageset/flip-id-82.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-82.imageset/flip-id-82.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-82.imageset/flip-id-82.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-83.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-83.imageset/Contents.json new file mode 100644 index 000000000..68b837e69 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-83.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-83.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-83.imageset/flip-id-83.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-83.imageset/flip-id-83.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-83.imageset/flip-id-83.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-84.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-84.imageset/Contents.json new file mode 100644 index 000000000..22db45c74 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-84.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-84.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-84.imageset/flip-id-84.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-84.imageset/flip-id-84.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-84.imageset/flip-id-84.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-85.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-85.imageset/Contents.json new file mode 100644 index 000000000..005c68161 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-85.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-85.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-85.imageset/flip-id-85.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-85.imageset/flip-id-85.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-85.imageset/flip-id-85.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-86.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-86.imageset/Contents.json new file mode 100644 index 000000000..14c5464ea --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-86.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-86.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-86.imageset/flip-id-86.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-86.imageset/flip-id-86.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-86.imageset/flip-id-86.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-87.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-87.imageset/Contents.json new file mode 100644 index 000000000..5eee62fa4 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-87.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-87.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-87.imageset/flip-id-87.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-87.imageset/flip-id-87.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-87.imageset/flip-id-87.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-88.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-88.imageset/Contents.json new file mode 100644 index 000000000..9d93bbce6 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-88.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-88.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-88.imageset/flip-id-88.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-88.imageset/flip-id-88.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-88.imageset/flip-id-88.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-89.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-89.imageset/Contents.json new file mode 100644 index 000000000..6d96b0293 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-89.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-89.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-89.imageset/flip-id-89.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-89.imageset/flip-id-89.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-89.imageset/flip-id-89.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-9.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-9.imageset/Contents.json new file mode 100644 index 000000000..3b19b185a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-9.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-9.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-9.imageset/flip-id-9.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-9.imageset/flip-id-9.png new file mode 100644 index 000000000..235816414 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-9.imageset/flip-id-9.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-90.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-90.imageset/Contents.json new file mode 100644 index 000000000..5ff93bc2b --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-90.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-90.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-90.imageset/flip-id-90.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-90.imageset/flip-id-90.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-90.imageset/flip-id-90.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-91.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-91.imageset/Contents.json new file mode 100644 index 000000000..c8ba92e19 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-91.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-91.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-91.imageset/flip-id-91.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-91.imageset/flip-id-91.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-91.imageset/flip-id-91.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-92.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-92.imageset/Contents.json new file mode 100644 index 000000000..c06af7e85 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-92.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-92.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-92.imageset/flip-id-92.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-92.imageset/flip-id-92.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-92.imageset/flip-id-92.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-93.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-93.imageset/Contents.json new file mode 100644 index 000000000..926d07c0d --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-93.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-93.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-93.imageset/flip-id-93.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-93.imageset/flip-id-93.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-93.imageset/flip-id-93.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-94.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-94.imageset/Contents.json new file mode 100644 index 000000000..60bb16607 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-94.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-94.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-94.imageset/flip-id-94.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-94.imageset/flip-id-94.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-94.imageset/flip-id-94.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-95.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-95.imageset/Contents.json new file mode 100644 index 000000000..bfcd669fe --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-95.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-95.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-95.imageset/flip-id-95.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-95.imageset/flip-id-95.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-95.imageset/flip-id-95.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-96.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-96.imageset/Contents.json new file mode 100644 index 000000000..b6a08fdf3 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-96.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-96.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-96.imageset/flip-id-96.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-96.imageset/flip-id-96.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-96.imageset/flip-id-96.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-97.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-97.imageset/Contents.json new file mode 100644 index 000000000..e655269cf --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-97.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-97.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-97.imageset/flip-id-97.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-97.imageset/flip-id-97.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-97.imageset/flip-id-97.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-98.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-98.imageset/Contents.json new file mode 100644 index 000000000..047fa6e32 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-98.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-98.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-98.imageset/flip-id-98.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-98.imageset/flip-id-98.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-98.imageset/flip-id-98.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-99.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-99.imageset/Contents.json new file mode 100644 index 000000000..6e3c574b0 --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-99.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "flip-id-99.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-99.imageset/flip-id-99.png b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-99.imageset/flip-id-99.png new file mode 100644 index 000000000..98ee49695 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/flip-id/flip-id-99.imageset/flip-id-99.png differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_barcode.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_barcode.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_barcode.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_barcode.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_barcode.imageset/intro_barcode.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_barcode.imageset/intro_barcode.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_barcode.imageset/intro_barcode.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_barcode.imageset/intro_barcode.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_bottlecap.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_bottlecap.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_bottlecap.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_bottlecap.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_bottlecap.imageset/intro_bottlecap.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_bottlecap.imageset/intro_bottlecap.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_bottlecap.imageset/intro_bottlecap.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_bottlecap.imageset/intro_bottlecap.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_dial_meter.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_dial_meter.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_dial_meter.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_dial_meter.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_dial_meter.imageset/intro_dial_meter.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_dial_meter.imageset/intro_dial_meter.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_dial_meter.imageset/intro_dial_meter.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_dial_meter.imageset/intro_dial_meter.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_digital.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_digital.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_digital.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_digital.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_digital.imageset/intro_digital.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_digital.imageset/intro_digital.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_digital.imageset/intro_digital.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_digital.imageset/intro_digital.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_electric_analog.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_electric_analog.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_electric_analog.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_electric_analog.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_electric_analog.imageset/intro_electric_analog.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_electric_analog.imageset/intro_electric_analog.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_electric_analog.imageset/intro_electric_analog.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_electric_analog.imageset/intro_electric_analog.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_gas.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_gas.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_gas.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_gas.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_gas.imageset/intro_gas.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_gas.imageset/intro_gas.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_gas.imageset/intro_gas.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_gas.imageset/intro_gas.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_heat.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_heat.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_heat.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_heat.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_heat.imageset/intro_heat.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_heat.imageset/intro_heat.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_heat.imageset/intro_heat.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_heat.imageset/intro_heat.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_iban.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_iban.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_iban.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_iban.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_iban.imageset/intro_iban(2).png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_iban.imageset/intro_iban(2).png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_iban.imageset/intro_iban(2).png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_iban.imageset/intro_iban(2).png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_isbn.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_isbn.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_isbn.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_isbn.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_isbn.imageset/intro_iban.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_isbn.imageset/intro_iban.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_isbn.imageset/intro_iban.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_isbn.imageset/intro_iban.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_license_plate.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_license_plate.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_license_plate.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_license_plate.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_license_plate.imageset/intro_license_plate_new.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_license_plate.imageset/intro_license_plate_new.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_license_plate.imageset/intro_license_plate_new.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_license_plate.imageset/intro_license_plate_new.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_mrz.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_mrz.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_mrz.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_mrz.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_mrz.imageset/intro_mrz.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_mrz.imageset/intro_mrz.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_mrz.imageset/intro_mrz.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_mrz.imageset/intro_mrz.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_record.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_record.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_record.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_record.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_record.imageset/intro_record.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_record.imageset/intro_record.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_record.imageset/intro_record.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_record.imageset/intro_record.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_red_bull.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_red_bull.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_red_bull.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_red_bull.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_red_bull.imageset/intro_red_bull.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_red_bull.imageset/intro_red_bull.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_red_bull.imageset/intro_red_bull.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_red_bull.imageset/intro_red_bull.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_scrabble.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_scrabble.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_scrabble.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_scrabble.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_scrabble.imageset/intro_scrabble.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_scrabble.imageset/intro_scrabble.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_scrabble.imageset/intro_scrabble.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_scrabble.imageset/intro_scrabble.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_voucher.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_voucher.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_voucher.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_voucher.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_voucher.imageset/intro_voucher.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_voucher.imageset/intro_voucher.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_voucher.imageset/intro_voucher.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_voucher.imageset/intro_voucher.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_water.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_water.imageset/Contents.json similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_water.imageset/Contents.json rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_water.imageset/Contents.json diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/intro_water.imageset/intro_water.png b/AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_water.imageset/intro_water.png similarity index 100% rename from AnylineExamples/Anyline Demo App/Images.xcassets/intro_water.imageset/intro_water.png rename to AnylineExamples/Anyline Demo App/Images.xcassets/intro/intro_water.imageset/intro_water.png diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/checkmark_script_selection.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/checkmark_script_selection.imageset/Contents.json new file mode 100644 index 000000000..06ef721ed --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/checkmark_script_selection.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "checkmark_script_selection.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/checkmark_script_selection.imageset/checkmark_script_selection.pdf b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/checkmark_script_selection.imageset/checkmark_script_selection.pdf new file mode 100644 index 000000000..a04f9af13 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/checkmark_script_selection.imageset/checkmark_script_selection.pdf differ diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/script_selection.imageset/Contents.json b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/script_selection.imageset/Contents.json new file mode 100644 index 000000000..acfa63d6c --- /dev/null +++ b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/script_selection.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "script_selection.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/script_selection.imageset/script_selection.pdf b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/script_selection.imageset/script_selection.pdf new file mode 100644 index 000000000..78ad5ff10 Binary files /dev/null and b/AnylineExamples/Anyline Demo App/Images.xcassets/script-selection/script_selection.imageset/script_selection.pdf differ diff --git a/AnylineExamples/Anyline Demo App/Info.plist b/AnylineExamples/Anyline Demo App/Info.plist index 8b93e1f73..f8ce6e2d9 100755 --- a/AnylineExamples/Anyline Demo App/Info.plist +++ b/AnylineExamples/Anyline Demo App/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 41.0.1 + 43.0.0-preview.1 CFBundleSignature ???? CFBundleVersion diff --git a/AnylineExamples/Anyline Examples Source/AnylineExamples-Bridging-Header.h b/AnylineExamples/Anyline Examples Source/AnylineExamples-Bridging-Header.h index 44f597574..10751f708 100644 --- a/AnylineExamples/Anyline Examples Source/AnylineExamples-Bridging-Header.h +++ b/AnylineExamples/Anyline Examples Source/AnylineExamples-Bridging-Header.h @@ -13,5 +13,6 @@ #import "NSUserDefaults+ALExamplesAdditions.h" #import "UIFont+ALExamplesAdditions.h" #import "UIColor+ALExamplesAdditions.h" +#import "ALPluginResultHelper.h" #import #import diff --git a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeFormatHelper.h b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeFormatHelper.h index 2436837e2..14d9aa933 100644 --- a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeFormatHelper.h +++ b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeFormatHelper.h @@ -1,13 +1,7 @@ -// -// ALBarcodeFormatHelper.h -// AnylineExamples -// -// Created by Daniel Albertini on 11.12.20. -// - #import NS_ASSUME_NONNULL_BEGIN +@class ALBarcodeFormat; @interface ALBarcodeFormatHelper : NSObject @@ -15,11 +9,11 @@ NS_ASSUME_NONNULL_BEGIN + (NSArray *)readableHeaderArray; -+ (NSArray *)defaultReadableName; ++ (NSArray *)defaultSymbologiesReadableNames; -+ (NSArray *)readableNameForFormats:(NSArray *)formats; ++ (NSArray *)readableNameForFormats:(NSArray *)formats; -+ (NSArray *)formatsForReadableNames:(NSArray *)readableNames; ++ (NSArray *)formatsForReadableNames:(NSArray *)readableNames; @end diff --git a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeFormatHelper.m b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeFormatHelper.m index e487fb79d..4dec9b745 100644 --- a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeFormatHelper.m +++ b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeFormatHelper.m @@ -1,11 +1,5 @@ -// -// ALBarcodeFormatHelper.m -// AnylineExamples -// -// Created by Daniel Albertini on 11.12.20. -// - #import "ALBarcodeFormatHelper.h" +#import "ALBarcodeTypes.h" #import static NSDictionary*>*> *barcodeFormats; @@ -19,50 +13,72 @@ static NSString * const kPostal = @"POSTAL CODES"; static NSString * const kLegacy = @"LEGACY SYMBOLOGIES"; + +@interface ALBarcodeFormatHelper () + ++ (NSArray *)barcodeFormatsFromSymbologyCodes:(NSArray *)symbologyCodes; + +@end + + @implementation ALBarcodeFormatHelper + (void)initialize { - barcodeFormats = - @{ - k1DRetail : @{@"UPC/EAN" : @[kCodeTypeONE_D_INVERSE,kCodeTypeEAN8,kCodeTypeEAN13,kCodeTypeUPCA,kCodeTypeUPCE,kCodeTypeUPCEANExtension,kCodeTypeUPC_EAN_EXTENSION], - @"GS1 DataBar & Composite Codes" : @[kCodeTypeRSS14,kCodeTypeRSSExpanded,kCodeTypeRSS_EXPANDED], - @"MSI" : @[kCodeTypeMSI] + barcodeFormats = @{ + + k1DRetail : @{ + @"UPC/EAN": + @[ + kCodeTypeONE_D_INVERSE, + kCodeTypeEAN8, + kCodeTypeEAN13, + kCodeTypeUPCA, + kCodeTypeUPCE, + kCodeTypeUPCEANExtension, + kCodeTypeUPC_EAN_EXTENSION + ], + @"GS1 DataBar & Composite Codes" : @[ + kCodeTypeRSS14, + kCodeTypeRSSExpanded, + kCodeTypeRSS_EXPANDED + ], + @"MSI" : @[ kCodeTypeMSI ] }, - + k1DLogisitcs : @{ - @"Code 128" : @[kCodeTypeCode128], - @"Code 39" : @[kCodeTypeCode39], - @"Interleaved 2 of 5" : @[kCodeTypeITF], - @"GS1-128" : @[kCodeTypeGS1_128], - @"ISBT 128" : @[kCodeTypeISBT_128], - @"Trioptic Code 39" : @[kCodeTypeTRIOPTIC], - @"Code 32" : @[kCodeTypeCODE_32], - @"Code 93" : @[kCodeTypeCode93], - //@"Matrix 2 of 5" : @[kCodeTypeMATRIX_2_5], + @"Code 128" : @[kCodeTypeCode128], + @"Code 39" : @[kCodeTypeCode39], + @"Interleaved 2 of 5" : @[kCodeTypeITF], + @"GS1-128" : @[kCodeTypeGS1_128], + @"ISBT 128" : @[kCodeTypeISBT_128], + @"Trioptic Code 39" : @[kCodeTypeTRIOPTIC], + @"Code 32" : @[kCodeTypeCODE_32], + @"Code 93" : @[kCodeTypeCode93], + //@"Matrix 2 of 5" : @[kCodeTypeMATRIX_2_5], }, - + k2D : @{ - @"Data Matrix" : @[kCodeTypeDataMatrix], - @"PDF417" : @[kCodeTypePDF417], - @"QR Code" : @[kCodeTypeQR], - @"MicroPDF417" : @[kCodeTypeMICRO_PDF], - @"MicroQR" : @[kCodeTypeMICRO_QR], - @"GS1 QR Code" : @[kCodeTypeGS1_QR_CODE], - @"Aztec" : @[kCodeTypeAztec], - @"MaxiCode" : @[kCodeTypeMaxiCode], + @"Data Matrix" : @[kCodeTypeDataMatrix], + @"PDF417" : @[kCodeTypePDF417], + @"QR Code" : @[kCodeTypeQR], + @"MicroPDF417" : @[kCodeTypeMICRO_PDF], + @"MicroQR" : @[kCodeTypeMICRO_QR], + @"GS1 QR Code" : @[kCodeTypeGS1_QR_CODE], + @"Aztec" : @[kCodeTypeAztec], + @"MaxiCode" : @[kCodeTypeMaxiCode], }, - + kPostal : @{ - @"US Postnet" : @[kCodeTypeUS_POSTNET], - @"US Planet" : @[kCodeTypeUS_PLANET], - @"UK Postal" : @[kCodeTypePOST_UK], - @"USPS 4CD / One Code / Intelligent Mail" : @[kCodeTypeUSPS_4CB,kCodeTypeDOT_CODE], + @"US Postnet" : @[kCodeTypeUS_POSTNET], + @"US Planet" : @[kCodeTypeUS_PLANET], + @"UK Postal" : @[kCodeTypePOST_UK], + @"USPS 4CD / One Code / Intelligent Mail" : @[kCodeTypeUSPS_4CB,kCodeTypeDOT_CODE], }, - + kLegacy : @{ - @"Code 25" : @[kCodeTypeDISCRETE_2_5], - @"Codabar" : @[kCodeTypeCodabar], - @"Code 11" : @[kCodeTypeCODE_11] + @"Code 25" : @[kCodeTypeDISCRETE_2_5], + @"Codabar" : @[kCodeTypeCodabar], + @"Code 11" : @[kCodeTypeCODE_11] } }; @@ -85,24 +101,28 @@ + (void)initialize { return headerNames; } -+ (NSArray *)defaultReadableName { ++ (NSArray *)defaultSymbologiesReadableNames { return defaultReadableNames; } -+ (NSArray *)readableNameForFormats:(NSArray *)formats { ++ (NSArray *)readableNameForFormats:(NSArray *)formats { + + BOOL isAllFormats = formats.count == 1 && formats[0] == ALBarcodeFormat.all; + NSMutableArray *readableNames = [@[] mutableCopy]; - - for (NSString *defaultFormat in formats) { + for (ALBarcodeFormat *defaultFormat in formats) { [barcodeFormats enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSDictionary *> * _Nonnull obj, BOOL * _Nonnull stop) { [obj enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull readableName, NSArray * _Nonnull sdkNames, BOOL * _Nonnull stop2) { for (NSString *sdkFormat in sdkNames) { - if ([defaultFormat isEqualToString:sdkFormat]) { + if (isAllFormats || [defaultFormat.value isEqualToString:sdkFormat]) { if (![readableNames containsObject:readableName]) { [readableNames addObject:readableName]; } - *stop = YES; - *stop2 = YES; + if (!isAllFormats) { + *stop = YES; + *stop2 = YES; + } } } }]; @@ -111,14 +131,15 @@ + (void)initialize { return readableNames; } -+ (NSArray *)formatsForReadableNames:(NSArray *)readableNames { - NSMutableArray *sdkFormats = [@[] mutableCopy]; ++ (NSArray *)formatsForReadableNames:(NSArray *)readableNames { + NSMutableArray *sdkFormats = [@[] mutableCopy]; for (NSString *readableName in readableNames) { [barcodeFormats enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSDictionary *> * _Nonnull obj, BOOL * _Nonnull stop) { [obj enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull readableNameKey, NSArray * _Nonnull sdkNames, BOOL * _Nonnull stop2) { if ([readableName isEqualToString:readableNameKey]) { - [sdkFormats addObjectsFromArray:sdkNames]; + NSArray *formats = [self barcodeFormatsFromSymbologyCodes:sdkNames]; + [sdkFormats addObjectsFromArray:formats]; *stop = YES; *stop2 = YES; } @@ -128,4 +149,14 @@ + (void)initialize { return sdkFormats; } ++ (NSArray *)barcodeFormatsFromSymbologyCodes:(NSArray *)symbologyCodes { + NSMutableArray *ret = [NSMutableArray arrayWithCapacity:symbologyCodes.count]; + for (NSString *code in symbologyCodes) { + ALBarcodeFormat *format = [ALBarcodeFormat withValue:code]; + NSAssert(format, @"format not recognized: %@", code); + [ret addObject:format]; + } + return ret; +} + @end diff --git a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeScanViewController.h b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeScanViewController.h new file mode 100755 index 000000000..65a1ec339 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeScanViewController.h @@ -0,0 +1,8 @@ +#import + +#import "ALBaseScanViewController.h" + +@interface ALBarcodeScanViewController : ALBaseScanViewController + + +@end diff --git a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeScanViewController.m b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeScanViewController.m new file mode 100755 index 000000000..5cd4644e3 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeScanViewController.m @@ -0,0 +1,477 @@ +#import "ALBarcodeScanViewController.h" +#import +#import "AnylineExamples-Swift.h" // for ALResultViewController +#import "ALBarcodeFormatHelper.h" +#import "ALBarcodeResultUtil.h" +#import "ALSelectionTable.h" +#import "UIColor+ALExamplesAdditions.h" +#import "UIFont+ALExamplesAdditions.h" +#import "UISwitch+ALExamplesAdditions.h" + +NSTimeInterval const kBarcodeTroubleScanningTimeoutTime = 15; + +NSString * const kBarcodeScanVC_titleText = @"Barcode does not scan?"; + +NSString * const kBarcodeScanVC_messageText = @"By default not all barcodes are enabled for scanning, \ +take a look at the settings to find out if your barcode is currently selected for scanning."; + +NSString * const kBarcodeScanVC_configJSONFilename = @"sample_barcode_config"; + + +@interface ALBarcodeScanViewController () + +@property (nonatomic, strong) ALScanViewPlugin *scanViewPlugin; + +@property (nonatomic, readonly) ALScanViewPluginConfig *scanViewPluginConfigDefault; + +@property (nonatomic, strong) ALScanResult *latestScanResult; + +@property (nonatomic, strong) NSArray *selectedBarcodeFormats; + +@property (nonatomic, strong) UILabel *resultLabel; + +@property (nonatomic, strong) UIButton *scanButton; + +@property (nonatomic, strong) NSTimer *fadeTimer; + +@property (nonatomic, strong) UISwitch *barcodeModeToggle; + +@property (nonatomic, assign) BOOL isMultiBarcode; + +@property (nonatomic, strong) NSArray *defaultBarcodeSymbologiesReadable; + +@property (nullable, nonatomic, strong) NSTimer *troubleScanningTimeout; + ++ (ALScanViewPluginConfig *)defaultScanViewPluginConfig; + ++ (ALScanViewPlugin *)scanViewPluginWithBarcodeFormats:(NSArray *)barcodeFormats + isMultiBarcode:(BOOL)isMultiBarcode; + +@end + + +@implementation ALBarcodeScanViewController + +- (void)dealloc { + NSLog(@"dealloc ALBarcodeScanViewController"); +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.title = @"Barcodes"; + self.controllerType = ALScanHistoryBarcode; + + [self setupSettingsNavBarBtn]; + + self.defaultBarcodeSymbologiesReadable = [ALBarcodeFormatHelper defaultSymbologiesReadableNames]; + + // NOTE: we don't use the `self.* = ` notation here to avoid calling the reloadScanView each time + // The values of these two properties are defined here and their corresponding values on the + // config JSON file are ignored. Also, must give this property a value otherwise a crash will + // ensue. + _isMultiBarcode = NO; + + // or alternatively, + // _selectedBarcodeFormats = @[ ,... ]; + _selectedBarcodeFormats = [ALBarcodeFormatHelper formatsForReadableNames: + self.defaultBarcodeSymbologiesReadable]; + + [self reloadScanView]; + + [self setupConfirmScanButton]; + + [self setupMultiBarcodeToggleButton]; + + [self setColors]; + + // ACO - maybe no need for this. + // [self setupResultLabel]; + + // TODO: enable PDF417 in the core, if it is available (it's a flag in the old plugin) + // TODO: replicate the existing "info" delegate calls +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.scanViewPlugin startWithError:nil]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self startTroubleScanningTimeout]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [self.scanViewPlugin stop]; + [self stopTroubleScanningTimeout]; + + // ACO do we still need this? + // usleep(200000); +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + [self setColors]; +} + +// MARK: - Getters and Setters + ++ (ALScanViewPluginConfig *)defaultScanViewPluginConfig { + NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:kBarcodeScanVC_configJSONFilename + ofType:@"json"]; + NSString *configStr = [NSString stringWithContentsOfFile:jsonFilePath + encoding:NSUTF8StringEncoding + error:NULL]; + return [[ALScanViewPluginConfig alloc] initWithJSONDictionary:[configStr asJSONObject] error:nil]; +} + +- (void)setIsMultiBarcode:(BOOL)isMultiBarcode { + [self.scanViewPlugin stop]; + _isMultiBarcode = isMultiBarcode; + [self reloadScanView]; +} + +- (void)setSelectedBarcodeFormats:(NSArray *)selectedBarcodeFormats { + [self.scanViewPlugin stop]; + _selectedBarcodeFormats = selectedBarcodeFormats; + [self reloadScanView]; +} + +/// When a config is updated, a new ScanView is generated and installed, along with a +/// new ScanViewPlugin incorporating the user config choices (`_selectedBarcodeFormats` and +/// `_isMultiBarcode` ). +- (void)reloadScanView { + + ALScanViewPlugin *scanViewPlugin = [self.class scanViewPluginWithBarcodeFormats:self.selectedBarcodeFormats + isMultiBarcode:self.isMultiBarcode]; + scanViewPlugin.scanPlugin.delegate = self; + scanViewPlugin.delegate = self; + + self.scanButton.alpha = self.isMultiBarcode ? 1 : 0; + + self.scanViewPlugin = scanViewPlugin; + + if (self.scanView) { + [self.scanView setScanViewPlugin:scanViewPlugin error:nil]; + } else { + NSDictionary *configJSONDictionary = [[self configJSONStrWithFilename:kBarcodeScanVC_configJSONFilename] + asJSONObject]; + ALScanViewConfig *scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:configJSONDictionary + error:nil]; + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:scanViewPlugin + scanViewConfig:scanViewConfig + error:nil]; + [self installScanView:self.scanView]; // call startCamera and start the plugin outside + } + + // we've just readded the ScanView, make sure it goes beneath the other views. + [self.view sendSubviewToBack:self.scanView]; + + [self.scanView startCamera]; +} + ++ (ALScanViewPlugin *)scanViewPluginWithBarcodeFormats:(NSArray *)barcodeFormats + isMultiBarcode:(BOOL)isMultiBarcode { + ALScanViewPluginConfig *scanViewPluginConfig = [self.class defaultScanViewPluginConfig]; + // reach into the barcode config and change the formats and multibarcode flags + ALPluginConfig *pluginConfig = scanViewPluginConfig.scanPluginConfig.pluginConfig; + + // if multibarcode, also cancelOnResult = false, otherwise true + pluginConfig.cancelOnResult = [NSNumber numberWithBool:isMultiBarcode ? false : true]; + + ALBarcodeConfig *barcodeConfig = pluginConfig.barcodeConfig; + barcodeConfig.barcodeFormats = barcodeFormats; + barcodeConfig.multiBarcode = @(isMultiBarcode); + + // ALScanFeedbackConfig *scanFeedbackConfig = + NSMutableDictionary *scanFeedbackConfigDict = [NSMutableDictionary dictionaryWithDictionary:[[scanViewPluginConfig.scanFeedbackConfig asJSONString] asJSONObject]]; + + scanFeedbackConfigDict[@"beepOnResult"] = @(!isMultiBarcode); + scanFeedbackConfigDict[@"vibrateOnResult"] = @(!isMultiBarcode); + ALScanFeedbackConfig *scanFeedbackConfig = [ALScanFeedbackConfig withJSONDictionary:scanFeedbackConfigDict]; + + scanViewPluginConfig = [[ALScanViewPluginConfig alloc] initWithScanPluginConfig:scanViewPluginConfig.scanPluginConfig cutoutConfig:scanViewPluginConfig.cutoutConfig scanFeedbackConfig:scanFeedbackConfig error:nil]; + + return [[ALScanViewPlugin alloc] initWithConfig:scanViewPluginConfig error:nil]; +} + +// MARK: - Setup UI Elements + +- (void)setupConfirmScanButton { + CGFloat horizontalPadding = 30; + + UIButton *scanButton = [[UIButton alloc] initWithFrame:CGRectZero]; + [self.view addSubview:scanButton]; + self.scanButton = scanButton; + + scanButton.backgroundColor = [UIColor AL_examplesBlue]; + scanButton.alpha = 0; + [scanButton addTarget:self action:@selector(scanAction:) forControlEvents:UIControlEventTouchUpInside]; + [scanButton setTitle:@"Scan" forState:UIControlStateNormal]; + [scanButton.titleLabel setFont:[UIFont AL_proximaBoldWithSize:18]]; + [scanButton.titleLabel setTextColor:[UIColor whiteColor]]; + [scanButton.layer setCornerRadius:50/2]; + [scanButton setTranslatesAutoresizingMaskIntoConstraints:NO]; + [scanButton.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES; + + NSArray *scanButtonConstraints = @[ + [scanButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:horizontalPadding], + [scanButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-horizontalPadding], + [scanButton.heightAnchor constraintEqualToConstant:50], + [scanButton.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:-30] + ]; + + [self.view addConstraints:scanButtonConstraints]; + [NSLayoutConstraint activateConstraints:scanButtonConstraints]; +} + +- (void)setupResultLabel { + // The resultLabel is used as a debug view to see the scanned results. We set its text + // in anylineBarcodeModuleView:didFindScanResult:atImage below + CGRect frame = CGRectMake(20, self.view.frame.size.height - 150, self.view.frame.size.width - 40, 50); + self.resultLabel = [[UILabel alloc] initWithFrame:frame]; + self.resultLabel.textAlignment = NSTextAlignmentCenter; + self.resultLabel.textColor = [UIColor whiteColor]; + self.resultLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:16]; + self.resultLabel.adjustsFontSizeToFitWidth = YES; + self.resultLabel.showsExpansionTextWhenTruncated = YES; + self.resultLabel.numberOfLines = 2; + [self.view addSubview:self.resultLabel]; + + self.resultLabel.translatesAutoresizingMaskIntoConstraints = NO; + + [self.resultLabel.leftAnchor constraintEqualToAnchor:self.view.leftAnchor constant:40].active = YES; + [self.resultLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES; + [self.resultLabel.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:-150].active = YES; +} + +- (void)setupSettingsNavBarBtn { + UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Settings"] + style:UIBarButtonItemStylePlain + target:self + action:@selector(showSymbologiesSelector:)]; + // UIColor *tintColor = [UIColor lightGrayColor]; + self.navigationItem.rightBarButtonItem = anotherButton; +} + +- (void)setupMultiBarcodeToggleButton { + UISwitch *multiBarcodeSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; + [self.view addSubview:multiBarcodeSwitch]; + + multiBarcodeSwitch.translatesAutoresizingMaskIntoConstraints = NO; + [multiBarcodeSwitch.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:-20].active = YES; + [multiBarcodeSwitch.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:115].active = YES; + [multiBarcodeSwitch setTintColor:[UIColor AL_NonSelectedToolBarItem]]; + [multiBarcodeSwitch setOnTintColor:[UIColor AL_examplesBlue]]; + [multiBarcodeSwitch useHighContrast]; + + [multiBarcodeSwitch addTarget:self action:@selector(toggleMultiBarcode:) forControlEvents:UIControlEventValueChanged]; + [multiBarcodeSwitch setOn:self.isMultiBarcode]; + + self.barcodeModeToggle = multiBarcodeSwitch; + + UILabel *multiBarcodeLabel = [[UILabel alloc] init]; + [self.view addSubview:multiBarcodeLabel]; + multiBarcodeLabel.translatesAutoresizingMaskIntoConstraints = NO; + [multiBarcodeLabel.centerYAnchor constraintEqualToAnchor:multiBarcodeSwitch.centerYAnchor].active = YES; + [multiBarcodeLabel.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES; + [multiBarcodeLabel.rightAnchor constraintEqualToAnchor:multiBarcodeSwitch.leftAnchor constant:-10].active = YES; + [multiBarcodeLabel.heightAnchor constraintEqualToAnchor:multiBarcodeSwitch.heightAnchor].active = YES; + + multiBarcodeLabel.text = @"Multi Barcode"; + multiBarcodeLabel.font = [UIFont AL_proximaBoldWithSize:16]; + multiBarcodeLabel.textColor = [UIColor AL_White]; + multiBarcodeLabel.textAlignment = NSTextAlignmentRight; +} + +- (void)setColors { + [super setColors]; + + UIColor *navTint = [UIColor colorWithWhite:0.3 alpha:1]; + if (self.isDarkMode) { + navTint = [UIColor colorWithWhite:1 alpha:1]; + } + self.navigationItem.rightBarButtonItem.tintColor = navTint; +} + +// MARK: - IBAction methods + +- (void)scanAction:(id)sender { + + [self showResultControllerWithResults]; // maybe save the last scanned cropped image result too +} + +- (IBAction)toggleMultiBarcode:(id)sender { + self.isMultiBarcode = self.barcodeModeToggle.isOn; // calls the setter for this property + [self.scanViewPlugin startWithError:nil]; +} + +- (void)showSymbologiesSelector:(id)button { + NSArray *selectedItems = [ALBarcodeFormatHelper readableNameForFormats:self.selectedBarcodeFormats]; + NSString *title = @"Select Symbologies"; // "Select Barcode Symbologies" would've been clearer, but is a bit long + ALSelectionTable *table = [[ALSelectionTable alloc] initWithSelectedItems:selectedItems + allItems:[ALBarcodeFormatHelper readableBarcodeNamesDict] + headerTitles:[ALBarcodeFormatHelper readableHeaderArray] + defaultItems:self.defaultBarcodeSymbologiesReadable + title:title + singleSelect:NO]; + table.delegate = self; + UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:table]; + navController.modalPresentationStyle = UIModalPresentationFullScreen; + [self presentViewController:navController animated:YES completion:nil]; +} + +// MARK: - ALSelectionTableDelegate + +- (void)selectionTable:(ALSelectionTable *)selectionTable + selectedItems:(NSArray *)selectedItems { + // this calls the setter for this property. + self.selectedBarcodeFormats = [ALBarcodeFormatHelper + formatsForReadableNames:selectedItems]; + [self.scanViewPlugin startWithError:nil]; +} + +// MARK: - ALScanPluginDelegate + +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + + if (!scanResult.croppedImage) { // reject any result that doesn't come with an image. + // ACO this is a known bug in the core (at the moment) + // In doing this, the plugin config (on JSON) needs `cancelOnResult` to be false. + return; + } + + [self stopTroubleScanningTimeout]; + + self.latestScanResult = scanResult; + + NSArray *barcodes = scanResult.pluginResult.barcodeResult.barcodes; + if (barcodes.count < 1) { + return; + } + + if (!self.isMultiBarcode) { + [self showResultControllerWithResults]; + } +} + + +// MARK: - ALScanViewPluginDelegate + +- (void)scanViewPlugin:(ALScanViewPlugin *)scanViewPlugin visualFeedbackReceived:(ALEvent *)event { + // NSLog(@"ACO visual feedback received: %@", event.JSONStr); +} + +- (void)scanViewPluginResultBeepTriggered:(ALScanViewPlugin *)scanViewPlugin { + +} + +- (void)scanViewPluginResultBlinkTriggered:(ALScanViewPlugin *)scanViewPlugin { + +} + +- (void)scanViewPluginResultVibrateTriggered:(ALScanViewPlugin *)scanViewPlugin { + +} + +- (void)scanViewPlugin:(ALScanViewPlugin *)scanViewPlugin brightnessUpdated:(ALEvent *)event { + // NSLog(@"ACO brightness updated: %@", event.JSONStr); +} + +- (void)scanViewPlugin:(ALScanViewPlugin *)scanViewPlugin cutoutVisibilityChanged:(ALEvent *)event { + // NSLog(@"ACO cutout visibility changed: %@", event.JSONStr); + // ACO TODO: maybe include the cutout coordinates in scan view coordinate space. +} + +// TODO: (ACO) see if there's any need to provide this + +//- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin *)anylineBarcodeScanPlugin didFindResult:(ALBarcodeResult*)scanResult { +// // Nothing to do there +// // we get the results with anylineBarcodeScanPlugin:scannedBarcodes: +//} +// + +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info { +// if ([info.variableName isEqualToString:@"$brightness"]) { +// [self updateBrightness:[info.value floatValue] forModule:self.barcodeScanPlugin]; +// } +//} + +- (void)showResultControllerWithResults { + if (!self.latestScanResult) { + // prevent double pushes (result will be cleared upon entry) + return; + } + [self.scanViewPlugin stop]; + + // copy the barcodes array and image before clearing + NSArray *barcodesFound = [NSArray arrayWithArray:self.latestScanResult.pluginResult + .barcodeResult.barcodes]; + UIImage *image = [self.latestScanResult.croppedImage copy]; + + NSAssert(barcodesFound.count > 0, @"no barcodes found"); + + self.latestScanResult = nil; + + NSArray *resultData = [ALBarcodeResultUtil resultDataFromBarcodeResults:barcodesFound]; + NSString *resultDataJSONStr = [ALResultEntry JSONStringFromList:resultData]; + + // ACO this disabled block of code copies the result text into the result label (which we've also disabled) + // NSMutableArray *resultStrs = [NSMutableArray arrayWithCapacity:resultData.count]; + // for (ALResultEntry *data in resultData) { + // if ([data.title isEqualToString:@"Barcode Result"]) { + // [resultStrs addObject:data.value]; + // } + // } + // self.resultLabel.text = [resultStrs componentsJoinedByString:@", "]; + + __weak __block typeof(self) weakSelf = self; + [self anylineDidFindResult:resultDataJSONStr + barcodeResult:barcodesFound[0].value + image:image + scanPlugin:self.scanViewPlugin.scanPlugin + viewPlugin:self.scanViewPlugin completion:^{ + ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; + vc.imagePrimary = image; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]; +} + +// MARK: - Handle timeouts + +- (void)startTroubleScanningTimeout { + [self.troubleScanningTimeout invalidate]; + self.troubleScanningTimeout = [NSTimer scheduledTimerWithTimeInterval:kBarcodeTroubleScanningTimeoutTime + target:self + selector:@selector(showTroubleScanningDialog) + userInfo:nil + repeats:NO]; +} + +- (void)stopTroubleScanningTimeout { + [self.troubleScanningTimeout invalidate]; + self.troubleScanningTimeout = nil; +} + +- (void)showTroubleScanningDialog { + if ([self.navigationController topViewController] != self) { + return; + } + + if (self.presentedViewController != nil) { + return; + } + + [self.scanViewPlugin stop]; + + __weak __block typeof(self) weakSelf = self; + [self showAlertWithTitle:kBarcodeScanVC_titleText message:kBarcodeScanVC_messageText completion:^{ + [weakSelf.scanViewPlugin startWithError:nil]; + [weakSelf startTroubleScanningTimeout]; + }]; +} + +@end diff --git a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeTypes.h b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeTypes.h new file mode 100644 index 000000000..457228069 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeTypes.h @@ -0,0 +1,54 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * _Nonnull const kCodeTypeAll; +extern NSString * _Nonnull const kCodeTypeUnknown; +extern NSString * _Nonnull const kCodeTypeAztec; +extern NSString * _Nonnull const kCodeTypeCodabar; +extern NSString * _Nonnull const kCodeTypeCode39; +extern NSString * _Nonnull const kCodeTypeCode93; +extern NSString * _Nonnull const kCodeTypeCode128; +extern NSString * _Nonnull const kCodeTypeDataMatrix; +extern NSString * _Nonnull const kCodeTypeEAN8; +extern NSString * _Nonnull const kCodeTypeEAN13; +extern NSString * _Nonnull const kCodeTypeITF; +extern NSString * _Nonnull const kCodeTypePDF417; +extern NSString * _Nonnull const kCodeTypeRSS14; +extern NSString * _Nonnull const kCodeTypeRSSExpanded; +extern NSString * _Nonnull const kCodeTypeUPCA; +extern NSString * _Nonnull const kCodeTypeUPCE; +extern NSString * _Nonnull const kCodeTypeUPCEANExtension; +extern NSString * _Nonnull const kCodeTypeQR; + +extern NSString * _Nonnull const kCodeTypeRSS_EXPANDED; +extern NSString * _Nonnull const kCodeTypeMATRIX_2_5; +extern NSString * _Nonnull const kCodeTypeAZTEC_INVERSE; +extern NSString * _Nonnull const kCodeTypeDATAMATRIX_INVERSE; +extern NSString * _Nonnull const kCodeTypeQR_INVERSE; +extern NSString * _Nonnull const kCodeTypeDOT_CODE; +extern NSString * _Nonnull const kCodeTypeGS1_QR_CODE; +extern NSString * _Nonnull const kCodeTypeMICRO_QR; +extern NSString * _Nonnull const kCodeTypeISSN_EAN; +extern NSString * _Nonnull const kCodeTypeCOUPON; +extern NSString * _Nonnull const kCodeTypeTRIOPTIC; +extern NSString * _Nonnull const kCodeTypeDISCRETE_2_5; +extern NSString * _Nonnull const kCodeTypeMSI; +extern NSString * _Nonnull const kCodeTypeONE_D_INVERSE; +extern NSString * _Nonnull const kCodeTypeUSPS_4CB; +extern NSString * _Nonnull const kCodeTypeUS_POSTNET; +extern NSString * _Nonnull const kCodeTypeUS_PLANET; +extern NSString * _Nonnull const kCodeTypeMICRO_PDF; +extern NSString * _Nonnull const kCodeTypeKIX; +extern NSString * _Nonnull const kCodeTypeUPU_FICS; +extern NSString * _Nonnull const kCodeTypePOST_UK; +extern NSString * _Nonnull const kCodeTypeGS1_128; +extern NSString * _Nonnull const kCodeTypeBOOKLAND; +extern NSString * _Nonnull const kCodeTypeISBT_128; +extern NSString * _Nonnull const kCodeTypeCODE_11; +extern NSString * _Nonnull const kCodeTypeCODE_32; +extern NSString * _Nonnull const kCodeTypeUPC_EAN_EXTENSION; +extern NSString * _Nonnull const kCodeTypeDATABAR; +extern NSString * _Nonnull const kCodeTypeMaxiCode; + +NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeTypes.m b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeTypes.m new file mode 100644 index 000000000..e0531e8d4 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALBarcodeTypes.m @@ -0,0 +1,51 @@ +#import "ALBarcodeTypes.h" + +NSString * const kCodeTypeAll = @"ALL"; +NSString * const kCodeTypeUnknown = @"UNKNOWN"; +NSString * const kCodeTypeAztec = @"AZTEC"; +NSString * const kCodeTypeCodabar = @"CODABAR"; +NSString * const kCodeTypeCode39 = @"CODE_39"; +NSString * const kCodeTypeCode93 = @"CODE_93"; +NSString * const kCodeTypeCode128 = @"CODE_128"; +NSString * const kCodeTypeDataMatrix = @"DATA_MATRIX"; +NSString * const kCodeTypeEAN8 = @"EAN_8"; +NSString * const kCodeTypeEAN13 = @"EAN_13"; +NSString * const kCodeTypeITF = @"ITF"; +NSString * const kCodeTypePDF417 = @"PDF_417"; +NSString * const kCodeTypeRSS14 = @"RSS_14"; +NSString * const kCodeTypeRSSExpanded = @"RSS_EXPANDED"; +NSString * const kCodeTypeUPCA = @"UPC_A"; +NSString * const kCodeTypeUPCE = @"UPC_E"; +NSString * const kCodeTypeUPCEANExtension = @"UPC_EAN_EXTENSION"; +NSString * const kCodeTypeQR = @"QR_CODE"; + +NSString * const kCodeTypeRSS_EXPANDED = @"RSS_EXPANDED"; +NSString * const kCodeTypeMATRIX_2_5 = @"MATRIX_2_5"; +NSString * const kCodeTypeAZTEC_INVERSE = @"AZTEC_INVERSE"; +NSString * const kCodeTypeDATAMATRIX_INVERSE = @"DATAMATRIX_INVERSE"; +NSString * const kCodeTypeQR_INVERSE = @"QR_INVERSE"; +NSString * const kCodeTypeDOT_CODE = @"DOT_CODE"; +NSString * const kCodeTypeGS1_QR_CODE = @"GS1_QR_CODE"; +NSString * const kCodeTypeMICRO_QR = @"MICRO_QR"; +NSString * const kCodeTypeISSN_EAN = @"ISSN_EAN"; +NSString * const kCodeTypeCOUPON = @"COUPON"; +NSString * const kCodeTypeTRIOPTIC = @"TRIOPTIC"; +NSString * const kCodeTypeDISCRETE_2_5 = @"DISCRETE_2_5"; +NSString * const kCodeTypeMSI = @"MSI"; +NSString * const kCodeTypeONE_D_INVERSE = @"ONE_D_INVERSE"; +NSString * const kCodeTypeUSPS_4CB = @"USPS_4CB"; +NSString * const kCodeTypeUS_POSTNET = @"US_POSTNET"; +NSString * const kCodeTypeUS_PLANET = @"US_PLANET"; +NSString * const kCodeTypeMICRO_PDF = @"MICRO_PDF"; +NSString * const kCodeTypeKIX = @"KIX"; +NSString * const kCodeTypeUPU_FICS = @"UPU_FICS"; +NSString * const kCodeTypePOST_UK = @"POST_UK"; +NSString * const kCodeTypeGS1_128 = @"GS1_128"; +NSString * const kCodeTypeBOOKLAND = @"BOOKLAND"; +NSString * const kCodeTypeISBT_128 = @"ISBT_128"; +NSString * const kCodeTypeCODE_11 = @"CODE_11"; +NSString * const kCodeTypeCODE_32 = @"CODE_32"; +NSString * const kCodeTypeUPC_EAN_EXTENSION = @"UPC_EAN_EXTENSION"; +NSString * const kCodeTypeDATABAR = @"DATABAR"; +NSString * const kCodeTypeMaxiCode = @"MAXICODE"; + diff --git a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALMultiformatBarcodeScanViewController.h b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALMultiformatBarcodeScanViewController.h deleted file mode 100755 index 4007ef1b4..000000000 --- a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALMultiformatBarcodeScanViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// ALBarcodeScanViewController.h -// AnylineExamples -// -// Created by Matthias Gasser on 22/04/15. -// Copyright (c) 2015 9yards GmbH. All rights reserved. -// - -#import - -#import "ALBaseScanViewController.h" - -@interface ALMultiformatBarcodeScanViewController : ALBaseScanViewController - - -@end diff --git a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALMultiformatBarcodeScanViewController.m b/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALMultiformatBarcodeScanViewController.m deleted file mode 100755 index e76df8b08..000000000 --- a/AnylineExamples/Anyline Examples Source/Barcode/ViewController/ALMultiformatBarcodeScanViewController.m +++ /dev/null @@ -1,284 +0,0 @@ -// -// ALBarcodeScanViewController.m -// AnylineExamples -// -// Created by Matthias Gasser on 22/04/15. -// Copyright (c) 2015 9yards GmbH. All rights reserved. -// - -#import "ALMultiformatBarcodeScanViewController.h" -#import -#import "AnylineExamples-Swift.h" -#import "NSUserDefaults+ALExamplesAdditions.h" -#import "ALSelectionTable.h" -#import "ALBarcodeFormatHelper.h" -#import "UIColor+ALExamplesAdditions.h" -#import "UIFont+ALExamplesAdditions.h" -#import "UISwitch+ALExamplesAdditions.h" -#import "ALRoundedView.h" -#import "ALBarcodeResultUtil.h" - -// The controller has to conform to to be able to receive results -@interface ALMultiformatBarcodeScanViewController() -// The Anyline plugin used to scan barcodes -@property (nonatomic, strong) ALBarcodeScanPlugin *barcodeScanPlugin; -@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; - -// A debug label to show scanned results -@property (nonatomic, strong) ALBarcodeResult* lastBarcodeResult; -@property (nonatomic, strong) UILabel *resultLabel; -@property (nonatomic, strong) UIButton *scanButton; -@property (nonatomic, strong) NSTimer *fadeTimer; -@property (nonatomic, strong) UISwitch *multiBarcode; - -@property (nonatomic, strong) NSArray *defaultReadableSymbologies; - -@end - -@implementation ALMultiformatBarcodeScanViewController - -/* - We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed. - */ -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"Barcodes"; - CGRect frame = [self scanViewFrame]; - - //Add Barcode Scan Plugin (Scan Process) - NSError *error = nil; - - self.barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] initWithPluginID:@"BARCODE" delegate:self error:&error]; - self.barcodeScanPlugin.parsePDF417 = YES; - NSAssert(self.barcodeScanPlugin, @"Setup Error: %@", error.debugDescription); - - [self.barcodeScanPlugin addInfoDelegate:self]; - - self.defaultReadableSymbologies = [ALBarcodeFormatHelper defaultReadableName]; - - //Set Barcode Formats - [self.barcodeScanPlugin setBarcodeFormatOptions:[ALBarcodeFormatHelper formatsForReadableNames:self.defaultReadableSymbologies]]; - //Add Barcode Scan View Plugin (Scan UI) - - ALScanViewPluginConfig * config = [ALScanViewPluginConfig defaultBarcodeConfig]; - config.cutoutConfig.alignment = ALCutoutAlignmentMiddle; - config.cancelOnResult = NO; - config.scanFeedbackConfig.vibrateOnResult = NO; - config.scanFeedbackConfig.blinkAnimationOnResult = NO; - config.scanFeedbackConfig.beepOnResult = NO; - config.scanFeedbackConfig.strokeWidth = 3; - config.cutoutConfig.feedbackStrokeColor = [UIColor clearColor]; - config.cutoutConfig.usesAnimatedRect = YES; - - - self.barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] initWithScanPlugin:self.barcodeScanPlugin scanViewPluginConfig:config]; - NSAssert(self.barcodeScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.barcodeScanViewPlugin addScanViewPluginDelegate:self]; - - //Add ScanView (Camera and Flashbutton) - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.barcodeScanViewPlugin]; - [self.scanView.captureDeviceManager setValue:@(1) forKey:@"disableNative"]; - - [self.view addSubview:self.scanView]; - - [self.scanView startCamera]; - - self.barcodeScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; - - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - - // The resultLabel is used as a debug view to see the scanned results. We set its text - // in anylineBarcodeModuleView:didFindScanResult:atImage below - self.resultLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, self.view.frame.size.height - 150, self.view.frame.size.width - 40, 50)]; - self.resultLabel.textAlignment = NSTextAlignmentLeft; - self.resultLabel.textColor = [UIColor whiteColor]; - self.resultLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:18]; - self.resultLabel.adjustsFontSizeToFitWidth = YES; - self.resultLabel.numberOfLines = 0; - - [self.view addSubview:self.resultLabel]; - - self.controllerType = ALScanHistoryBarcode; - - UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Settings"] - style:UIBarButtonItemStylePlain - target:self - action:@selector(showSymbologySelector:)]; - self.navigationItem.rightBarButtonItem = anotherButton; - - UIWindow *window = UIApplication.sharedApplication.keyWindow; - CGFloat bottomPadding = window.safeAreaInsets.bottom; - CGFloat horizontalPadding = 30; - - UISwitch *multiBarcode = [[UISwitch alloc] initWithFrame:CGRectMake(self.view.bounds.size.width - 70, 20, 70, 60)]; - [self.scanView addSubview:multiBarcode]; - - [multiBarcode setTintColor:[UIColor AL_NonSelectedToolBarItem]]; - [multiBarcode setOnTintColor:[UIColor AL_examplesBlue]]; - [multiBarcode useHighContrast]; - [multiBarcode addTarget:self action:@selector(switchMultiBarcode:) forControlEvents:UIControlEventValueChanged]; - [multiBarcode setOn:NO]; - self.multiBarcode = multiBarcode; - - UILabel *multiBarcodeLabel = [[UILabel alloc] init]; - [self.view addSubview:multiBarcodeLabel]; - multiBarcodeLabel.translatesAutoresizingMaskIntoConstraints = NO; - [multiBarcodeLabel.centerYAnchor constraintEqualToAnchor:multiBarcode.centerYAnchor].active = YES; - [multiBarcodeLabel.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES; - [multiBarcodeLabel.rightAnchor constraintEqualToAnchor:multiBarcode.leftAnchor constant:-10].active = YES; - [multiBarcodeLabel.heightAnchor constraintEqualToAnchor:multiBarcode.heightAnchor].active = YES; - multiBarcodeLabel.text = @"Multi Barcode"; - multiBarcodeLabel.font = [UIFont AL_proximaBoldWithSize:16]; - multiBarcodeLabel.textColor = [UIColor AL_White]; - multiBarcodeLabel.textAlignment = NSTextAlignmentRight; - - - //Setup Confirm Button - UIButton * scanButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50+bottomPadding)]; - [self.scanView addSubview:scanButton]; - [scanButton addTarget:self action:@selector(scanAction:) forControlEvents:UIControlEventTouchUpInside]; - [scanButton setTitle:@"Scan" forState:UIControlStateNormal]; - [scanButton.titleLabel setFont:[UIFont AL_proximaBoldWithSize:18]]; - [scanButton.titleLabel setTextColor:[UIColor whiteColor]]; - scanButton.backgroundColor = [UIColor AL_examplesBlue]; - [scanButton.layer setCornerRadius:50/2]; - [scanButton setTranslatesAutoresizingMaskIntoConstraints:NO]; - [scanButton.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES; - - NSArray *scanButtonConstraints = @[ - [scanButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-horizontalPadding], - [scanButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:horizontalPadding], - [scanButton.heightAnchor constraintEqualToConstant:50], - [scanButton.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:-30] - ]; - [self.view addConstraints:scanButtonConstraints]; - [NSLayoutConstraint activateConstraints:scanButtonConstraints]; - scanButton.alpha = 0; - self.scanButton = scanButton; - -} - -#pragma mark - IBAction methods - -- (void)scanAction:(id)sender { - [self showResultControllerWithResult:self.lastBarcodeResult]; -} - -- (IBAction)switchMultiBarcode:(id)sender { - BOOL multi = self.multiBarcode.isOn; - self.barcodeScanPlugin.multiBarcode = multi; -} - -- (void)showSymbologySelector:(id)button { - NSArray *selectedItems = [ALBarcodeFormatHelper readableNameForFormats:self.barcodeScanPlugin.barcodeFormatOptions]; - - ALSelectionTable* table = [[ALSelectionTable alloc] initWithSelectedItems:selectedItems - allItems:[ALBarcodeFormatHelper readableBarcodeNamesDict] - headerTitles:[ALBarcodeFormatHelper readableHeaderArray] - defaultItems:self.defaultReadableSymbologies - title:@"Select Symbologies" - singleSelect:NO]; - table.delegate = self; - UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:table]; - navController.modalPresentationStyle = UIModalPresentationFullScreen; - [self presentViewController:navController animated:YES completion:nil]; -} - -- (void)selectionTable:(ALSelectionTable *)selectionTable selectedItems:(NSArray *)selectedItems { - [self.barcodeScanPlugin setBarcodeFormatOptions:[ALBarcodeFormatHelper - formatsForReadableNames:selectedItems]]; -} - -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self startPlugin:self.barcodeScanViewPlugin]; -} - -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.barcodeScanViewPlugin stopAndReturnError:nil]; - usleep(200000); -} - - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; - -} - -#pragma mark -- AnylineBarcodeModuleDelegate - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info { - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.barcodeScanPlugin]; - } -} - -- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin *)anylineBarcodeScanPlugin scannedBarcodes:(ALBarcodeResult*)scanResult { - // Enable this to see the barcode result on screen - // self.resultLabel.text = scanResult.barcodes.firstObject.value; - - self.lastBarcodeResult = scanResult; - if(self.multiBarcode.isOn ) { - [self.fadeTimer invalidate]; - // show scan button - [UIView animateWithDuration:0.3 animations:^{ self.scanButton.alpha = 1; }]; - // fade away in 3 seconds - self.fadeTimer = [NSTimer scheduledTimerWithTimeInterval:3 repeats:NO block:^(NSTimer * _Nonnull timer) { - [UIView animateWithDuration:0.3 animations:^{ - self.scanButton.alpha = 0; - }]; - }]; - } else { - [self showResultControllerWithResult:scanResult]; - } -} - -- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin *)anylineBarcodeScanPlugin didFindResult:(ALBarcodeResult*)scanResult { - // Nothing to do there - // we get the results with anylineBarcodeScanPlugin:scannedBarcodes: -} - -- (void)showResultControllerWithResult:(ALBarcodeResult *)scanResult { - [self.barcodeScanPlugin stopAndReturnError:nil]; - - NSArray *resultData = [ALBarcodeResultUtil barcodeResultDataFromBarcodeResultArray:scanResult.result]; - - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString - barcodeResult:@"" - image:scanResult.image - scanPlugin:self.barcodeScanPlugin - viewPlugin:self.barcodeScanViewPlugin - completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = scanResult.image; - - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/Barcode/barcode_pdf417_in_id.json b/AnylineExamples/Anyline Examples Source/Barcode/barcode_pdf417_in_id.json index 5f85d91a3..754def18d 100644 --- a/AnylineExamples/Anyline Examples Source/Barcode/barcode_pdf417_in_id.json +++ b/AnylineExamples/Anyline Examples Source/Barcode/barcode_pdf417_in_id.json @@ -1,41 +1,39 @@ { - "camera" : { - "captureResolution" : "1080p" - }, - "viewPlugin" : { - "plugin":{ - "id":"Barcode_ID", - "barcodePlugin": { - "barcodeFormatOptions": ["PDF_417"] - } + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.barcode", + "barcodeConfig": { + "barcodeFormats": [ "PDF_417" ], + "parseAAMVA": true + }, + "cancelOnResult": false, + "startScanDelay": 1000 }, - "cutoutConfig" : { + "cutoutConfig": { "animation": "none", - "style": "rect", - "maxWidthPercent": "80%", - "maxHeightPercent": "80%", + "maxWidthPercent": "75%", + "maxHeightPercent": "50%", + "width": 0, "alignment": "center", - "strokeWidth": 0, - "cornerRadius": 0, - "strokeColor": "FFFFFF", + "ratioFromSize": { "width": 3, "height": 1 }, + "offset": { "x": 0, "y": 0 }, + "cropOffset": { "x": 0, "y": 0 }, + "cropPadding": { "x": 0, "y": 0 }, + "cornerRadius": 4, + "strokeColor": "0099FF", + "strokeWidth": 2, "outerColor": "000000", - "outerAlpha": 0, - "ratioFromSize" : { - "width": 100, - "height": 80 - }, - "feedbackStrokeColor": "0099FF" + "feedbackStrokeColor": "0099FF", + "outerAlpha": 0.3 }, - "scanFeedback" : { - "style": "none", - "animation": "none", - "strokeWidth": 0, - "strokeColor": "000000", - "fillColor": "00000000", - "beepOnResult": false, - "vibrateOnResult": false, - "blinkAnimationOnFresult": false, - }, - "cancelOnResult": true + "scanFeedbackConfig": { + "style": "rect", + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "330099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": false + } } } diff --git a/AnylineExamples/Anyline Examples Source/Barcode/sample_barcode_config.json b/AnylineExamples/Anyline Examples Source/Barcode/sample_barcode_config.json new file mode 100644 index 000000000..c6c407589 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Barcode/sample_barcode_config.json @@ -0,0 +1,37 @@ +{ + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.barcode", + "barcodeConfig": { + "barcodeFormats": [ "ALL" ] + }, + "cancelOnResult": true, + "startScanDelay": 1000 + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "70%", + "maxHeightPercent": "70%", + "alignment": "center", + "ratioFromSize": { "width": 3, "height": 2 }, + "offset": { "x": 0, "y": 0 }, + "cropOffset": { "x": 0, "y": 0 }, + "cropPadding": { "x": 0, "y": 0 }, + "cornerRadius": 4, + "strokeColor": "0099ff", + "strokeWidth": 2, + "outerColor": "000000", + "feedbackStrokeColor": "0099FF", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "none", + "strokeWidth": 0, + "strokeColor": "0099FF", + "fillColor": "330099FF", + "beepOnResult": false, + "vibrateOnResult": false, + "blinkAnimationOnResult": false + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/Barcode/sample_barcode_fullframe_config.json b/AnylineExamples/Anyline Examples Source/Barcode/sample_barcode_fullframe_config.json new file mode 100644 index 000000000..bf30d928e --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Barcode/sample_barcode_fullframe_config.json @@ -0,0 +1,21 @@ +{ + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.barcode-fullframe", + "barcodeConfig": { + "multiBarcode": true, + "barcodeFormats": [ "ALL" ] + }, + "cancelOnResult": true + }, + "scanFeedbackConfig": { + "style": "rect", + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "330099FF", + "beepOnResult": false, + "vibrateOnResult": false, + "blinkAnimationOnResult": false + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/Bottlecap/ViewController/ALBottlecapScanViewController.m b/AnylineExamples/Anyline Examples Source/Bottlecap/ViewController/ALBottlecapScanViewController.m index 316852958..ec2cd51c3 100644 --- a/AnylineExamples/Anyline Examples Source/Bottlecap/ViewController/ALBottlecapScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/Bottlecap/ViewController/ALBottlecapScanViewController.m @@ -1,24 +1,13 @@ -// -// ALBottleCapScanViewController.m -// AnylineExamples -// -// Created by Daniel Albertini on 04/02/16. -// Copyright © 2016 9yards GmbH. All rights reserved. -// - #import "ALBottlecapScanViewController.h" #import #import "ALResultOverlayView.h" #import "NSUserDefaults+ALExamplesAdditions.h" #import "AnylineExamples-Swift.h" -// The controller has to conform to to be able to receive results -@interface ALBottlecapScanViewController () +NSString * const kBottleCapVC_configJSONFilename = @"bottlecap_config"; +@interface ALBottlecapScanViewController () -// The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *bottlecapScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *bottlecapvinScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +@property (nonatomic, strong) ALScanViewPlugin *scanViewPlugin; @end @@ -31,121 +20,68 @@ - (void)viewDidLoad { self.title = @"Pepsi Code"; - ALOCRConfig *config = [[ALOCRConfig alloc] init]; - config.scanMode = ALGrid; + self.controllerType = ALScanHistoryBottleCapPepsi; - NSString *alePath = [[NSBundle mainBundle] pathForResource:@"pepsi_code_scanner" ofType:@"ale"]; - [config setCustomCmdFilePath:alePath]; - - NSError *languagesError = nil; - NSString *anyPath = [[NSBundle mainBundle] pathForResource:@"PepsiCo" ofType:@"any"]; - [config setLanguages:@[anyPath,] error:&languagesError]; - NSAssert(!languagesError, @"SetLanguages Error: %@", languagesError.debugDescription); - - - NSError *error = nil; - - CGRect frame = [self scanViewFrame]; + [self reloadScanView]; + + [self setColors]; +} +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.scanViewPlugin startWithError:nil]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [self.scanViewPlugin stop]; +} + +- (void)reloadScanView { + NSDictionary *configJSONDictionary = [[self configJSONStrWithFilename:kBottleCapVC_configJSONFilename] asJSONObject]; + ALScanViewPlugin *scanViewPlugin = [[ALScanViewPlugin alloc] initWithJSONDictionary:configJSONDictionary error:nil]; + scanViewPlugin.scanPlugin.delegate = self; - self.bottlecapvinScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.bottlecapvinScanPlugin, @"Setup Error: %@", error.debugDescription); + [self.scanView stopCamera]; + if (self.scanView) { + [self.scanView removeFromSuperview]; + } - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"bottlecap_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; + self.scanViewPlugin = scanViewPlugin; - self.bottlecapScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.bottlecapvinScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; + ALScanViewConfig *scanViewConfig = [ALScanViewConfig withJSONDictionary:configJSONDictionary]; + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:scanViewPlugin + scanViewConfig:scanViewConfig + error:nil]; - NSAssert(self.bottlecapScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.bottlecapScanViewPlugin addScanViewPluginDelegate:self]; - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.bottlecapScanViewPlugin]; + [self installScanView:self.scanView]; // call startCamera and start the plugin outside - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; + // we've just readded the ScanView, make sure it goes beneath the other views. [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - //Start Camera: [self.scanView startCamera]; - [self startListeningForMotion]; - - self.controllerType = ALScanHistoryBottleCapPepsi; -} - -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; } -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.bottlecapScanViewPlugin stopAndReturnError:nil]; -} - -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.bottlecapScanViewPlugin]; -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} +#pragma mark -- ALScanPluginDelegate -#pragma mark -- ALOCRScanPluginDelegate - -/* - This is the main delegate method Anyline uses to report its results - */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin - didFindResult:(ALOCRResult *)result { - // We are done. Cancel scanning +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Pepsi Code" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.bottlecapScanViewPlugin completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Pepsi Code" value:scanResult.pluginResult.ocrResult.text shouldSpellOutValue:YES]]; + NSString *resultDataJSONStr = [ALResultEntry JSONStringFromList:resultData]; + __weak ALBottlecapScanViewController *weakSelf = self; + [self anylineDidFindResult:resultDataJSONStr + barcodeResult:@"" + image:scanResult.croppedImage + scanPlugin:scanPlugin + viewPlugin:self.scanViewPlugin + completion:^{ + ALResultViewController *vc = [[ALResultViewController alloc] + initWithResults:resultData]; + vc.imagePrimary = scanResult.croppedImage; + [weakSelf.navigationController pushViewController:vc animated:YES]; }]; } -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.bottlecapScanViewPlugin]; - } - -} - @end diff --git a/AnylineExamples/Anyline Examples Source/Bottlecap/ViewController/AnylineBottlecapScanViewController.swift b/AnylineExamples/Anyline Examples Source/Bottlecap/ViewController/AnylineBottlecapScanViewController.swift index 8333f25f4..f5899087e 100644 --- a/AnylineExamples/Anyline Examples Source/Bottlecap/ViewController/AnylineBottlecapScanViewController.swift +++ b/AnylineExamples/Anyline Examples Source/Bottlecap/ViewController/AnylineBottlecapScanViewController.swift @@ -11,13 +11,13 @@ import UIKit // The controller has to conform to ALOCRScanPluginDelegate to be able to receive results -@objc class AnylineBottlecapScanViewController: UIViewController, ALOCRScanPluginDelegate { +@objc class AnylineBottlecapScanViewController: UIViewController { //, ALOCRScanPluginDelegate let kBottlecapLicenseKey = "eyJzY29wZSI6WyJBTEwiXSwicGxhdGZvcm0iOlsiaU9TIiwiQW5kcm9pZCIsIldpbmRvd3MiXSwidmFsaWQiOiIyMDE3LTA4LTMwIiwibWFqb3JWZXJzaW9uIjoiMyIsImlzQ29tbWVyY2lhbCI6ZmFsc2UsInRvbGVyYW5jZURheXMiOjYwLCJpb3NJZGVudGlmaWVyIjpbImlvLmFueWxpbmUuZXhhbXBsZXMuYnVuZGxlIl0sImFuZHJvaWRJZGVudGlmaWVyIjpbImlvLmFueWxpbmUuZXhhbXBsZXMuYnVuZGxlIl0sIndpbmRvd3NJZGVudGlmaWVyIjpbImlvLmFueWxpbmUuZXhhbXBsZXMuYnVuZGxlIl19CkIxbU5LZEEvb0JZMlBvRlpsVGV4d3QraHltZTh1S25ON1ZYUStXbE1DY2dYc3RjTnJTL2ZOWVduSHJaSUVORk0vbmNFYWdlVU9Vem9tbmhFNG1tTFY1c3Mxbi8zc2tBQjdjM3pmd25MNkV2Mmx4Y1k4L0htN3Bna2t0K01NanRYODdXMTdWNjBGZWdXTmpXbWF0dmNJSHRFMkhmTEdjUkprQ3BHNFpacm5KWEltVnlkSVJtQmNsamwvWktuZzY1Nm5Rb3ZhMUZzc1p5Q2Vsb3VXSVhpRi9Odk1EcmVraUlaR2JreWVTRk9TT0VxLzgra0xFdHlmZG1yUy8vRjNVZ055YWtXN3NRQXFlNjlUQmN6ak5kVXdQU1lnY3BnSXd0d2puVUJsV2FmdGJ3aW9EKzlNRkowc1JFR2p0OFd5REJ6RHRZSi9EL3NRUm5sSXA2akFjQTNBQT09"; // The Anyline plugins used to scan - var ocrScanPlugin : ALOCRScanPlugin!; - var ocrScanViewPlugin : ALOCRScanViewPlugin!; +// var ocrScanPlugin : ALOCRScanPlugin!; +// var ocrScanViewPlugin : ALOCRScanViewPlugin!; var scanView : ALScanView!; /* @@ -32,45 +32,45 @@ import UIKit let frame : CGRect = CGRect(x: UIScreen.main.bounds.origin.x, y: UIScreen.main.bounds.origin.y + (self.navigationController?.navigationBar.frame.size.height)!, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height); //Setup OCR Scan Config - See Anyline Documentation for more information. - let config: ALOCRConfig = ALOCRConfig(); - config.scanMode = ALOCRScanMode.ALGrid; - config.charHeight = ALRangeMake(21, 97); - - do { - //Set Language files used for scanning - let languagePath : String = Bundle.main.path(forResource: "bottlecap", ofType: "traineddata")!; - try config.setLanguages([languagePath], error: ()); - } catch _ as NSError { - //Handle errors here. - } - config.characterWhitelist = "123456789ABCDEFGHJKLMNPRSTUVWXYZ"; - config.minConfidence = 75; - config.validationRegex = "^[0-9A-Z]{3}\n[0-9A-Z]{3}\n[0-9A-Z]{3}"; - - config.charCountX = 3; - config.charCountY = 3; - config.charPaddingXFactor = 0.3; - config.charPaddingYFactor = 0.5; - config.isBrightTextOnDark = true; - - //Load Anyline ScanViewPluginConfig - let bottlecapConfigPath : String = Bundle.main.path(forResource: "bottlecap_config", ofType: "json")!; - let bottlecapUIConfig : ALScanViewPluginConfig = ALScanViewPluginConfig.init(jsonFilePath: bottlecapConfigPath)!; - - - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - do { - // Init. ScanPlugin with ID, licenseKey, OCRConfig and delegate - self.ocrScanPlugin = try ALOCRScanPlugin.init(pluginID: "OCR", delegate: self, ocrConfig: config); - - //Set ScanViewPluginConfig and scanPluin for the ALOCRScanViewPlugin - self.ocrScanViewPlugin = ALOCRScanViewPlugin.init(scanPlugin: self.ocrScanPlugin, scanViewPluginConfig: bottlecapUIConfig); - - //Setup ScanView with frame size and the ocrScanViewPlugin - self.scanView = ALScanView.init(frame: frame, scanViewPlugin: self.ocrScanViewPlugin); - } catch _ as NSError { - //Handle error here - } +// let config: ALOCRConfig = ALOCRConfig(); +// config.scanMode = ALOCRScanMode.ALGrid; +// config.charHeight = ALRangeMake(21, 97); +// +// do { +// //Set Language files used for scanning +// let languagePath : String = Bundle.main.path(forResource: "bottlecap", ofType: "traineddata")!; +// try config.setLanguages([languagePath], error: ()); +// } catch _ as NSError { +// //Handle errors here. +// } +// config.characterWhitelist = "123456789ABCDEFGHJKLMNPRSTUVWXYZ"; +// config.minConfidence = 75; +// config.validationRegex = "^[0-9A-Z]{3}\n[0-9A-Z]{3}\n[0-9A-Z]{3}"; +// +// config.charCountX = 3; +// config.charCountY = 3; +// config.charPaddingXFactor = 0.3; +// config.charPaddingYFactor = 0.5; +// config.isBrightTextOnDark = true; +// +// //Load Anyline ScanViewPluginConfig +// let bottlecapConfigPath : String = Bundle.main.path(forResource: "bottlecap_config", ofType: "json")!; +// let bottlecapUIConfig : ALScanViewPluginConfig = ALScanViewPluginConfig.init(jsonFilePath: bottlecapConfigPath)!; +// +// +// // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen +// do { +// // Init. ScanPlugin with ID, licenseKey, OCRConfig and delegate +// self.ocrScanPlugin = try ALOCRScanPlugin.init(pluginID: "OCR", delegate: self, ocrConfig: config); +// +// //Set ScanViewPluginConfig and scanPluin for the ALOCRScanViewPlugin +// self.ocrScanViewPlugin = ALOCRScanViewPlugin.init(scanPlugin: self.ocrScanPlugin, scanViewPluginConfig: bottlecapUIConfig); +// +// //Setup ScanView with frame size and the ocrScanViewPlugin +// self.scanView = ALScanView.init(frame: frame, scanViewPlugin: self.ocrScanViewPlugin); +// } catch _ as NSError { +// //Handle error here +// } self.scanView.translatesAutoresizingMaskIntoConstraints = false; @@ -83,26 +83,26 @@ import UIKit /* This method will be called once the view controller and its subviews have appeared on screen */ - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated); - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - self.startAnyline(); - } +// override func viewDidAppear(_ animated: Bool) { +// super.viewDidAppear(animated); +// +// // We use this subroutine to start Anyline. The reason it has its own subroutine is +// // so that we can later use it to restart the scanning process. +// self.startAnyline(); +// } /* Cancel scanning to allow the module to clean up */ - override func viewWillDisappear(_ animated: Bool) { - do { - try self.ocrScanViewPlugin.stop(); - } catch let error as NSError { - print("\(error.debugDescription)"); - } - - super.viewWillDisappear(animated); - } +// override func viewWillDisappear(_ animated: Bool) { +// do { +// try self.ocrScanViewPlugin.stop(); +// } catch let error as NSError { +// print("\(error.debugDescription)"); +// } +// +// super.viewWillDisappear(animated); +// } /* This method is used to tell Anyline to start scanning. It gets called in @@ -111,46 +111,46 @@ import UIKit with cancelOnResult:). When the user dismisses self.identificationView this method will get called again. */ - func startAnyline() { - do { - try self.ocrScanViewPlugin.start(); - } catch let error as NSError { - // Something went wrong. The error object contains the error description - UIAlertView.init(title: "Start Scanning Error", - message: error.debugDescription, - delegate: self, - cancelButtonTitle: "OK").show(); - - } - } +// func startAnyline() { +// do { +// try self.ocrScanViewPlugin.start(); +// } catch let error as NSError { +// // Something went wrong. The error object contains the error description +// UIAlertView.init(title: "Start Scanning Error", +// message: error.debugDescription, +// delegate: self, +// cancelButtonTitle: "OK").show(); +// +// } +// } // MARK: ALOCRScanPluginDelegate /* This is the main delegate method Anyline uses to report its results */ - func anylineOCRScanPlugin(_ anylineOCRScanPlugin: ALOCRScanPlugin, didFind result: ALOCRResult) { - // We are done. Cancel scanning - do { - try self.ocrScanViewPlugin.stop(); - } catch let error as NSError { - print("\(error.debugDescription)"); - } - - // Display an overlay showing the result - let image : UIImage = UIImage(imageLiteralResourceName: "bottle_background"); - let overlay : ALResultOverlayView = ALResultOverlayView(frame: self.view.bounds); - - weak var welf = self; - weak var woverlay: ALResultOverlayView? = overlay; - overlay.setImage(image); - overlay.setText(result.result as String); - overlay.setTouchDownBlock( { () in - // Remove the view when touched and restart scanning - welf?.startAnyline(); - woverlay?.removeFromSuperview(); - }); - - self.view.addSubview(overlay); - } +// func anylineOCRScanPlugin(_ anylineOCRScanPlugin: ALOCRScanPlugin, didFind result: ALOCRResult) { +// // We are done. Cancel scanning +// do { +// try self.ocrScanViewPlugin.stop(); +// } catch let error as NSError { +// print("\(error.debugDescription)"); +// } +// +// // Display an overlay showing the result +// let image : UIImage = UIImage(imageLiteralResourceName: "bottle_background"); +// let overlay : ALResultOverlayView = ALResultOverlayView(frame: self.view.bounds); +// +// weak var welf = self; +// weak var woverlay: ALResultOverlayView? = overlay; +// overlay.setImage(image); +// overlay.setText(result.result as String); +// overlay.setTouchDownBlock( { () in +// // Remove the view when touched and restart scanning +// welf?.startAnyline(); +// woverlay?.removeFromSuperview(); +// }); +// +// self.view.addSubview(overlay); +// } } diff --git a/AnylineExamples/Anyline Examples Source/Bottlecap/bottlecap_config.json b/AnylineExamples/Anyline Examples Source/Bottlecap/bottlecap_config.json index c3c3fa52e..6ebadcc44 100644 --- a/AnylineExamples/Anyline Examples Source/Bottlecap/bottlecap_config.json +++ b/AnylineExamples/Anyline Examples Source/Bottlecap/bottlecap_config.json @@ -1,36 +1,61 @@ { - "viewPlugin" : { - "cutoutConfig" : { - "style": "animated_rect", - "maxWidthPercent": "80%", - "maxHeightPercent": "80%", + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_right" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.pepsi-bottlecap", + "ocrConfig": { + "customCmdFile": "pepsi_code_scanner.ale", + "model": "PepsiCo.any", + "scanMode": "grid" + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "100%", + "maxHeightPercent": "100%", + "width": 500, "alignment": "center", - "width": 300, "ratioFromSize": { "width": 2, "height": 1 }, - "strokeWidth": 2, - "cornerRadius": 5, - "strokeColor": "FFFFFF", - "outerColor": "000000", - "outerAlpha": 0.7, + "offset": { + "x": 0, + "y": 0 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, "cropPadding": { "x": 0, "y": 0 }, - "feedbackStrokeColor": "0099FF" + "cornerRadius": 4, + "strokeColor": "0099ff", + "strokeWidth": 2, + "outerColor": "000000", + "feedbackStrokeColor": "0099FF", + "outerAlpha": 0.3 }, - "scanFeedback" : { + "scanFeedbackConfig": { "style": "rect", - "strokeWidth": 1, + "strokeWidth": 2, + "cornerRadius": 2, "strokeColor": "0099FF", - "fillColor": "220099FF", - "cornerRadius": 10, - "beepOnResult": true, + "fillColor": "330099FF", + "beepOnResult": false, "vibrateOnResult": true, - "blinkAnimationOnResult": true - }, - "cancelOnResult" : true + "blinkAnimationOnResult": false + } } } diff --git a/AnylineExamples/Anyline Examples Source/CattleTag/ViewController/ALCattleTagScanViewController.m b/AnylineExamples/Anyline Examples Source/CattleTag/ViewController/ALCattleTagScanViewController.m index 4c9a4678b..c232af2d5 100644 --- a/AnylineExamples/Anyline Examples Source/CattleTag/ViewController/ALCattleTagScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/CattleTag/ViewController/ALCattleTagScanViewController.m @@ -9,12 +9,12 @@ #import #import "AnylineExamples-Swift.h" -@interface ALCattleTagScanViewController () +@interface ALCattleTagScanViewController () // // The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *cattleTagScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *cattleTagScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALOCRScanViewPlugin *cattleTagScanViewPlugin; +//@property (nonatomic, strong) ALOCRScanPlugin *cattleTagScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; @end @@ -27,28 +27,28 @@ - (void)viewDidLoad { // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen CGRect frame = [self scanViewFrame]; - ALCattleTagConfig *config = [[ALCattleTagConfig alloc] init]; - - NSError *error = nil; - - self.cattleTagScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.cattleTagScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.cattleTagScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"cow_tag_capture_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.cattleTagScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.cattleTagScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - NSAssert(self.cattleTagScanViewPlugin, @"Setup Error: %@", error.debugDescription); - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.cattleTagScanViewPlugin]; - - //Enable Zoom Gesture - [self.scanView enableZoomPinchGesture:YES]; +// ALCattleTagConfig *config = [[ALCattleTagConfig alloc] init]; +// +// NSError *error = nil; +// +// self.cattleTagScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" +// delegate:self +// ocrConfig:config +// error:&error]; +// NSAssert(self.cattleTagScanPlugin, @"Setup Error: %@", error.debugDescription); +// [self.cattleTagScanPlugin addInfoDelegate:self]; +// +// NSString *confPath = [[NSBundle mainBundle] pathForResource:@"cow_tag_capture_config" ofType:@"json"]; +// ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +// +// self.cattleTagScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.cattleTagScanPlugin +// scanViewPluginConfig:scanViewPluginConfig]; +// NSAssert(self.cattleTagScanViewPlugin, @"Setup Error: %@", error.debugDescription); +// +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.cattleTagScanViewPlugin]; +// +// //Enable Zoom Gesture +// [self.scanView enableZoomPinchGesture:YES]; // After setup is complete we add the scanView to the view of this view controller [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; @@ -63,7 +63,7 @@ - (void)viewDidLoad { //Start Camera: [self.scanView startCamera]; - [self startListeningForMotion]; +// [self startListeningForMotion]; self.controllerType = ALScanHistoryCattleTag; } @@ -71,21 +71,21 @@ - (void)viewDidLoad { /* This method will be called once the view controller and its subviews have appeared on screen */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} +//-(void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// +// // We use this subroutine to start Anyline. The reason it has its own subroutine is +// // so that we can later use it to restart the scanning process. +// [self startAnyline]; +//} /* Cancel scanning to allow the module to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.cattleTagScanViewPlugin stopAndReturnError:nil]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [self.cattleTagScanViewPlugin stopAndReturnError:nil]; +//} /* This method is used to tell Anyline to start scanning. It gets called in @@ -94,26 +94,26 @@ is found scanning will stop automatically (you can change this behaviour with cancelOnResult:). When the user dismisses self.identificationView this method will get called again. */ -- (void)startAnyline { - [self startPlugin:self.cattleTagScanViewPlugin]; -} +//- (void)startAnyline { +// [self startPlugin:self.cattleTagScanViewPlugin]; +//} #pragma mark -- AnylineOCRModuleDelegate /* This is the main delegate method Anyline uses to report its results */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin - didFindResult:(ALOCRResult *)result { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Cattle Tag Number" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.cattleTagScanViewPlugin completion:^{ - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} +//- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin +// didFindResult:(ALOCRResult *)result { +// NSMutableArray *resultData = [[NSMutableArray alloc] init]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Cattle Tag Number" value:result.result shouldSpellOutValue:YES]]; +// NSString *jsonString = [self JSONStringFromResultData:resultData]; +// +// __weak __block typeof(self) weakSelf = self; +// [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.cattleTagScanViewPlugin completion:^{ +// ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; +// vc.imagePrimary = result.image; +// [weakSelf.navigationController pushViewController:vc animated:YES]; +// }]; +//} @end diff --git a/AnylineExamples/Anyline Examples Source/CattleTag/cow_tag_capture_config.json b/AnylineExamples/Anyline Examples Source/CattleTag/cow_tag_capture_config.json index 5b2797ab7..f11426169 100644 --- a/AnylineExamples/Anyline Examples Source/CattleTag/cow_tag_capture_config.json +++ b/AnylineExamples/Anyline Examples Source/CattleTag/cow_tag_capture_config.json @@ -11,8 +11,8 @@ "height": 1 }, "strokeWidth": 2, - "cornerRadius": 10, - "strokeColor": "FFFFFF", + "cornerRadius": 4, + "strokeColor": "0099FF", "outerColor": "000000", "outerAlpha": 0.3, "feedbackStrokeColor": "0099FF", diff --git a/AnylineExamples/Anyline Examples Source/CompositeScanning/ALParallelMeterWithJSONScanViewController.m b/AnylineExamples/Anyline Examples Source/CompositeScanning/ALParallelMeterWithJSONScanViewController.m index 17b5cef75..0ada8b0f9 100644 --- a/AnylineExamples/Anyline Examples Source/CompositeScanning/ALParallelMeterWithJSONScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/CompositeScanning/ALParallelMeterWithJSONScanViewController.m @@ -1,18 +1,19 @@ +#import #import "ALParallelMeterWithJSONScanViewController.h" #import "UIViewController+ALExamplesAdditions.h" const bool parallel_scan_view_uses_json_config_for_setup = true; NSString * const parallel_scan_plugin_config_json_filename = @"meter_barcode_parallel"; // without the .json extension -@interface ALParallelMeterWithJSONScanViewController () +@interface ALParallelMeterWithJSONScanViewController () // -@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; +//@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; +// +//@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin; +// +//@property (nonatomic, strong) ALParallelScanViewPluginComposite *parallelScanViewPlugin; -@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin; - -@property (nonatomic, strong) ALParallelScanViewPluginComposite *parallelScanViewPlugin; - -@property (nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALScanView *scanView; @end @@ -34,16 +35,16 @@ - (void)setupAndStartPlugins { [self setupPluginsWithManually]; } - NSAssert(self.parallelScanViewPlugin, @"parallelScanViewPlugin was not set up properly!"); - - self.scanView = [[ALScanView alloc] initWithFrame:[self scanViewFrame] - scanViewPlugin:self.parallelScanViewPlugin]; +// NSAssert(self.parallelScanViewPlugin, @"parallelScanViewPlugin was not set up properly!"); +// +// self.scanView = [[ALScanView alloc] initWithFrame:[self scanViewFrame] +// scanViewPlugin:self.parallelScanViewPlugin]; [self.view addSubview:self.scanView]; [self.scanView startCamera]; - [self.parallelScanViewPlugin startAndReturnError:nil]; +// [self.parallelScanViewPlugin startAndReturnError:nil]; } - (void)setupPluginsWithJSON { @@ -53,26 +54,26 @@ - (void)setupPluginsWithJSON { // NOTE: we made an assumption here that the JSON is an appropriately-defined config of // a parallel scan view with two members: a barcode scan plugin and a meter scan plugin. - self.parallelScanViewPlugin = (ALParallelScanViewPluginComposite *)[ALAbstractScanViewPluginComposite - scanViewPluginForConfigDict:self.configDict - delegate:self - error:&error]; - - for (ALAbstractScanViewPlugin *scanPlugin in self.parallelScanViewPlugin.childPlugins) { - if ([scanPlugin isKindOfClass:ALBarcodeScanViewPlugin.class]) { - self.barcodeScanViewPlugin = (ALBarcodeScanViewPlugin *)scanPlugin; - } else if ([scanPlugin isKindOfClass:ALMeterScanViewPlugin.class]) { - self.meterScanViewPlugin = (ALMeterScanViewPlugin *)scanPlugin; - } - } +// self.parallelScanViewPlugin = (ALParallelScanViewPluginComposite *)[ALAbstractScanViewPluginComposite +// scanViewPluginForConfigDict:self.configDict +// delegate:self +// error:&error]; +// +// for (ALAbstractScanViewPlugin *scanPlugin in self.parallelScanViewPlugin.childPlugins) { +// if ([scanPlugin isKindOfClass:ALBarcodeScanViewPlugin.class]) { +// self.barcodeScanViewPlugin = (ALBarcodeScanViewPlugin *)scanPlugin; +// } else if ([scanPlugin isKindOfClass:ALMeterScanViewPlugin.class]) { +// self.meterScanViewPlugin = (ALMeterScanViewPlugin *)scanPlugin; +// } +// } // (Optional) If desired, you may set scan delegates for individual scan view plugins, // allowing you to read scan results individually as they detected: - NSAssert(self.barcodeScanViewPlugin != nil, @"barcodeScanViewPlugin should not be nil"); - NSAssert(self.meterScanViewPlugin != nil, @"meterScanViewPlugin should not be nil"); +// NSAssert(self.barcodeScanViewPlugin != nil, @"barcodeScanViewPlugin should not be nil"); +// NSAssert(self.meterScanViewPlugin != nil, @"meterScanViewPlugin should not be nil"); - [self.barcodeScanViewPlugin.barcodeScanPlugin addDelegate:self]; - [self.meterScanViewPlugin.meterScanPlugin addDelegate:self]; +// [self.barcodeScanViewPlugin.barcodeScanPlugin addDelegate:self]; +// [self.meterScanViewPlugin.meterScanPlugin addDelegate:self]; } @@ -82,22 +83,22 @@ - (void)setupPluginsWithManually { NSError *error = nil; // Meter Plugin - ALMeterScanPlugin *meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"METER" - delegate:self - error:&error]; - self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:meterScanPlugin]; - - // Barcode Plugin - ALBarcodeScanPlugin *barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] initWithPluginID:@"BARCODE" - delegate:self - error:&error]; - [barcodeScanPlugin setBarcodeFormatOptions:@[ kCodeTypeAll ]]; - self.barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] - initWithScanPlugin:barcodeScanPlugin]; - - // Parallel Scan View Plugin - self.parallelScanViewPlugin = [[ALParallelScanViewPluginComposite alloc] - initWithPluginID:@"Energy and Meter Parallel"]; +// ALMeterScanPlugin *meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"METER" +// delegate:self +// error:&error]; +// self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:meterScanPlugin]; +// +// // Barcode Plugin +// ALBarcodeScanPlugin *barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] initWithPluginID:@"BARCODE" +// delegate:self +// error:&error]; +// [barcodeScanPlugin setBarcodeFormatOptions:@[ kCodeTypeAll ]]; +// self.barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] +// initWithScanPlugin:barcodeScanPlugin]; +// +// // Parallel Scan View Plugin +// self.parallelScanViewPlugin = [[ALParallelScanViewPluginComposite alloc] +// initWithPluginID:@"Energy and Meter Parallel"]; // (Optional) - make certain child plugins return without a scan result after a timeout // @@ -110,19 +111,19 @@ - (void)setupPluginsWithManually { // on before the delegate callback is invoked. // When not explicitly set, the default delay is 3.0 seconds. - self.parallelScanViewPlugin.optionalTimeoutDelay = @3.5; - - // You can make a member ScanViewPlugin (in this case, for the barcode) by setting its - // isOptional property to YES. (NOTE: make sure to set this BEFORE it is added to the - // parallel plugin.) - self.barcodeScanViewPlugin.isOptional = YES; - - // Add the component plugins. - [self.parallelScanViewPlugin addPlugin:self.meterScanViewPlugin]; - [self.parallelScanViewPlugin addPlugin:self.barcodeScanViewPlugin]; - - // make oneself a ALCompositeScanPluginDelegate (for the aggregated results) - [self.parallelScanViewPlugin addDelegate:self]; +// self.parallelScanViewPlugin.optionalTimeoutDelay = @3.5; +// +// // You can make a member ScanViewPlugin (in this case, for the barcode) by setting its +// // isOptional property to YES. (NOTE: make sure to set this BEFORE it is added to the +// // parallel plugin.) +// self.barcodeScanViewPlugin.isOptional = YES; +// +// // Add the component plugins. +// [self.parallelScanViewPlugin addPlugin:self.meterScanViewPlugin]; +// [self.parallelScanViewPlugin addPlugin:self.barcodeScanViewPlugin]; +// +// // make oneself a ALCompositeScanPluginDelegate (for the aggregated results) +// [self.parallelScanViewPlugin addDelegate:self]; } - (void)displayResults:(NSString *)resultsMsg { @@ -134,7 +135,7 @@ - (void)displayResults:(NSString *)resultsMsg { style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - [weakSelf.parallelScanViewPlugin startAndReturnError:nil]; +// [weakSelf.parallelScanViewPlugin startAndReturnError:nil]; }]]; [self.navigationController presentViewController:alertController animated:YES completion:nil]; @@ -156,53 +157,53 @@ - (NSDictionary * _Nonnull)configDict { // MARK: - ALCompositeScanPluginDelegate -- (void)anylineCompositeScanPlugin:(ALAbstractScanViewPluginComposite * _Nonnull)anylineCompositeScanPlugin - didFindResult:(ALCompositeResult * _Nonnull)scanResult { - - // this method is executed when all 'required' component plugins have - // been scanned. - - NSMutableArray *resultStrs = [NSMutableArray arrayWithCapacity:2]; - for (NSString *key in scanResult.result.allKeys) { - id res = scanResult.result[key]; - if ([res isKindOfClass:ALMeterResult.class]) { - [resultStrs addObject: - [NSString stringWithFormat:@"meter result: %@", - [(ALMeterResult *)res result]] - ]; - } else if ([res isKindOfClass:ALBarcodeResult.class]) { - [resultStrs addObject: - [NSString stringWithFormat:@"barcode result: %@", - [(ALBarcodeResult *)res result].firstObject.value] - ]; - } - } - NSString *message = [resultStrs componentsJoinedByString:@" | "]; - NSLog(@"Parallel Scan: aggregate result: %@", message); - [self displayResults:message]; -} - -// MARK: - ALBarcodeScanPluginDelegate - -- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin * _Nonnull)anylineBarcodeScanPlugin - didFindResult:(ALBarcodeResult * _Nonnull)scanResult { - NSString *barcodeResultStr = [[scanResult.result firstObject] value]; - - // by setting a ALBarcodeScanPluginDelegate you can detect a barcode scan before the - // composite (parallel) plugin delegate is called. - NSLog(@"Parallel Scan: barcode result: %@", barcodeResultStr); -} - - -// MARK: - ALMeterScanPluginDelegate - -- (void)anylineMeterScanPlugin:(ALMeterScanPlugin * _Nonnull)anylineMeterScanPlugin - didFindResult:(ALMeterResult * _Nonnull)scanResult { - - // by setting a ALMeterScanPluginDelegate you can detect a meter scan before the - // composite (parallel) plugin delegate is called. - NSString *meterResultStr = scanResult.result; - NSLog(@"Parallel Scan: meter result: %@", meterResultStr); -} +//- (void)anylineCompositeScanPlugin:(ALAbstractScanViewPluginComposite * _Nonnull)anylineCompositeScanPlugin +// didFindResult:(ALCompositeResult * _Nonnull)scanResult { +// +// // this method is executed when all 'required' component plugins have +// // been scanned. +// +// NSMutableArray *resultStrs = [NSMutableArray arrayWithCapacity:2]; +// for (NSString *key in scanResult.result.allKeys) { +// id res = scanResult.result[key]; +// if ([res isKindOfClass:ALMeterResult.class]) { +// [resultStrs addObject: +// [NSString stringWithFormat:@"meter result: %@", +// [(ALMeterResult *)res result]] +// ]; +// } else if ([res isKindOfClass:ALBarcodeResult.class]) { +// [resultStrs addObject: +// [NSString stringWithFormat:@"barcode result: %@", +// [(ALBarcodeResult *)res result].firstObject.value] +// ]; +// } +// } +// NSString *message = [resultStrs componentsJoinedByString:@" | "]; +// NSLog(@"Parallel Scan: aggregate result: %@", message); +// [self displayResults:message]; +//} +// +//// MARK: - ALBarcodeScanPluginDelegate +// +//- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin * _Nonnull)anylineBarcodeScanPlugin +// didFindResult:(ALBarcodeResult * _Nonnull)scanResult { +// NSString *barcodeResultStr = [[scanResult.result firstObject] value]; +// +// // by setting a ALBarcodeScanPluginDelegate you can detect a barcode scan before the +// // composite (parallel) plugin delegate is called. +// NSLog(@"Parallel Scan: barcode result: %@", barcodeResultStr); +//} +// +// +//// MARK: - ALMeterScanPluginDelegate +// +//- (void)anylineMeterScanPlugin:(ALMeterScanPlugin * _Nonnull)anylineMeterScanPlugin +// didFindResult:(ALMeterResult * _Nonnull)scanResult { +// +// // by setting a ALMeterScanPluginDelegate you can detect a meter scan before the +// // composite (parallel) plugin delegate is called. +// NSString *meterResultStr = scanResult.result; +// NSLog(@"Parallel Scan: meter result: %@", meterResultStr); +//} @end diff --git a/AnylineExamples/Anyline Examples Source/CompositeScanning/meter_barcode_parallel.json b/AnylineExamples/Anyline Examples Source/CompositeScanning/meter_barcode_parallel.json index 4ac06d453..9c1ef7667 100644 --- a/AnylineExamples/Anyline Examples Source/CompositeScanning/meter_barcode_parallel.json +++ b/AnylineExamples/Anyline Examples Source/CompositeScanning/meter_barcode_parallel.json @@ -29,7 +29,7 @@ }, "scanFeedback": { "style": "CONTOUR_RECT", - "strokeColor": "FFFFFF", + "strokeColor": "0099FF", "strokeWidth": 2, "fillColor": "220099FF", "cornerRadius": 2, @@ -61,9 +61,9 @@ }, "strokeWidth": 2, "cornerRadius": 2, - "strokeColor": "FFFFFF", + "strokeColor": "0099FF", "outerColor": "000000", - "outerAlpha": 0.75, + "outerAlpha": 0.3, "feedbackStrokeColor": "0099FF", "offset": { "x": 0, diff --git a/AnylineExamples/Anyline Examples Source/ContainerScannerHorizontal/ViewController/ALContainerScanViewController.h b/AnylineExamples/Anyline Examples Source/ContainerScanner/ViewController/ALContainerScanViewController.h similarity index 100% rename from AnylineExamples/Anyline Examples Source/ContainerScannerHorizontal/ViewController/ALContainerScanViewController.h rename to AnylineExamples/Anyline Examples Source/ContainerScanner/ViewController/ALContainerScanViewController.h diff --git a/AnylineExamples/Anyline Examples Source/ContainerScanner/ViewController/ALContainerScanViewController.m b/AnylineExamples/Anyline Examples Source/ContainerScanner/ViewController/ALContainerScanViewController.m new file mode 100644 index 000000000..f125119d5 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/ContainerScanner/ViewController/ALContainerScanViewController.m @@ -0,0 +1,99 @@ +#import "ALContainerScanViewController.h" +#import +#import "AnylineExamples-Swift.h" +#import "UIColor+ALExamplesAdditions.h" + +NSString * const kContainerVC_configJSONFilename = @"horizontal_container_scanner_capture_config"; +NSString * const kVerticalContainerVC_configJSONFilename = @"vertical_container_scanner_capture_config"; +@interface ALContainerScanViewController () + +@property (nonatomic, strong) ALScanViewPlugin *scanViewPlugin; +// @property (nullable, nonatomic, strong) ALScanView *scanView; + +@property (assign, nonatomic) BOOL isVertical; + +@end + +@implementation ALContainerScanViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.isVertical = [self.title localizedCaseInsensitiveContainsString:@"Vertical"]; + if (_isVertical) { + self.title = @"Vertical Shipping Container"; + } else { + self.title = @"Horizontal Shipping Container"; + } + // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen + self.controllerType = ALScanHistoryContainer; + + [self reloadScanView]; + + [self setColors]; + +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.scanViewPlugin startWithError:nil]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [self.scanViewPlugin stop]; +} + +- (void)reloadScanView { + NSDictionary *configJSONDictionary; + + if (self.isVertical) { + configJSONDictionary = [[self configJSONStrWithFilename:kVerticalContainerVC_configJSONFilename] asJSONObject]; + } else { + configJSONDictionary = [[self configJSONStrWithFilename:kContainerVC_configJSONFilename] asJSONObject]; + } + ALScanViewPlugin *scanViewPlugin = [[ALScanViewPlugin alloc] initWithJSONDictionary:configJSONDictionary error:nil]; + scanViewPlugin.scanPlugin.delegate = self; + + [self.scanView stopCamera]; + if (self.scanView) { + [self.scanView removeFromSuperview]; + } + + self.scanViewPlugin = scanViewPlugin; + + ALScanViewConfig *scanViewConfig = [ALScanViewConfig withJSONDictionary:configJSONDictionary]; + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:scanViewPlugin + scanViewConfig:scanViewConfig + error:nil]; + + [self installScanView:self.scanView]; // call startCamera and start the plugin outside + + // we've just readded the ScanView, make sure it goes beneath the other views. + [self.view sendSubviewToBack:self.scanView]; + + [self.scanView startCamera]; + +} + +#pragma mark -- ALScanPluginDelegate + +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + NSArray *resultData = scanResult.pluginResult.containerResult.resultEntryList; + NSString *resultDataJSONStr = [ALResultEntry JSONStringFromList:resultData]; + __weak ALContainerScanViewController *weakSelf = self; + [self anylineDidFindResult:resultDataJSONStr + barcodeResult:@"" + image:scanResult.croppedImage + scanPlugin:scanPlugin + viewPlugin:self.scanViewPlugin + completion:^{ + ALResultViewController *vc = [[ALResultViewController alloc] + initWithResults:resultData]; + vc.imagePrimary = scanResult.croppedImage; + + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]; +} + +@end diff --git a/AnylineExamples/Anyline Examples Source/ContainerScanner/horizontal_container_scanner_capture_config.json b/AnylineExamples/Anyline Examples Source/ContainerScanner/horizontal_container_scanner_capture_config.json new file mode 100644 index 000000000..1f81bee4f --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/ContainerScanner/horizontal_container_scanner_capture_config.json @@ -0,0 +1,61 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_right" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.horizontal-container", + "containerConfig": { + "scanMode": "HORIZONTAL" + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "style": "rect", + "animation": "none", + "maxWidthPercent": "70%", + "alignment": "top_half", + "ratioFromSize": { + "width": 62, + "height": 9, + }, + "offset": { + "x": 0, + "y": 0 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "cropPadding": { + "x": 0, + "y": 0 + }, + "cornerRadius": 4, + "strokeColor": "0099ff", + "strokeWidth": 2, + "outerColor": "000000", + "feedbackStrokeColor": "0099FF", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "contour_rect", + "animation": "traverse_multi", + "animationDuration" : 250, + "strokeWidth": 2, + "cornerRadius": 2, + "strokeColor": "0099FF", + "fillColor": "330099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true + } + } +} + diff --git a/AnylineExamples/Anyline Examples Source/ContainerScanner/vertical_container_scanner_capture_config.json b/AnylineExamples/Anyline Examples Source/ContainerScanner/vertical_container_scanner_capture_config.json new file mode 100644 index 000000000..38c6b8552 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/ContainerScanner/vertical_container_scanner_capture_config.json @@ -0,0 +1,61 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_right" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.vertical-container", + "containerConfig": { + "scanMode": "VERTICAL" + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "style": "rect", + "animation": "none", + "maxWidthPercent": "10%", + "alignment": "center", + "ratioFromSize": { + "width": 9, + "height": 62, + }, + "offset": { + "x": 0, + "y": 0 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "cropPadding": { + "x": 0, + "y": 0 + }, + "cornerRadius": 4, + "strokeColor": "0099ff", + "strokeWidth": 2, + "outerColor": "000000", + "feedbackStrokeColor": "0099FF", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "contour_rect", + "animation": "traverse_multi", + "animationDuration" : 250, + "strokeWidth": 2, + "cornerRadius": 2, + "strokeColor": "0099FF", + "fillColor": "330099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true + } + } +} + diff --git a/AnylineExamples/Anyline Examples Source/ContainerScannerHorizontal/ViewController/ALContainerScanViewController.m b/AnylineExamples/Anyline Examples Source/ContainerScannerHorizontal/ViewController/ALContainerScanViewController.m deleted file mode 100644 index 8b0efa0cc..000000000 --- a/AnylineExamples/Anyline Examples Source/ContainerScannerHorizontal/ViewController/ALContainerScanViewController.m +++ /dev/null @@ -1,134 +0,0 @@ -// -// ALShippingContainerScanViewController.m -// AnylineExamples -// -// Created by Daniel Albertini on 09.04.18. -// - -#import "ALContainerScanViewController.h" -#import -#import "AnylineExamples-Swift.h" -#import "UIColor+ALExamplesAdditions.h" - -@interface ALContainerScanViewController () - -// The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *containerScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *containerScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; - -@end - -@implementation ALContainerScanViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"Horizontal Shipping Container"; - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - ALContainerConfig *config = [[ALContainerConfig alloc] init]; - config.scanMode = ALHorizontal; - - NSError *error = nil; - - self.containerScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.containerScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.containerScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"container_scanner_capture_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.containerScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.containerScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - [self.containerScanViewPlugin addScanViewPluginDelegate:self]; - NSAssert(self.containerScanViewPlugin, @"Setup Error: %@", error.debugDescription); - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.containerScanViewPlugin]; - - //Enable Zoom Gesture - [self.scanView enableZoomPinchGesture:YES]; - - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; - - //Enable Zoom Gesture for the scanView - [self.scanView enableZoomPinchGesture:YES]; - - self.controllerType = ALScanHistoryContainer; -} - -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} - -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.containerScanViewPlugin stopAndReturnError:nil]; -} - -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.containerScanViewPlugin]; -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} - -#pragma mark -- ALOCRScanPluginDelegate - -/* - This is the main delegate method Anyline uses to report its results - */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin - didFindResult:(ALOCRResult *)result { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Shipping Container Number" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.containerScanViewPlugin completion:^{ - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/ContainerScannerHorizontal/container_scanner_capture_config.json b/AnylineExamples/Anyline Examples Source/ContainerScannerHorizontal/container_scanner_capture_config.json deleted file mode 100644 index 0b280aac8..000000000 --- a/AnylineExamples/Anyline Examples Source/ContainerScannerHorizontal/container_scanner_capture_config.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "viewPlugin" : { - "cutoutConfig" : { - "style": "rect", - "maxWidthPercent": "70%", - "alignment": "top_half", - "ratioFromSize": { - "width": 62, - "height": 9 - }, - "outerColor": "000000", - "outerAlpha": 0.3, - "strokeWidth": 1, - "strokeColor": "FFFFFF", - "cornerRadius": 2, - "feedbackStrokeColor": "0099FF", - }, - "scanFeedback" : { - "animation": "traverse_multi", - "animationDuration" : 250, - "style": "contour_rect", - "strokeWidth": 2, - "strokeColor": "0099FF", - "beepOnResult": true, - "vibrateOnResult": true, - "blinkAnimationOnResult": true - }, - "cancelOnResult" : true - } -} diff --git a/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/ViewController/ALVerticalContainerScanViewController.h b/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/ViewController/ALVerticalContainerScanViewController.h deleted file mode 100644 index 25555e475..000000000 --- a/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/ViewController/ALVerticalContainerScanViewController.h +++ /dev/null @@ -1,15 +0,0 @@ - -// -// ALContainerScanScanViewController.h -// AnylineExamples -// -// Created by Daniel Albertini on 09.04.18. -// - -#import - -#import "ALBaseScanViewController.h" - -@interface ALVerticalContainerScanViewController : ALBaseScanViewController - -@end diff --git a/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/ViewController/ALVerticalContainerScanViewController.m b/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/ViewController/ALVerticalContainerScanViewController.m deleted file mode 100644 index 05c6c6b5a..000000000 --- a/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/ViewController/ALVerticalContainerScanViewController.m +++ /dev/null @@ -1,136 +0,0 @@ -// -// ALShippingContainerScanViewController.m -// AnylineExamples -// -// Created by Daniel Albertini on 09.04.18. -// - -#import "ALVerticalContainerScanViewController.h" -#import -#import "AnylineExamples-Swift.h" - -@interface ALVerticalContainerScanViewController () - -// The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *containerScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *containerScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; - -@end - -@implementation ALVerticalContainerScanViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"Vertical Shipping Container"; - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - ALContainerConfig *config = [[ALContainerConfig alloc] init]; - config.scanMode = ALVertical; - - NSError *error = nil; - - self.containerScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.containerScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.containerScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"vertical_container_scanner_capture_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.containerScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.containerScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - [self.containerScanViewPlugin addScanViewPluginDelegate:self]; - NSAssert(self.containerScanViewPlugin, @"Setup Error: %@", error.debugDescription); - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.containerScanViewPlugin]; - - //Enable Zoom Gesture - [self.scanView enableZoomPinchGesture:YES]; - - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; - - //Enable Zoom Gesture for the scanView - [self.scanView enableZoomPinchGesture:YES]; - - self.controllerType = ALScanHistoryContainer; -} - -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} - -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.containerScanViewPlugin stopAndReturnError:nil]; -} - -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.containerScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} - - -#pragma mark -- AnylineOCRModuleDelegate - -/* - This is the main delegate method Anyline uses to report its results - */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin - didFindResult:(ALOCRResult *)result { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Shipping Container Number" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.containerScanViewPlugin completion:^{ - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/vertical_container_scanner_capture_config.json b/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/vertical_container_scanner_capture_config.json deleted file mode 100644 index a8f29e2a0..000000000 --- a/AnylineExamples/Anyline Examples Source/ContainerScannerVertical/vertical_container_scanner_capture_config.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "viewPlugin" : { - "cutoutConfig" : { - "style": "rect", - "maxWidthPercent": "10%", - "alignment": "top_half", - "ratioFromSize": { - "width": 9, - "height": 62 - }, - "outerColor": "000000", - "outerAlpha": 0.3, - "strokeWidth": 1, - "strokeColor": "FFFFFF", - "cornerRadius": 2, - "feedbackStrokeColor": "0099FF", - }, - "scanFeedback" : { - "animation": "traverse_multi", - "animationDuration" : 250, - "style": "contour_rect", - "strokeWidth": 2, - "strokeColor": "0099FF", - "beepOnResult": true, - "vibrateOnResult": true, - "blinkAnimationOnResult": true - }, - "cancelOnResult" : true - } -} diff --git a/AnylineExamples/Anyline Examples Source/CoreData/Model/ScanHistory+CoreDataClass.h b/AnylineExamples/Anyline Examples Source/CoreData/Model/ScanHistory+CoreDataClass.h index 6c3679431..78e25901c 100644 --- a/AnylineExamples/Anyline Examples Source/CoreData/Model/ScanHistory+CoreDataClass.h +++ b/AnylineExamples/Anyline Examples Source/CoreData/Model/ScanHistory+CoreDataClass.h @@ -49,6 +49,9 @@ typedef enum : NSUInteger { ALScanHistoryUniversalID = 31, ALScanHistoryBarcodePDF417 = 32, ALScanHistoryBottleCapPepsi = 33, + ALScanHistoryCommercialTireID = 34, + ALScanHistoryTireSizeConfiguration = 35, + ALScanHistoryVehicleRegistrationCertificate = 36, //be sure to add any new types to ALScanHistoryType_toString! } ALScanHistoryType; diff --git a/AnylineExamples/Anyline Examples Source/CoreData/Model/ScanHistory+CoreDataClass.m b/AnylineExamples/Anyline Examples Source/CoreData/Model/ScanHistory+CoreDataClass.m index 6874b06db..3049115d3 100644 --- a/AnylineExamples/Anyline Examples Source/CoreData/Model/ScanHistory+CoreDataClass.m +++ b/AnylineExamples/Anyline Examples Source/CoreData/Model/ScanHistory+CoreDataClass.m @@ -38,11 +38,14 @@ [ALScanHistoryDrivingLicense] = @"Driving License", // deprecated [ALScanHistoryGermanIDFront] = @"German ID Front", // deprecated [ALScanHistoryCattleTag] = @"Cattle Tag", - [ALScanHistoryTIN] = @"TIN Scanner", + [ALScanHistoryTIN] = @"Tire Identification Number", + [ALScanHistoryTireSizeConfiguration] = @"Tire Size Configuration", + [ALScanHistoryCommercialTireID] = @"Commercial Tire ID", [ALScanHistoryNFC] = @"NFC Reader", [ALScanHistoryUniversalID] = @"Universal ID", [ALScanHistoryBarcodePDF417] = @"PDF 417", [ALScanHistoryBottleCapPepsi] = @"Pepsi Code", + [ALScanHistoryVehicleRegistrationCertificate] = @"Vehicle Registration Certificate", }; @implementation ScanHistory diff --git a/AnylineExamples/Anyline Examples Source/Document/ViewController/ALDocumentScanViewController.m b/AnylineExamples/Anyline Examples Source/Document/ViewController/ALDocumentScanViewController.m index 4ef3410df..a0a8bcc49 100644 --- a/AnylineExamples/Anyline Examples Source/Document/ViewController/ALDocumentScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/Document/ViewController/ALDocumentScanViewController.m @@ -7,12 +7,12 @@ @class AnylineDocumentModuleView; -@interface ALDocumentScanViewController () +@interface ALDocumentScanViewController () // // The Anyline plugin used for Document -@property (nonatomic, strong) ALDocumentScanViewPlugin *documentScanViewPlugin; -@property (nonatomic, strong) ALDocumentScanPlugin *documentScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALDocumentScanViewPlugin *documentScanViewPlugin; +//@property (nonatomic, strong) ALDocumentScanPlugin *documentScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; @property (nonatomic, strong) ALRoundedView *roundedView; @property (nonatomic, assign) NSInteger showingLabel; @@ -33,27 +33,27 @@ - (void)viewDidLoad { NSError *error = nil; - self.documentScanPlugin = [[ALDocumentScanPlugin alloc] initWithPluginID:@"DOCUMENT" delegate:self error:&error]; - NSAssert(self.documentScanPlugin, @"Setup Error: %@", error.debugDescription); - self.documentScanPlugin.justDetectCornersIfPossible = NO; - [self.documentScanPlugin addInfoDelegate:self]; +// self.documentScanPlugin = [[ALDocumentScanPlugin alloc] initWithPluginID:@"DOCUMENT" delegate:self error:&error]; +// NSAssert(self.documentScanPlugin, @"Setup Error: %@", error.debugDescription); +// self.documentScanPlugin.justDetectCornersIfPossible = NO; +// [self.documentScanPlugin addInfoDelegate:self]; - self.documentScanViewPlugin = [[ALDocumentScanViewPlugin alloc] initWithScanPlugin:self.documentScanPlugin]; - NSAssert(self.documentScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.documentScanViewPlugin addScanViewPluginDelegate:self]; +// self.documentScanViewPlugin = [[ALDocumentScanViewPlugin alloc] initWithScanPlugin:self.documentScanPlugin]; +// NSAssert(self.documentScanViewPlugin, @"Setup Error: %@", error.debugDescription); +// [self.documentScanViewPlugin addScanViewPluginDelegate:self]; - [self.documentScanViewPlugin setValue:self forKey:@"tmpOutlineDelegate"]; - self.scanView = [[ALScanView alloc] initWithFrame:frame - scanViewPlugin:self.documentScanViewPlugin - cameraConfig:[ALCameraConfig defaultDocumentCameraConfig] - flashButtonConfig:[ALFlashButtonConfig defaultFlashConfig]]; +// [self.documentScanViewPlugin setValue:self forKey:@"tmpOutlineDelegate"]; +// self.scanView = [[ALScanView alloc] initWithFrame:frame +// scanViewPlugin:self.documentScanViewPlugin +// cameraConfig:[ALCameraConfig defaultDocumentCameraConfig] +// flashButtonConfig:[ALFlashButtonConfig defaultFlashConfig]]; // Stop scanning after a result has been found // self.documentScanViewPlugin - [self.documentScanPlugin setPostProcessingEnabled:YES]; +// [self.documentScanPlugin setPostProcessingEnabled:YES]; self.controllerType = ALScanHistoryDocument; - self.documentScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; +// self.documentScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; // After setup is complete we add the scanView to the view of this view controller [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; @@ -81,97 +81,97 @@ - (void)viewDidLoad { /* This method will be called once the view controller and its subviews have appeared on screen */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self startPlugin:self.documentScanViewPlugin]; -} +//-(void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// [self startPlugin:self.documentScanViewPlugin]; +//} /* Cancel scanning to allow the module to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.documentScanViewPlugin stopAndReturnError:nil]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [self.documentScanViewPlugin stopAndReturnError:nil]; +//} #pragma mark -- AnylineDocumentModuleDelegate /* This is the main delegate method Anyline uses to report its scanned codes */ -- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin - hasResult:(UIImage *)transformedImage - fullImage:(UIImage *)fullFrame - documentCorners:(ALSquare *)corners { - UIViewController *viewController = [[UIViewController alloc] init]; - UIImageView *imageView = [[UIImageView alloc] initWithFrame:viewController.view.bounds]; - imageView.center = CGPointMake(imageView.center.x, imageView.center.y + 30); - imageView.contentMode = UIViewContentModeScaleAspectFit; - imageView.image = transformedImage; - [viewController.view addSubview:imageView]; - [self.navigationController pushViewController:viewController animated:YES]; -} +//- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin +// hasResult:(UIImage *)transformedImage +// fullImage:(UIImage *)fullFrame +// documentCorners:(ALSquare *)corners { +// UIViewController *viewController = [[UIViewController alloc] init]; +// UIImageView *imageView = [[UIImageView alloc] initWithFrame:viewController.view.bounds]; +// imageView.center = CGPointMake(imageView.center.x, imageView.center.y + 30); +// imageView.contentMode = UIViewContentModeScaleAspectFit; +// imageView.image = transformedImage; +// [viewController.view addSubview:imageView]; +// [self.navigationController pushViewController:viewController animated:YES]; +//} /* This method receives errors that occured during the scan. */ -- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin - reportsPictureProcessingFailure:(ALDocumentError)error { - [self showUserLabel:error]; -} +//- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin +// reportsPictureProcessingFailure:(ALDocumentError)error { +// [self showUserLabel:error]; +//} /* This method receives errors that occured during the scan. */ -- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin - reportsPreviewProcessingFailure:(ALDocumentError)error { - [self showUserLabel:error]; -} +//- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin +// reportsPreviewProcessingFailure:(ALDocumentError)error { +// [self showUserLabel:error]; +//} #pragma mark -- Helper Methods /* Shows a little round label at the bottom of the screen to inform the user what happended */ -- (void)showUserLabel:(ALDocumentError)error { - NSString *helpString = nil; - switch (error) { - case ALDocumentErrorNotSharp: - helpString = @"Document not Sharp"; - break; - case ALDocumentErrorSkewTooHigh: - helpString = @"Wrong Perspective"; - break; - case ALDocumentErrorImageTooDark: - helpString = @"Too Dark"; - break; - case ALDocumentErrorShakeDetected: - helpString = @"Shake detected"; - break; - default: - break; - } - - // The error is not in the list above or a label is on screen at the moment - if(!helpString || self.showingLabel == 1) { - return; - } - - self.showingLabel = 1; - self.roundedView.textLabel.text = helpString; - - - // Animate the appearance of the label - CGFloat fadeDuration = 0.8; - [UIView animateWithDuration:fadeDuration animations:^{ - self.roundedView.alpha = 1; - } completion:^(BOOL finished) { - [UIView animateWithDuration:fadeDuration animations:^{ - self.roundedView.alpha = 0; - } completion:^(BOOL finished) { - self.showingLabel = 0; - }]; - }]; -} +//- (void)showUserLabel:(ALDocumentError)error { +// NSString *helpString = nil; +// switch (error) { +// case ALDocumentErrorNotSharp: +// helpString = @"Document not Sharp"; +// break; +// case ALDocumentErrorSkewTooHigh: +// helpString = @"Wrong Perspective"; +// break; +// case ALDocumentErrorImageTooDark: +// helpString = @"Too Dark"; +// break; +// case ALDocumentErrorShakeDetected: +// helpString = @"Shake detected"; +// break; +// default: +// break; +// } +// +// // The error is not in the list above or a label is on screen at the moment +// if(!helpString || self.showingLabel == 1) { +// return; +// } +// +// self.showingLabel = 1; +// self.roundedView.textLabel.text = helpString; +// +// +// // Animate the appearance of the label +// CGFloat fadeDuration = 0.8; +// [UIView animateWithDuration:fadeDuration animations:^{ +// self.roundedView.alpha = 1; +// } completion:^(BOOL finished) { +// [UIView animateWithDuration:fadeDuration animations:^{ +// self.roundedView.alpha = 0; +// } completion:^(BOOL finished) { +// self.showingLabel = 0; +// }]; +// }]; +//} @end diff --git a/AnylineExamples/Anyline Examples Source/IBAN/ViewController/ALIBANScanViewController.m b/AnylineExamples/Anyline Examples Source/IBAN/ViewController/ALIBANScanViewController.m index d73f9bc0c..ef60c753a 100644 --- a/AnylineExamples/Anyline Examples Source/IBAN/ViewController/ALIBANScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/IBAN/ViewController/ALIBANScanViewController.m @@ -13,12 +13,12 @@ #import "AnylineExamples-Swift.h" // The controller has to conform to to be able to receive results -@interface ALIBANScanViewController () +@interface ALIBANScanViewController () // // The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *ibanScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *ibanScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALOCRScanViewPlugin *ibanScanViewPlugin; +//@property (nonatomic, strong) ALOCRScanPlugin *ibanScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; @end @@ -31,34 +31,34 @@ - (void)viewDidLoad { self.title = @"IBAN"; // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - ALOCRConfig *config = [[ALOCRConfig alloc] init]; - config.scanMode = ALLine; - config.charHeight = ALRangeMake(25, 65); - config.minConfidence = 70; - config.characterWhitelist = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - config.validationRegex = @"^[A-Z]{2}([0-9A-Z]\\s*){13,32}$"; - config.scanMode = ALLine; - - NSError *error = nil; - - self.ibanScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.ibanScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.ibanScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"iban_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.ibanScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.ibanScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - NSAssert(self.ibanScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.ibanScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.ibanScanViewPlugin]; +// CGRect frame = [self scanViewFrame]; +// +// ALOCRConfig *config = [[ALOCRConfig alloc] init]; +// config.scanMode = ALLine; +// config.charHeight = ALRangeMake(25, 65); +// config.minConfidence = 70; +// config.characterWhitelist = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; +// config.validationRegex = @"^[A-Z]{2}([0-9A-Z]\\s*){13,32}$"; +// config.scanMode = ALLine; +// +// NSError *error = nil; +// +// self.ibanScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" +// delegate:self +// ocrConfig:config +// error:&error]; +// NSAssert(self.ibanScanPlugin, @"Setup Error: %@", error.debugDescription); +// [self.ibanScanPlugin addInfoDelegate:self]; +// +// NSString *confPath = [[NSBundle mainBundle] pathForResource:@"iban_config" ofType:@"json"]; +// ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +// +// self.ibanScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.ibanScanPlugin +// scanViewPluginConfig:scanViewPluginConfig]; +// NSAssert(self.ibanScanViewPlugin, @"Setup Error: %@", error.debugDescription); +// [self.ibanScanViewPlugin addScanViewPluginDelegate:self]; +// +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.ibanScanViewPlugin]; // After setup is complete we add the scanView to the view of this view controller [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; @@ -73,7 +73,7 @@ - (void)viewDidLoad { //Start Camera: [self.scanView startCamera]; - [self startListeningForMotion]; +// [self startListeningForMotion]; self.controllerType = ALScanHistoryIban; } @@ -81,21 +81,21 @@ - (void)viewDidLoad { /* This method will be called once the view controller and its subviews have appeared on screen */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} +//-(void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// +// // We use this subroutine to start Anyline. The reason it has its own subroutine is +// // so that we can later use it to restart the scanning process. +// [self startAnyline]; +//} /* Cancel scanning to allow the module to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.ibanScanViewPlugin stopAndReturnError:nil]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [self.ibanScanViewPlugin stopAndReturnError:nil]; +//} /* This method is used to tell Anyline to start scanning. It gets called in @@ -104,52 +104,52 @@ is found scanning will stop automatically (you can change this behaviour with cancelOnResult:). When the user dismisses self.identificationView this method will get called again. */ -- (void)startAnyline { - [self startPlugin:self.ibanScanViewPlugin]; - - self.startTime = CACurrentMediaTime(); -} - -- (void)stopAnyline { - if (self.ibanScanPlugin.isRunning) { - [self.ibanScanViewPlugin stopAndReturnError:nil]; - } -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} +//- (void)startAnyline { +// [self startPlugin:self.ibanScanViewPlugin]; +// +// self.startTime = CACurrentMediaTime(); +//} + +//- (void)stopAnyline { +// if (self.ibanScanPlugin.isRunning) { +// [self.ibanScanViewPlugin stopAndReturnError:nil]; +// } +//} + +//- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { +// //Update Position of Warning Indicator +// [self updateWarningPosition: +// cutoutRect.origin.y + +// cutoutRect.size.height + +// self.scanView.frame.origin.y + +// 80]; +//} #pragma mark -- AnylineOCRModuleDelegate /* This is the main delegate method Anyline uses to report its results */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"IBAN" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.ibanScanViewPlugin completion:^{ - [self stopAnyline]; - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.ibanScanViewPlugin]; - } - -} +//- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { +// NSMutableArray *resultData = [[NSMutableArray alloc] init]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"IBAN" value:result.result shouldSpellOutValue:YES]]; +// NSString *jsonString = [self JSONStringFromResultData:resultData]; +// +// __weak __block typeof(self) weakSelf = self; +// [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.ibanScanViewPlugin completion:^{ +// [self stopAnyline]; +// ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; +// vc.imagePrimary = result.image; +// [weakSelf.navigationController pushViewController:vc animated:YES]; +// }]; +//} +// +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ +// if ([info.variableName isEqualToString:@"$brightness"]) { +// [self updateBrightness:[info.value floatValue] forModule:self.ibanScanViewPlugin]; +// } +// +//} - (NSString *)formattedIbanText:(NSString*)originalString { NSMutableString *resultString = [NSMutableString string]; diff --git a/AnylineExamples/Anyline Examples Source/IBAN/iban_config.json b/AnylineExamples/Anyline Examples Source/IBAN/iban_config.json index 3b9aa323c..ac6803cd6 100644 --- a/AnylineExamples/Anyline Examples Source/IBAN/iban_config.json +++ b/AnylineExamples/Anyline Examples Source/IBAN/iban_config.json @@ -11,18 +11,18 @@ "height": 1 }, "strokeWidth": 2, - "cornerRadius": 10, - "strokeColor": "FFFFFF", + "cornerRadius": 4, + "strokeColor": "0099FF", "feedbackStrokeColor": "0099FF", "outerColor": "000000", "outerAlpha": 0.3 }, "scanFeedback" : { "style": "CONTOUR_UNDERLINE", - "strokeWidth": 1, + "strokeWidth": 2, "strokeColor": "0099FF", "fillColor": "110099FF", - "cornerRadius": 10, + "cornerRadius": 4, "beepOnResult": true, "vibrateOnResult": true, "blinkAnimationOnResult": true diff --git a/AnylineExamples/Anyline Examples Source/ISBN/ViewController/ALISBNScanViewController.m b/AnylineExamples/Anyline Examples Source/ISBN/ViewController/ALISBNScanViewController.m index 61376a4f5..1160c63d6 100644 --- a/AnylineExamples/Anyline Examples Source/ISBN/ViewController/ALISBNScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/ISBN/ViewController/ALISBNScanViewController.m @@ -12,12 +12,12 @@ #import "NSUserDefaults+ALExamplesAdditions.h" // The controller has to conform to to be able to receive results -@interface ALISBNScanViewController () +@interface ALISBNScanViewController () // // The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *isbnScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *isbnScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALOCRScanViewPlugin *isbnScanViewPlugin; +//@property (nonatomic, strong) ALOCRScanPlugin *isbnScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; @end @@ -33,30 +33,30 @@ - (void)viewDidLoad { // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen CGRect frame = [self scanViewFrame]; - ALOCRConfig *config = [[ALOCRConfig alloc] init]; - - config.characterWhitelist = @"ISBN0123456789<>-X"; - config.validationRegex = @"^ISBN((-)?\\s*(13|10))?:?\\s*((978|979){1}-?\\s*)*[0-9]{1,5}-?\\s*[0-9]{2,7}-?\\s*[0-9]{2,7}-?\\s*[0-9X]$"; - config.scanMode = ALAuto; - - NSError *error = nil; - - self.isbnScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.isbnScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.isbnScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"isbn_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.isbnScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.isbnScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - NSAssert(self.isbnScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.isbnScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.isbnScanViewPlugin]; +// ALOCRConfig *config = [[ALOCRConfig alloc] init]; +// +// config.characterWhitelist = @"ISBN0123456789<>-X"; +// config.validationRegex = @"^ISBN((-)?\\s*(13|10))?:?\\s*((978|979){1}-?\\s*)*[0-9]{1,5}-?\\s*[0-9]{2,7}-?\\s*[0-9]{2,7}-?\\s*[0-9X]$"; +// config.scanMode = ALAuto; +// +// NSError *error = nil; +// +// self.isbnScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" +// delegate:self +// ocrConfig:config +// error:&error]; +// NSAssert(self.isbnScanPlugin, @"Setup Error: %@", error.debugDescription); +// [self.isbnScanPlugin addInfoDelegate:self]; +// +// NSString *confPath = [[NSBundle mainBundle] pathForResource:@"isbn_config" ofType:@"json"]; +// ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +// +// self.isbnScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.isbnScanPlugin +// scanViewPluginConfig:scanViewPluginConfig]; +// NSAssert(self.isbnScanViewPlugin, @"Setup Error: %@", error.debugDescription); +// [self.isbnScanViewPlugin addScanViewPluginDelegate:self]; +// +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.isbnScanViewPlugin]; // After setup is complete we add the scanView to the view of this view controller [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; @@ -71,7 +71,7 @@ - (void)viewDidLoad { //Start Camera: [self.scanView startCamera]; - [self startListeningForMotion]; +// [self startListeningForMotion]; self.controllerType = ALScanHistoryIsbn; } @@ -79,21 +79,21 @@ - (void)viewDidLoad { /* This method will be called once the view controller and its subviews have appeared on screen */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} +//-(void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// +// // We use this subroutine to start Anyline. The reason it has its own subroutine is +// // so that we can later use it to restart the scanning process. +// [self startAnyline]; +//} /* Cancel scanning to allow the module to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.isbnScanViewPlugin stopAndReturnError:nil]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [self.isbnScanViewPlugin stopAndReturnError:nil]; +//} /* This method is used to tell Anyline to start scanning. It gets called in @@ -102,53 +102,53 @@ is found scanning will stop automatically (you can change this behaviour with cancelOnResult:). When the user dismisses self.identificationView this method will get called again. */ -- (void)startAnyline { - [self startPlugin:self.isbnScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} +//- (void)startAnyline { +// [self startPlugin:self.isbnScanViewPlugin]; +// self.startTime = CACurrentMediaTime(); +//} +// +//- (void)stopAnyline { +// if (self.isbnScanPlugin.isRunning) { +// [self.isbnScanViewPlugin stopAndReturnError:nil]; +// } +//} -- (void)stopAnyline { - if (self.isbnScanPlugin.isRunning) { - [self.isbnScanViewPlugin stopAndReturnError:nil]; - } -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} +//- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { +// //Update Position of Warning Indicator +// [self updateWarningPosition: +// cutoutRect.origin.y + +// cutoutRect.size.height + +// self.scanView.frame.origin.y + +// 80]; +//} #pragma mark -- AnylineOCRModuleDelegate /* This is the main delegate method Anyline uses to report its results */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { - //TODO: (RNR) align this with other calls so it creates a proper json string - [self anylineDidFindResult:result.result barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.isbnScanViewPlugin completion:^{ - [self stopAnyline]; - ALISBNViewController *vc = [[ALISBNViewController alloc] init]; - NSString *isbn = result.result; - isbn = [isbn stringByReplacingOccurrencesOfString:@"-" withString:@""]; - isbn = [isbn stringByReplacingOccurrencesOfString:@" " withString:@""]; - isbn = [isbn stringByReplacingOccurrencesOfString:@"ISBN10" withString:@""]; - isbn = [isbn stringByReplacingOccurrencesOfString:@"ISBN13" withString:@""]; - isbn = [isbn stringByReplacingOccurrencesOfString:@"ISBN" withString:@""]; - isbn = [isbn stringByReplacingOccurrencesOfString:@":" withString:@""]; - - [vc setResult:isbn]; - [self.navigationController pushViewController:vc animated:YES]; - }]; -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.isbnScanViewPlugin]; - } - -} +//- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { +// //TODO: (RNR) align this with other calls so it creates a proper json string +// [self anylineDidFindResult:result.result barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.isbnScanViewPlugin completion:^{ +// [self stopAnyline]; +// ALISBNViewController *vc = [[ALISBNViewController alloc] init]; +// NSString *isbn = result.result; +// isbn = [isbn stringByReplacingOccurrencesOfString:@"-" withString:@""]; +// isbn = [isbn stringByReplacingOccurrencesOfString:@" " withString:@""]; +// isbn = [isbn stringByReplacingOccurrencesOfString:@"ISBN10" withString:@""]; +// isbn = [isbn stringByReplacingOccurrencesOfString:@"ISBN13" withString:@""]; +// isbn = [isbn stringByReplacingOccurrencesOfString:@"ISBN" withString:@""]; +// isbn = [isbn stringByReplacingOccurrencesOfString:@":" withString:@""]; +// +// [vc setResult:isbn]; +// [self.navigationController pushViewController:vc animated:YES]; +// }]; +//} +// +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ +// if ([info.variableName isEqualToString:@"$brightness"]) { +// [self updateBrightness:[info.value floatValue] forModule:self.isbnScanViewPlugin]; +// } +// +//} @end diff --git a/AnylineExamples/Anyline Examples Source/ISBN/isbn_config.json b/AnylineExamples/Anyline Examples Source/ISBN/isbn_config.json index 82fa1c2ed..618d3a95d 100644 --- a/AnylineExamples/Anyline Examples Source/ISBN/isbn_config.json +++ b/AnylineExamples/Anyline Examples Source/ISBN/isbn_config.json @@ -11,15 +11,15 @@ "height": 1 }, "strokeWidth": 2, - "cornerRadius": 10, - "strokeColor": "FFFFFF", + "cornerRadius": 4, + "strokeColor": "0099FF", "outerColor": "000000", "outerAlpha": 0.3, "feedbackStrokeColor": "0099FF" }, "scanFeedback" : { "style": "contour_underline", - "strokeWidth": 1, + "strokeWidth": 2, "strokeColor": "0099FF", "beepOnResult": true, "vibrateOnResult": true, diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALAFLicensePlateViewController.h b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALAFLicensePlateViewController.h deleted file mode 100644 index d47ac17f1..000000000 --- a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALAFLicensePlateViewController.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// ALAFLicensePlateViewController.h -// AnylineExamples -// -// Created by Aldrich Co on 9/30/21. -// - -#import -#import "ALBaseScanViewController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface ALAFLicensePlateViewController : ALBaseScanViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALAFLicensePlateViewController.m b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALAFLicensePlateViewController.m deleted file mode 100644 index 94bde8e2a..000000000 --- a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALAFLicensePlateViewController.m +++ /dev/null @@ -1,166 +0,0 @@ -// -// ALAFLicensePlateViewController.m -// AnylineExamples -// -// Created by Aldrich Co on 9/30/21. -// - -#import "ALAFLicensePlateViewController.h" -#import -#import "AnylineExamples-Swift.h" - -//#import "Anyline/AnylineLicensePlateModuleView.h" - -// The controller has to conform to to be able to receive results -@interface ALAFLicensePlateViewController () -// The Anyline module used for OCR -@property (nonatomic, strong) ALLicensePlateScanViewPlugin *licensePlateScanViewPlugin; -@property (nonatomic, strong) ALLicensePlateScanPlugin *licensePlateScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; - -@end - -@implementation ALAFLicensePlateViewController -/* - We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed. - */ -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"African License Plate"; - - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - NSError *error = nil; - - self.licensePlateScanPlugin = [[ALLicensePlateScanPlugin alloc] initWithPluginID:@"LICENSE_PLATE" delegate:self error:&error]; - NSAssert(self.licensePlateScanPlugin, @"Setup Error: %@", error.debugDescription); - - [self.licensePlateScanPlugin setScanMode:ALLicensePlateAfrica error:&error]; - NSAssert(!error, @"Set ScanMode Error: %@", error.debugDescription); - - [self.licensePlateScanPlugin addInfoDelegate:self]; - - - //Set a delayed scan start time in the scanViewPluginConfig - ALScanViewPluginConfig *viewPluginConfig = [ALScanViewPluginConfig defaultLicensePlateConfig]; - viewPluginConfig.delayStartScanTime = 2000; - - - self.licensePlateScanViewPlugin = [[ALLicensePlateScanViewPlugin alloc] initWithScanPlugin:self.licensePlateScanPlugin scanViewPluginConfig:viewPluginConfig]; - NSAssert(self.licensePlateScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.licensePlateScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.licensePlateScanViewPlugin]; - - self.controllerType = ALScanHistoryLicensePlates; - - // After setup is complete we add the scanView to the view of this view controller - [self.view addSubview:self.scanView]; - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - - // Enable zoom gesture for scanView - [self.scanView enableZoomPinchGesture:true]; - - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; -} - -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} - -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [self.licensePlateScanViewPlugin stopAndReturnError:nil]; -} - -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.licensePlateScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} - -#pragma mark -- AnylineOCRModuleDelegate - -/* - This is the main delegate method Anyline uses to report its results - */ - -- (void)anylineLicensePlateScanPlugin:(ALLicensePlateScanPlugin *)anylineLicensePlateScanPlugin - didFindResult:(ALLicensePlateResult *)result { - - NSMutableArray *resultData = @[ - [[ALResultEntry alloc] initWithTitle:@"License Plate" value:result.result shouldSpellOutValue:YES], - ].mutableCopy; - - if (result.country != nil) { - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Country" value:result.country]]; - } - - if (result.area != nil) { - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"State" value:result.area]]; - } - - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString - barcodeResult:@"" - image:result.image - scanPlugin:anylineLicensePlateScanPlugin - viewPlugin:self.licensePlateScanViewPlugin - completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] - initWithResults:resultData]; - vc.imagePrimary = result.image; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.licensePlateScanViewPlugin]; - } else if ([info.variableName isEqualToString:@"$square"] && info.value) { - //the visual feedback shows we have found a potential license plate, so let's give some feedback on VoiceOver too. - UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, @"License Plate"); - } - -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateScanViewController.h b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateScanViewController.h new file mode 100644 index 000000000..b206fc0af --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateScanViewController.h @@ -0,0 +1,7 @@ +#import + +#import "ALBaseScanViewController.h" + +@interface ALLicensePlateScanViewController : ALBaseScanViewController + +@end diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateScanViewController.m b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateScanViewController.m new file mode 100644 index 000000000..3e3cdcd88 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateScanViewController.m @@ -0,0 +1,103 @@ +#import "ALLicensePlateScanViewController.h" +#import +#import "AnylineExamples-Swift.h" +#import "ALPluginResultHelper.h" + +@interface ALLicensePlateScanViewController () + +@property (nonatomic, strong) id scanViewPlugin; + +@property (nonatomic, strong) ALScanViewConfig *scanViewConfig; + +@property (nonatomic, readonly) NSString *configJSONStr; + +@end + + +NSString * const kLicensePlateScanVC_configEU = @"vehicle_config_license_plate_eu"; +NSString * const kLicensePlateScanVC_configUS = @"vehicle_config_license_plate_us"; +NSString * const kLicensePlateScanVC_configAF = @"vehicle_config_license_plate_af"; + +@implementation ALLicensePlateScanViewController + +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + // self.title would have been set based on values from ALLicensePlateManager + NSString *licensePlateConfigJSONFile = kLicensePlateScanVC_configEU; + if ([self.title isEqualToString:@"US License Plate"]) { + licensePlateConfigJSONFile = kLicensePlateScanVC_configUS; + } else if ([self.title isEqualToString:@"African License Plate"] || [self.title isEqualToString:@"AF License Plate"]) { + licensePlateConfigJSONFile = kLicensePlateScanVC_configAF; + } + + id JSONConfigObj = [[self configJSONStrWithFilename:licensePlateConfigJSONFile] asJSONObject]; + + self.scanViewPlugin = [ALScanViewPluginFactory withJSONDictionary:JSONConfigObj]; + + self.scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:JSONConfigObj error:nil]; + + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.scanViewPlugin + scanViewConfig:self.scanViewConfig + error:nil]; + + [self installScanView:self.scanView]; + + ALScanViewPlugin *scanViewPlugin = self.scanViewPlugin; + + scanViewPlugin.scanPlugin.delegate = self; + + [self.scanView startCamera]; + + self.controllerType = ALScanHistoryLicensePlates; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + // We use this subroutine to start Anyline. The reason it has its own subroutine is + // so that we can later use it to restart the scanning process. + [self.scanViewPlugin startWithError:nil]; +} + + +// MARK: - Handle & present results + +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + [self enableLandscapeOrientation:NO]; + ALLicensePlateResult *result = scanResult.pluginResult.licensePlateResult; + + NSArray *resultData = result.resultEntryList; + NSString *resultString = [ALResultEntry JSONStringFromList:resultData]; + UIImage *image = scanResult.croppedImage; + + __weak __block typeof(self) weakSelf = self; + [self anylineDidFindResult:resultString + barcodeResult:nil + image:image + scanPlugin:scanPlugin + viewPlugin:self.scanViewPlugin + completion:^{ + ALResultViewController *vc = [[ALResultViewController alloc] + initWithResults:resultData]; + vc.imagePrimary = scanResult.croppedImage; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]; +} + +// TODO: (ACO) decide if we still need them +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ +// if ([info.variableName isEqualToString:@"$brightness"]) { +// [self updateBrightness:[info.value floatValue] forModule:self.licensePlateScanViewPlugin]; +// } else if ([info.variableName isEqualToString:@"$square"] && info.value) { +// //the visual feedback shows we have found a potential license plate, so let's give some feedback on VoiceOver too. +// UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, @"License Plate"); +// } +// +//} + +@end diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateViewController.h b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateViewController.h deleted file mode 100644 index 9e17f9572..000000000 --- a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// ALLicensePlateViewController.h -// AnylineExamples -// -// Created by Daniel Albertini on 04/02/16. -// Copyright © 2016 9yards GmbH. All rights reserved. -// - -#import - -#import "ALBaseScanViewController.h" - -@interface ALLicensePlateViewController : ALBaseScanViewController - -@end diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateViewController.m b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateViewController.m deleted file mode 100644 index 90841e9b5..000000000 --- a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALLicensePlateViewController.m +++ /dev/null @@ -1,158 +0,0 @@ -// -// ALLicensePlateViewController.m -// AnylineExamples -// -// Created by Matthias Gasser on 04/02/16. -// Copyright © 2016 Anyline GmbH. All rights reserved. -// - -#import "ALLicensePlateViewController.h" -#import -#import "NSUserDefaults+ALExamplesAdditions.h" -#import "AnylineExamples-Swift.h" - -// The controller has to conform to to be able to receive results -@interface ALLicensePlateViewController () -// The Anyline module used for OCR -@property (nonatomic, strong) ALLicensePlateScanViewPlugin *licensePlateScanViewPlugin; -@property (nonatomic, strong) ALLicensePlateScanPlugin *licensePlateScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; - -@end - -@implementation ALLicensePlateViewController -/* - We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed. - */ -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"EU License Plate"; - - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - NSError *error = nil; - - self.licensePlateScanPlugin = [[ALLicensePlateScanPlugin alloc] initWithPluginID:@"LICENSE_PLATE" delegate:self error:&error]; - NSAssert(self.licensePlateScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.licensePlateScanPlugin setScanMode:ALLicensePlateAuto error:nil]; - [self.licensePlateScanPlugin addInfoDelegate:self]; - - - //Set a delayed scan start time in the scanViewPluginConfig - ALScanViewPluginConfig *viewPluginConfig = [ALScanViewPluginConfig defaultLicensePlateConfig]; - - - self.licensePlateScanViewPlugin = [[ALLicensePlateScanViewPlugin alloc] initWithScanPlugin:self.licensePlateScanPlugin scanViewPluginConfig:viewPluginConfig]; - NSAssert(self.licensePlateScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.licensePlateScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.licensePlateScanViewPlugin]; - - self.controllerType = ALScanHistoryLicensePlates; - - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - - // Enable zoom gesture for scanView - [self.scanView enableZoomPinchGesture:true]; - - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; -} - -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} - -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.licensePlateScanViewPlugin stopAndReturnError:nil]; -} - -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.licensePlateScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} - -#pragma mark -- AnylineOCRModuleDelegate - -/* - This is the main delegate method Anyline uses to report its results - */ - -- (void)anylineLicensePlateScanPlugin:(ALLicensePlateScanPlugin *)anylineLicensePlateScanPlugin - didFindResult:(ALLicensePlateResult *)result { - - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"License Plate" - value:result.result - shouldSpellOutValue:YES]]; - - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Country" - value:result.country]]; - - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString - barcodeResult:@"" - image:result.image - scanPlugin:anylineLicensePlateScanPlugin - viewPlugin:self.licensePlateScanViewPlugin - completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.licensePlateScanViewPlugin]; - } else if ([info.variableName isEqualToString:@"$square"] && info.value) { - //the visual feedback shows we have found a potential license plate, so let's give some feedback on VoiceOver too. - UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, @"License Plate"); - } - -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALUSLicensePlateViewController.h b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALUSLicensePlateViewController.h deleted file mode 100644 index 2f8a55035..000000000 --- a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALUSLicensePlateViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// ALUSLicensePlateViewController.h -// AnylineExamples -// -// Created by Philipp Müller on 05/03/21. -// Copyright © 2021 Anyline GmbH. All rights reserved. -// - -#import - -#import "ALBaseScanViewController.h" - -@interface ALUSLicensePlateViewController : ALBaseScanViewController - -@end diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALUSLicensePlateViewController.m b/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALUSLicensePlateViewController.m deleted file mode 100644 index b7b3e9afe..000000000 --- a/AnylineExamples/Anyline Examples Source/LicensePlate/ViewController/ALUSLicensePlateViewController.m +++ /dev/null @@ -1,166 +0,0 @@ -// -// ALUSLicensePlateViewController.h -// AnylineExamples -// -// Created by Philipp Müller on 05/03/21. -// Copyright © 2021 Anyline GmbH. All rights reserved. -// - -#import "ALUSLicensePlateViewController.h" -#import -#import "AnylineExamples-Swift.h" - -//#import "Anyline/AnylineLicensePlateModuleView.h" - -// The controller has to conform to to be able to receive results -@interface ALUSLicensePlateViewController () -// The Anyline module used for OCR -@property (nonatomic, strong) ALLicensePlateScanViewPlugin *licensePlateScanViewPlugin; -@property (nonatomic, strong) ALLicensePlateScanPlugin *licensePlateScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; - -@end - -@implementation ALUSLicensePlateViewController -/* - We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed. - */ -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"US License Plate"; - - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - NSError *error = nil; - - self.licensePlateScanPlugin = [[ALLicensePlateScanPlugin alloc] initWithPluginID:@"LICENSE_PLATE" delegate:self error:&error]; - NSAssert(self.licensePlateScanPlugin, @"Setup Error: %@", error.debugDescription); - - [self.licensePlateScanPlugin setScanMode:ALLicensePlateUnitedStates error:&error]; - NSAssert(!error, @"Set ScanMode Error: %@", error.debugDescription); - - [self.licensePlateScanPlugin addInfoDelegate:self]; - - - //Set a delayed scan start time in the scanViewPluginConfig - ALScanViewPluginConfig *viewPluginConfig = [ALScanViewPluginConfig defaultLicensePlateConfig]; - - - self.licensePlateScanViewPlugin = [[ALLicensePlateScanViewPlugin alloc] initWithScanPlugin:self.licensePlateScanPlugin scanViewPluginConfig:viewPluginConfig]; - NSAssert(self.licensePlateScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.licensePlateScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.licensePlateScanViewPlugin]; - - self.controllerType = ALScanHistoryLicensePlates; - - // After setup is complete we add the scanView to the view of this view controller - [self.view addSubview:self.scanView]; - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - // Enable zoom gesture for scanView - [self.scanView enableZoomPinchGesture:true]; - - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; -} - -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} - -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [self.licensePlateScanViewPlugin stopAndReturnError:nil]; -} - -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.licensePlateScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} - -#pragma mark -- AnylineOCRModuleDelegate - -/* - This is the main delegate method Anyline uses to report its results - */ - -- (void)anylineLicensePlateScanPlugin:(ALLicensePlateScanPlugin *)anylineLicensePlateScanPlugin - didFindResult:(ALLicensePlateResult *)result { - - NSMutableArray *resultData = @[ - [[ALResultEntry alloc] initWithTitle:@"License Plate" value:result.result shouldSpellOutValue:YES], - ].mutableCopy; - - if (result.country != nil) { - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Country" value:result.country]]; - } - - if (result.area != nil) { - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"State" value:result.area]]; - } - - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - - [self anylineDidFindResult:jsonString - barcodeResult:@"" - image:result.image - scanPlugin:anylineLicensePlateScanPlugin - viewPlugin:self.licensePlateScanViewPlugin - completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.licensePlateScanViewPlugin]; - } else if ([info.variableName isEqualToString:@"$square"] && info.value) { - //the visual feedback shows we have found a potential license plate, so let's give some feedback on VoiceOver too. - UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, @"License Plate"); - } - -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_af.json b/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_af.json new file mode 100644 index 000000000..71f7c4613 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_af.json @@ -0,0 +1,46 @@ +{ + "cameraConfig": { + "captureResolution": "1080p" + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "license-plate-af", + "licensePlateConfig": { + "scanMode": "africa" + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "80%", + "maxHeightPercent": "80%", + "width": 600, + "alignment": "top_half", + "ratioFromSize": { "width": 2, "height": 1 }, + "offset": { "x": 0, "y": 0 }, + "cropPadding": { "x": 40, "y": 40 }, + "cropOffset": { "x": 0, "y": 0 }, + "cornerRadius": 4, + "strokeColor": "0099ff", + "strokeWidth": 2, + "feedbackStrokeColor": "0099ff", + "outerColor": "000000", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "rect", + "strokeWidth": 2, + "animationDuration": 0, + "strokeColor": "0099ff", + "cornerRadius": 0, + "fillColor": "330099ff", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_eu.json b/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_eu.json new file mode 100644 index 000000000..deb51af28 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_eu.json @@ -0,0 +1,45 @@ +{ + "cameraConfig": { + "captureResolution": "1080p" + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "license-plate-eu", + "licensePlateConfig": { + "scanMode": "auto" + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "80%", + "maxHeightPercent": "80%", + "alignment": "top_half", + "ratioFromSize": { "width": 4, "height": 1 }, + "offset": { "x": 0, "y": 40 }, + "cropPadding": { "x": 0, "y": 0 }, + "cropOffset": { "x": 0, "y": 0 }, + "cornerRadius": 4, + "strokeColor": "0099ff", + "strokeWidth": 2, + "feedbackStrokeColor": "0099ff", + "outerColor": "000000", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "rect", + "strokeWidth": 2, + "animationDuration": 0, + "strokeColor": "0099ff", + "cornerRadius": 0, + "fillColor": "330099ff", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_us.json b/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_us.json new file mode 100644 index 000000000..b71d6ff79 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/LicensePlate/vehicle_config_license_plate_us.json @@ -0,0 +1,46 @@ +{ + "cameraConfig": { + "captureResolution": "1080p" + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "license-plate-us", + "licensePlateConfig": { + "scanMode": "unitedstates" + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "80%", + "maxHeightPercent": "80%", + "width": 550, + "alignment": "top_half", + "ratioFromSize": { "width": 2, "height": 1 }, + "offset": { "x": 0, "y": 0 }, + "cropPadding": { "x": 40, "y": 40 }, + "cropOffset": { "x": 0, "y": 0 }, + "cornerRadius": 4, + "strokeColor": "0099ff", + "strokeWidth": 2, + "feedbackStrokeColor": "0099ff", + "outerColor": "000000", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "rect", + "strokeWidth": 2, + "animationDuration": 0, + "strokeColor": "0099ff", + "cornerRadius": 0, + "fillColor": "330099ff", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/MRZ/ViewController/ALMRZScanViewController.m b/AnylineExamples/Anyline Examples Source/MRZ/ViewController/ALMRZScanViewController.m index 733037ce3..9add652c8 100755 --- a/AnylineExamples/Anyline Examples Source/MRZ/ViewController/ALMRZScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/MRZ/ViewController/ALMRZScanViewController.m @@ -1,28 +1,23 @@ -// -// ALPassportScanViewController.m -// AnylineExamples -// -// Created by Matthias on 24/05/15. -// Copyright (c) 2015 9yards GmbH. All rights reserved. -// - #import "ALMRZScanViewController.h" #import "ALIdentificationView.h" #import #import "AnylineExamples-Swift.h" #import "NSUserDefaults+ALExamplesAdditions.h" -#import "ALUniversalIDFieldnameUtil.h" #import "AnylineExamples-Swift.h" #import "ALTutorialViewController.h" #import "NSString+Util.h" +#import "ALPluginResultHelper.h" // The controller has to conform to to be able to receive results -@interface ALMRZScanViewController () +@interface ALMRZScanViewController () // The Anyline module used to scan machine readable zones -@property (nonatomic, strong) ALIDScanViewPlugin *mrzScanViewPlugin; -@property (nonatomic, strong) ALIDScanPlugin *mrzScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +@property (nonatomic, strong) id scanViewPlugin; + +@property (nonatomic, strong) ALScanViewConfig *scanViewConfig; + +@property (nonatomic, readonly) NSString *configJSONStr; + @end @@ -34,7 +29,15 @@ - (void)viewDidLoad { [super viewDidLoad]; self.title = (self.title && self.title.length > 0) ? self.title : @"MRZ"; - + [self setColors]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self startMRZScanMode]; +} + +- (void)startMRZScanMode { if (![[[NSBundle mainBundle] bundleIdentifier] localizedCaseInsensitiveContainsString:@"bundle"]) { UIBarButtonItem *infoBarItem; if (@available(iOS 13.0, *)) { @@ -43,86 +46,44 @@ - (void)viewDidLoad { infoBarItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"info"] style:UIBarButtonItemStylePlain target:self action:@selector(infoPressed:)]; } self.navigationItem.rightBarButtonItem = infoBarItem; + [self setColors]; } - - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - ALMRZConfig *mrzConfig = [[ALMRZConfig alloc] init]; - - //Create fieldScanOptions to configure individual scannable fields - ALMRZFieldScanOptions *scanOptions = [[ALMRZFieldScanOptions alloc] init]; - scanOptions.vizAddress = ALDefault; - scanOptions.vizDateOfIssue = ALDefault; - scanOptions.vizSurname = ALDefault; - scanOptions.vizGivenNames = ALDefault; - scanOptions.vizDateOfBirth = ALDefault; - scanOptions.vizDateOfExpiry = ALDefault; - - //Set scanOptions for MRZConfig - mrzConfig.idFieldScanOptions = scanOptions; - - NSError *error = nil; - //Init the anyline ID ScanPlugin with an ID, Licensekey, the delegate, - // the MRZConfig (which will configure the scan Plugin for MRZ scanning), and an error - self.mrzScanPlugin = [[ALIDScanPlugin alloc] initWithPluginID:@"ModuleID" delegate:self idConfig:mrzConfig error:&error]; - NSAssert(self.mrzScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.mrzScanPlugin addInfoDelegate:self]; - - - self.mrzScanViewPlugin = [[ALIDScanViewPlugin alloc] initWithScanPlugin:self.mrzScanPlugin]; - NSAssert(self.mrzScanViewPlugin, @"Setup Error: %@", error.debugDescription); - - //turn on the new 'usesAnimatedRect' visual feedback, which uses animations around the cutout itself rather than the parts inside it where characters are detected. - //mrzScanViewPlugin and cutoutConfig return copies of the configs so they can not be changed in-place - ALScanViewPluginConfig *pluginConfig = self.mrzScanViewPlugin.scanViewPluginConfig; - ALCutoutConfig * cutoutConfig = pluginConfig.cutoutConfig; - cutoutConfig.usesAnimatedRect = YES; - cutoutConfig.strokeWidth = 3.0; - pluginConfig.cutoutConfig = cutoutConfig; - self.mrzScanViewPlugin.scanViewPluginConfig = pluginConfig; - - [self.mrzScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.mrzScanViewPlugin]; - - self.controllerType = ALScanHistoryMrz; - - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; + id JSONConfigObj = [[self configJSONStrWithFilename:@"mrz_config"] asJSONObject]; + + self.scanViewPlugin = [ALScanViewPluginFactory withJSONDictionary:JSONConfigObj]; - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; -} + self.scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:JSONConfigObj error:nil]; -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; + if (self.scanView) { + [self.scanView setScanViewPlugin:self.scanViewPlugin error:nil]; + } else { + + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.scanViewPlugin + scanViewConfig:self.scanViewConfig + error:nil]; + + [self installScanView:self.scanView]; + } + ALScanViewPlugin *scanViewPlugin = self.scanViewPlugin; + + scanViewPlugin.scanPlugin.delegate = self; + + [self.scanView startCamera]; - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; + self.controllerType = ALScanHistoryMrz; + + [self.scanViewPlugin startWithError:nil]; } -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; +- (void)setColors { + [super setColors]; + UIColor *tintColor = UIColor.blackColor; + if (self.isDarkMode) { + tintColor = UIColor.whiteColor; + } + self.navigationItem.rightBarButtonItem.tintColor = tintColor; } /* @@ -130,20 +91,7 @@ - (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin */ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - [self.mrzScanViewPlugin stopAndReturnError:nil]; -} - - -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.mrzScanViewPlugin]; - self.startTime = CACurrentMediaTime(); + [self.scanViewPlugin stop]; } - (IBAction)infoPressed:(id)sender { @@ -151,131 +99,29 @@ - (IBAction)infoPressed:(id)sender { [self presentViewController:vc animated:YES completion:nil]; } -#pragma mark -- AnylineMRZModuleDelegate - -/* - This is the main delegate method Anyline uses to report its results - */ -- (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin didFindResult:(ALIDResult *)scanResult { - ALMRZIdentification *identification = (ALMRZIdentification*)scanResult.result; - - [self.mrzScanViewPlugin stopAndReturnError:nil]; - - // MRZ Fields - NSMutableArray *resultData = [NSMutableArray array]; - - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Surname" - value:[identification surname]]]; - - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Given Names" - value:[identification givenNames]]]; - - [resultData addObject:[self resultEntryWithDate:[identification dateOfBirthObject] - dateString:[identification dateOfBirth] title:@"Date of Birth"]]; - - [resultData addObject:[self resultEntryWithDate:[identification dateOfExpiryObject] - dateString:[identification dateOfExpiry] title:@"Date of Expiry"]]; +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + [self enableLandscapeOrientation:NO]; + NSArray *resultData = scanResult.pluginResult.mrzResult.resultEntryList; + NSString *resultJSON = [ALResultEntry JSONStringFromList:resultData]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Document Type" - value:[identification documentType] - isMandatory:NO]]; + __weak __block ALMRZScanViewController *weakSelf = self; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Document Number" - value:[identification documentNumber] - shouldSpellOutValue:YES]]; + [self anylineDidFindResult:resultJSON + barcodeResult:nil + faceImage:scanResult.faceImage + images:@[scanResult.croppedImage] + scanPlugin:scanPlugin + viewPlugin:self.scanViewPlugin completion:^{ - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Nationality" - value:[identification nationalityCountryCode] - isMandatory:NO]]; - - // VIZ Fields - NSMutableArray *vizResultData = [[NSMutableArray alloc] init]; - if (identification.vizSurname.trimmed.length > 0) { - [vizResultData addObject:[[ALResultEntry alloc] initWithTitle:@"Surname" - value:[identification vizSurname]]]; - } - - if (identification.vizGivenNames.trimmed.length > 0) { - [vizResultData addObject:[[ALResultEntry alloc] initWithTitle:@"Given Names" - value:[identification vizGivenNames]]]; - } - if (identification.vizAddress.trimmed.length > 0) { - [vizResultData addObject:[[ALResultEntry alloc] initWithTitle:@"Address" - value:[identification vizAddress] - isMandatory:NO]]; - } - if (identification.vizDateOfBirth.trimmed.length > 0) { - [vizResultData addObject:[self resultEntryWithDate:[identification vizDateOfBirthObject] - dateString:[identification vizDateOfBirth] - title:@"Date of Birth"]]; - } - if (identification.vizDateOfIssue.trimmed.length > 0) { - [vizResultData addObject:[self resultEntryWithDate:[identification vizDateOfIssueObject] - dateString:[identification vizDateOfIssue] - title:@"Date of Issue"]]; - } - if (identification.vizDateOfExpiry.trimmed.length > 0) { - [vizResultData addObject:[self resultEntryWithDate:[identification vizDateOfExpiryObject] - dateString:[identification vizDateOfExpiry] - title:@"Date of Expiry"]]; - } - - if (identification.personalNumber.trimmed.length > 0) { - [vizResultData addObject:[[ALResultEntry alloc] initWithTitle:@"Personal Number" - value:[identification personalNumber] isMandatory:NO]]; - } - - [vizResultData addObject:[[ALResultEntry alloc] initWithTitle:@"Sex" - value:[identification sex] - isMandatory:NO]]; - - [resultData addObjectsFromArray:vizResultData]; - resultData = [ALUniversalIDFieldnameUtil sortResultDataUsingFieldNamesWithSpace:resultData].mutableCopy; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString - barcodeResult:@"" - faceImage:[identification faceImage] - images:@[scanResult.image] - scanPlugin:anylineIDScanPlugin - viewPlugin:self.mrzScanViewPlugin - completion:^{ - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = scanResult.image; - vc.imageFace = identification.faceImage; - vc.showDisclaimer = YES; - [weakSelf.navigationController pushViewController:vc animated:YES]; + ALResultViewController *vc = [[ALResultViewController alloc] + initWithResults:resultData]; + vc.imageFace = scanResult.faceImage; + vc.imagePrimary = scanResult.croppedImage; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf.navigationController pushViewController:vc animated:YES]; + }); }]; } -- (ALResultEntry *)resultEntryWithDate:(NSDate *)date dateString:(NSString *)dateString title:(NSString *)title { - BOOL isAvailable = [self checkDateIfAvailable:date dateString:dateString]; - if (!isAvailable) { - return [[ALResultEntry alloc] initWithTitle:title value:nil]; - } - - NSString *value = [self stringForDate:date]; - return [[ALResultEntry alloc] initWithTitle:title value:value isAvailable:isAvailable]; -} - -- (BOOL)checkDateIfAvailable:(NSDate *)date dateString:(NSString *)dateString { - if (!date && dateString.length == 0) { - return NO; - } - return YES; -} - -- (NSString *)stringForDate:(NSDate *)date { - if (!date) { - return @"Date not valid"; - } - - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT+0:00"]]; - dateFormatter.dateStyle = NSDateFormatterMediumStyle; - dateFormatter.timeStyle = NSDateFormatterNoStyle; - - return [dateFormatter stringFromDate:date]; -} @end diff --git a/AnylineExamples/Anyline Examples Source/MRZ/Views/ALIdentificationView.h b/AnylineExamples/Anyline Examples Source/MRZ/Views/ALIdentificationView.h index c36df4a57..5e1e3573f 100755 --- a/AnylineExamples/Anyline Examples Source/MRZ/Views/ALIdentificationView.h +++ b/AnylineExamples/Anyline Examples Source/MRZ/Views/ALIdentificationView.h @@ -10,6 +10,6 @@ #import @interface ALIdentificationView : UIView -- (void)updateIdentification:(ALIdentification *)aIdentification; +//- (void)updateIdentification:(ALIdentification *)aIdentification; @end diff --git a/AnylineExamples/Anyline Examples Source/MRZ/Views/ALIdentificationView.m b/AnylineExamples/Anyline Examples Source/MRZ/Views/ALIdentificationView.m index 5dcd0be75..391171cec 100755 --- a/AnylineExamples/Anyline Examples Source/MRZ/Views/ALIdentificationView.m +++ b/AnylineExamples/Anyline Examples Source/MRZ/Views/ALIdentificationView.m @@ -122,33 +122,33 @@ + (UILabel *)AL_IdentificationLabel2 { } -- (void)updateIdentification:(ALMRZIdentification *)aIdentification { - - self.nr.text = aIdentification.documentNumber; - self.surname.text = aIdentification.surname; - self.given_names.text = aIdentification.givenNames; - self.code.text = aIdentification.nationalityCountryCode; - self.type.text = aIdentification.documentType; - - if (aIdentification.dateOfBirthObject) { - self.dob.text = [NSDateFormatter localizedStringFromDate:aIdentification.dateOfBirthObject dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle]; - [self.dob sizeToFit]; - } else { - self.dob.text = aIdentification.dateOfBirth; - } - - if (aIdentification.dateOfExpiryObject) { - self.expiration_date.text = [NSDateFormatter localizedStringFromDate:aIdentification.dateOfExpiryObject dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle]; - [self.expiration_date sizeToFit]; - } else { - self.expiration_date.text = aIdentification.dateOfExpiry; - } - - self.sex.text = aIdentification.sex; - - self.line0.text = [aIdentification.mrzString stringByReplacingOccurrencesOfString:@"\\n" - withString:@"\n"]; - self.line0.numberOfLines = 0; -} +//- (void)updateIdentification:(ALMRZIdentification *)aIdentification { +// +// self.nr.text = aIdentification.documentNumber; +// self.surname.text = aIdentification.surname; +// self.given_names.text = aIdentification.givenNames; +// self.code.text = aIdentification.nationalityCountryCode; +// self.type.text = aIdentification.documentType; +// +// if (aIdentification.dateOfBirthObject) { +// self.dob.text = [NSDateFormatter localizedStringFromDate:aIdentification.dateOfBirthObject dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle]; +// [self.dob sizeToFit]; +// } else { +// self.dob.text = aIdentification.dateOfBirth; +// } +// +// if (aIdentification.dateOfExpiryObject) { +// self.expiration_date.text = [NSDateFormatter localizedStringFromDate:aIdentification.dateOfExpiryObject dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle]; +// [self.expiration_date sizeToFit]; +// } else { +// self.expiration_date.text = aIdentification.dateOfExpiry; +// } +// +// self.sex.text = aIdentification.sex; +// +// self.line0.text = [aIdentification.mrzString stringByReplacingOccurrencesOfString:@"\\n" +// withString:@"\n"]; +// self.line0.numberOfLines = 0; +//} @end diff --git a/AnylineExamples/Anyline Examples Source/MRZ/mrz_config.json b/AnylineExamples/Anyline Examples Source/MRZ/mrz_config.json new file mode 100644 index 000000000..67b3772e7 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/MRZ/mrz_config.json @@ -0,0 +1,49 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "ID", + "cancelOnResult": true, + "mrzConfig": { + "strictMode": false, + "cropAndTransformID": false + } + }, + "cutoutConfig": { + "style": "none", + "maxWidthPercent": "90%", + "maxHeightPercent": "90%", + "alignment": "center", + "ratioFromSize": { + "width": 50, + "height": 31 + }, + "cropPadding": { + }, + "outerColor": "000000", + "outerAlpha": 0.3, + "strokeWidth": 2, + "strokeColor": "0099FF", + "cornerRadius": 4, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig": { + "style": "rect", + "visualFeedbackRedrawTimeout": 100, + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": false + } + } +} + diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALAutoAnalogDigitalMeterScanViewController.m b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALAutoAnalogDigitalMeterScanViewController.m index 3efb742be..8d55f7e94 100644 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALAutoAnalogDigitalMeterScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALAutoAnalogDigitalMeterScanViewController.m @@ -17,12 +17,12 @@ static const NSInteger padding = 7; // The controller has to conform to to be able to receive results -@interface ALAutoAnalogDigitalMeterScanViewController () +@interface ALAutoAnalogDigitalMeterScanViewController () // // The Anyline plugins used to scan -@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; -@property (nonatomic, strong) ALMeterScanPlugin *meterScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; +//@property (nonatomic, strong) ALMeterScanPlugin *meterScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; //Native barcode scanning properties @property (nonatomic, strong) NSString *barcodeResult; @@ -47,30 +47,30 @@ - (void)viewDidLoad { //Add Meter Scan Plugin (Scan Process) NSError *error = nil; - self.meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"ENERGY" delegate:self error:&error]; - NSAssert(self.meterScanPlugin, @"Setup Error: %@", error.debugDescription); - - //Add Meter Scan View Plugin (Scan UI) - self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:self.meterScanPlugin]; - - - //Set ScanMode to ALAutoAnalogDigitalMeter - BOOL success = [self.meterScanPlugin setScanMode:ALAutoAnalogDigitalMeter error:&error]; - if( !success ) { - // Something went wrong. The error object contains the error description - __weak __block typeof(self) weakSelf = self; - [self showAlertWithTitle:@"Set ScanMode Error" - message:error.debugDescription completion:^{ - [weakSelf.navigationController popViewControllerAnimated:YES]; - }]; - - } - - //Add ScanView (Camera and Flashbutton) - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.meterScanViewPlugin]; - - //Enable Zoom Gesture - [self.scanView enableZoomPinchGesture:YES]; +// self.meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"ENERGY" delegate:self error:&error]; +// NSAssert(self.meterScanPlugin, @"Setup Error: %@", error.debugDescription); +// +// //Add Meter Scan View Plugin (Scan UI) +// self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:self.meterScanPlugin]; +// +// +// //Set ScanMode to ALAutoAnalogDigitalMeter +// BOOL success = [self.meterScanPlugin setScanMode:ALAutoAnalogDigitalMeter error:&error]; +// if( !success ) { +// // Something went wrong. The error object contains the error description +// __weak __block typeof(self) weakSelf = self; +// [self showAlertWithTitle:@"Set ScanMode Error" +// message:error.debugDescription completion:^{ +// [weakSelf.navigationController popViewControllerAnimated:YES]; +// }]; +// +// } +// +// //Add ScanView (Camera and Flashbutton) +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.meterScanViewPlugin]; +// +// //Enable Zoom Gesture +// [self.scanView enableZoomPinchGesture:YES]; //Adding the scanView [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; @@ -84,7 +84,7 @@ - (void)viewDidLoad { [NSLayoutConstraint activateConstraints:scanViewConstraints]; [self.scanView startCamera]; - self.meterScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; +// self.meterScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; self.controllerType = ALScanHistoryElectricMeter; @@ -97,61 +97,60 @@ - (void)viewDidLoad { /* This method will be called once the view controller and its subviews have appeared on screen */ -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self startPlugin:self.meterScanViewPlugin]; -} - -- (void)viewDidLayoutSubviews { - [super viewDidLayoutSubviews]; - [self updateLayoutBarcodeSwitchView]; -} - -- (void)updateLayoutBarcodeSwitchView { - self.enableBarcodeLabel.center = CGPointMake(self.enableBarcodeLabel.frame.size.width/2, - self.enableBarcodeView.frame.size.height/2); - - self.enableBarcodeSwitch.center = CGPointMake(self.enableBarcodeLabel.frame.size.width + self.enableBarcodeSwitch.frame.size.width/2 + padding, - self.enableBarcodeView.frame.size.height/2); - - CGFloat width = self.enableBarcodeSwitch.frame.size.width + padding + self.enableBarcodeLabel.frame.size.width; - self.enableBarcodeView.frame = CGRectMake(self.scanView.frame.size.width-width-15, - self.scanView.frame.size.height-self.enableBarcodeView.frame.size.height-55, - width, - 50); -} +//- (void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// [self startPlugin:self.meterScanViewPlugin]; +//} +// +//- (void)viewDidLayoutSubviews { +// [super viewDidLayoutSubviews]; +// [self updateLayoutBarcodeSwitchView]; +//} +// +//- (void)updateLayoutBarcodeSwitchView { +// self.enableBarcodeLabel.center = CGPointMake(self.enableBarcodeLabel.frame.size.width/2, +// self.enableBarcodeView.frame.size.height/2); +// +// self.enableBarcodeSwitch.center = CGPointMake(self.enableBarcodeLabel.frame.size.width + self.enableBarcodeSwitch.frame.size.width/2 + padding, +// self.enableBarcodeView.frame.size.height/2); +// +// CGFloat width = self.enableBarcodeSwitch.frame.size.width + padding + self.enableBarcodeLabel.frame.size.width; +// self.enableBarcodeView.frame = CGRectMake(self.scanView.frame.size.width-width-15, +// self.scanView.frame.size.height-self.enableBarcodeView.frame.size.height-55, +// width, +// 50); +//} /* Cancel scanning to allow the module to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.meterScanViewPlugin stopAndReturnError:nil]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [self.meterScanViewPlugin stopAndReturnError:nil]; +//} #pragma mark - IBAction methods -- (IBAction)toggleBarcodeScanning:(id)sender { - UISwitch * switcher = sender; - switcher.enabled = NO; - switcher.alpha = 0.5; - if (self.scanView.captureDeviceManager.barcodeDelegates.count > 0) { - self.enableBarcodeSwitch.on = false; - [self.scanView.captureDeviceManager removeBarcodeDelegate:self]; - //reset found barcode - self.barcodeResult = @""; - } else { - self.enableBarcodeSwitch.on = true; - [self.scanView.captureDeviceManager setNativeBarcodeFormats:[self.class nativeBarcodeFormats]]; - [self.scanView.captureDeviceManager addBarcodeDelegate:self error:nil]; - } - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - switcher.enabled = YES; - switcher.alpha = 1; - }); -} +//- (IBAction)toggleBarcodeScanning:(id)sender { +// UISwitch * switcher = sender; +// switcher.enabled = NO; +// switcher.alpha = 0.5; +// if (self.scanView.captureDeviceManager.barcodeDelegates.count > 0) { +// self.enableBarcodeSwitch.on = false; +// [self.scanView.captureDeviceManager removeBarcodeDelegate:self]; +// //reset found barcode +// self.barcodeResult = @""; +// } else { +// self.enableBarcodeSwitch.on = true; +// [self.scanView.captureDeviceManager addBarcodeDelegate:self error:nil]; +// } +// +// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ +// switcher.enabled = YES; +// switcher.alpha = 1; +// }); +//} #pragma mark - Barcode View layout - (UIView *)createBarcodeSwitchView { @@ -184,54 +183,34 @@ - (UIView *)createBarcodeSwitchView { /* The main delegate method Anyline uses to report its scanned codes */ -- (void)anylineMeterScanPlugin:(ALMeterScanPlugin *)anylineMeterScanPlugin - didFindResult:(ALMeterResult *)scanResult { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Meter Reading" value:scanResult.result]]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode" value:self.barcodeResult shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - [self anylineDidFindResult:jsonString barcodeResult:self.barcodeResult image:(UIImage*)scanResult.image scanPlugin:anylineMeterScanPlugin viewPlugin:self.meterScanViewPlugin completion:^{ - ALResultViewController *vc = [[ALResultViewController alloc] - initWithResults:resultData]; - vc.imagePrimary = scanResult.image; - [self.navigationController pushViewController:vc animated:YES]; - }]; - - //reset found barcodes - self.barcodeResult = @""; -} +//- (void)anylineMeterScanPlugin:(ALMeterScanPlugin *)anylineMeterScanPlugin +// didFindResult:(ALMeterResult *)scanResult { +// NSMutableArray *resultData = [[NSMutableArray alloc] init]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Meter Reading" value:scanResult.result]]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode" value:self.barcodeResult shouldSpellOutValue:YES]]; +// NSString *jsonString = [self JSONStringFromResultData:resultData]; +// [self anylineDidFindResult:jsonString barcodeResult:self.barcodeResult image:(UIImage*)scanResult.image scanPlugin:anylineMeterScanPlugin viewPlugin:self.meterScanViewPlugin completion:^{ +// ALResultViewController *vc = [[ALResultViewController alloc] +// initWithResults:resultData]; +// vc.imagePrimary = scanResult.image; +// [self.navigationController pushViewController:vc animated:YES]; +// }]; +// +// //reset found barcodes +// self.barcodeResult = @""; +//} -#pragma mark - AnylineNativeBarcodeDelegate methods +//#pragma mark - AnylineNativeBarcodeDelegate methods /* An additional delegate which will add all found, and unique, barcodes to a Dictionary simultaneously. */ -- (void)anylineCaptureDeviceManager:(ALCaptureDeviceManager *)captureDeviceManager didFindBarcodeResult:(NSString *)scanResult type:(NSString *)barcodeType { - dispatch_async(dispatch_get_main_queue(), ^{ - if ([scanResult length] > 0 && ![self.barcodeResult isEqualToString:scanResult]) { - self.barcodeResult = scanResult; - } - }); -} +//- (void)anylineCaptureDeviceManager:(ALCaptureDeviceManager *)captureDeviceManager didFindBarcodeResult:(NSString *)scanResult type:(NSString *)barcodeType { +// dispatch_async(dispatch_get_main_queue(), ^{ +// if ([scanResult length] > 0 && ![self.barcodeResult isEqualToString:scanResult]) { +// self.barcodeResult = scanResult; +// } +// }); +//} -#pragma mark - List of (native) barcode formats to support - -+ (NSArray *)nativeBarcodeFormats { - return @[ - AVMetadataObjectTypeAztecCode, - AVMetadataObjectTypeCode128Code, - AVMetadataObjectTypeCode39Code, - AVMetadataObjectTypeCode39Mod43Code, - AVMetadataObjectTypeCode93Code, - AVMetadataObjectTypeDataMatrixCode, - AVMetadataObjectTypeEAN13Code, - AVMetadataObjectTypeEAN8Code, - AVMetadataObjectTypeITF14Code, - AVMetadataObjectTypeInterleaved2of5Code, - AVMetadataObjectTypePDF417Code, - AVMetadataObjectTypeQRCode, - AVMetadataObjectTypeUPCECode, - ]; -} - @end diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALDialMeterScanViewController.m b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALDialMeterScanViewController.m index 2c8a4069a..5ac5625a2 100644 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALDialMeterScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALDialMeterScanViewController.m @@ -17,15 +17,15 @@ static const NSInteger padding = 7; // The controller has to conform to to be able to receive results -@interface ALDialMeterScanViewController () +@interface ALDialMeterScanViewController () // // The Anyline plugins used to scan -@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; -@property (nonatomic, strong) ALMeterScanPlugin *meterScanPlugin; -@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin; -@property (nonatomic, strong) ALBarcodeScanPlugin *barcodeScanPlugin; -@property (nonatomic, strong) ALParallelScanViewPluginComposite *parallelScanViewPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; +//@property (nonatomic, strong) ALMeterScanPlugin *meterScanPlugin; +//@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin; +//@property (nonatomic, strong) ALBarcodeScanPlugin *barcodeScanPlugin; +//@property (nonatomic, strong) ALParallelScanViewPluginComposite *parallelScanViewPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; //Native barcode scanning properties @property (nonatomic, strong) NSString *barcodeResult; @@ -51,40 +51,39 @@ - (void)viewDidLoad { //Add Meter Scan Plugin (Scan Process) NSError *error = nil; - self.meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"ENERGY" delegate:self error:&error]; - NSAssert(self.meterScanPlugin, @"Setup Error: %@", error.debugDescription); - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"meter_barcode_view_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - //Add Meter Scan View Plugin (Scan UI) - self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:self.meterScanPlugin]; - - - //Set ScanMode to ALAutoAnalogDigitalMeter - BOOL success = [self.meterScanPlugin setScanMode:ALDialMeter error:&error]; - if( !success ) { - // Something went wrong. The error object contains the error description - __weak __block typeof(self) weakSelf = self; - [self showAlertWithTitle:@"Set ScanMode Error" message:error.debugDescription completion:^{ - [weakSelf.navigationController popViewControllerAnimated:YES]; - }]; - } - - self.barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] initWithPluginID:@"BARCODE" delegate:self error:&error]; - NSAssert(self.barcodeScanPlugin, @"Setup Error: %@", error.debugDescription); - - //Set Barcode Formats - [self.barcodeScanPlugin setBarcodeFormatOptions:@[kCodeTypeAll]]; - - //Add Barcode Scan View Plugin (Scan UI) - self.barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] initWithScanPlugin:self.barcodeScanPlugin scanViewPluginConfig:scanViewPluginConfig]; - - self.parallelScanViewPlugin = [[ALParallelScanViewPluginComposite alloc] initWithPluginID:@"Energy with meter ID"]; - [self.parallelScanViewPlugin addPlugin:self.meterScanViewPlugin]; - [self.parallelScanViewPlugin addPlugin:self.barcodeScanViewPlugin]; - - //Add ScanView (Camera and Flashbutton) - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:[self selectedPlugin]]; - +// self.meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"ENERGY" delegate:self error:&error]; +// NSAssert(self.meterScanPlugin, @"Setup Error: %@", error.debugDescription); +// NSString *confPath = [[NSBundle mainBundle] pathForResource:@"meter_barcode_view_config" ofType:@"json"]; +// ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +// //Add Meter Scan View Plugin (Scan UI) +// self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:self.meterScanPlugin]; +// +// +// //Set ScanMode to ALAutoAnalogDigitalMeter +// BOOL success = [self.meterScanPlugin setScanMode:ALDialMeter error:&error]; +// if( !success ) { +// // Something went wrong. The error object contains the error description +// __weak __block typeof(self) weakSelf = self; +// [self showAlertWithTitle:@"Set ScanMode Error" message:error.debugDescription completion:^{ +// [weakSelf.navigationController popViewControllerAnimated:YES]; +// }]; +// } +// +// self.barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] initWithPluginID:@"BARCODE" delegate:self error:&error]; +// NSAssert(self.barcodeScanPlugin, @"Setup Error: %@", error.debugDescription); +// +// //Set Barcode Formats +// [self.barcodeScanPlugin setBarcodeFormatOptions:@[kCodeTypeAll]]; +// +// //Add Barcode Scan View Plugin (Scan UI) +// self.barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] initWithScanPlugin:self.barcodeScanPlugin scanViewPluginConfig:scanViewPluginConfig]; +// +// self.parallelScanViewPlugin = [[ALParallelScanViewPluginComposite alloc] initWithPluginID:@"Energy with meter ID"]; +// [self.parallelScanViewPlugin addPlugin:self.meterScanViewPlugin]; +// [self.parallelScanViewPlugin addPlugin:self.barcodeScanViewPlugin]; +// +// //Add ScanView (Camera and Flashbutton) +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:[self selectedPlugin]]; //Adding the scanView [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.view addSubview:self.scanView]; @@ -97,181 +96,181 @@ - (void)viewDidLoad { [NSLayoutConstraint activateConstraints:scanViewConstraints]; [self.scanView startCamera]; - self.meterScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; +// self.meterScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; // After setup is complete we add the scanView to the view of this view controller self.controllerType = ALScanHistoryElectricMeter; - [self.scanView addSubview:[self createBarcodeSwitchView]]; +// [self.scanView addSubview:[self createBarcodeSwitchView]]; [self.scanView bringSubviewToFront:self.enableBarcodeView]; } /* This method will be called once the view controller and its subviews have appeared on screen */ -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self setAsCurrentPlugin:[self selectedPlugin]]; -} - -- (void)viewDidLayoutSubviews { - [super viewDidLayoutSubviews]; - - [self updateLayoutBarcodeSwitchView]; -} +//- (void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// [self setAsCurrentPlugin:[self selectedPlugin]]; +//} +// +//- (void)viewDidLayoutSubviews { +// [super viewDidLayoutSubviews]; +// +// [self updateLayoutBarcodeSwitchView]; +//} /* Cancel scanning to allow the module to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [[self selectedPlugin] stopAndReturnError:nil]; -} - -- (ALAbstractScanViewPlugin *)selectedPlugin { - if (self.enableBarcodeSwitch.on) { - return self.parallelScanViewPlugin; - } else { - return self.meterScanViewPlugin; - } -} - -- (void)setAsCurrentPlugin:(ALAbstractScanViewPlugin *)plugin { - self.scanView.scanViewPlugin = plugin; - [self stopPlugin:plugin]; //just in case it is already running for some reason - [self startPlugin:plugin]; - [self.scanView bringSubviewToFront:self.enableBarcodeView]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [[self selectedPlugin] stopAndReturnError:nil]; +//} +// +//- (ALAbstractScanViewPlugin *)selectedPlugin { +// if (self.enableBarcodeSwitch.on) { +// return self.parallelScanViewPlugin; +// } else { +// return self.meterScanViewPlugin; +// } +//} -- (void)stopPlugin:(ALAbstractScanViewPlugin *)plugin { - NSError *error = nil; - [plugin stopAndReturnError:&error]; - if (error) { - [self showAlertWithTitle:@"Error stopping scanning" - message:error.debugDescription - completion:nil]; - } -} +//- (void)setAsCurrentPlugin:(ALAbstractScanViewPlugin *)plugin { +// self.scanView.scanViewPlugin = plugin; +// [self stopPlugin:plugin]; //just in case it is already running for some reason +// [self startPlugin:plugin]; +// [self.scanView bringSubviewToFront:self.enableBarcodeView]; +//} +// +//- (void)stopPlugin:(ALAbstractScanViewPlugin *)plugin { +// NSError *error = nil; +// [plugin stopAndReturnError:&error]; +// if (error) { +// [self showAlertWithTitle:@"Error stopping scanning" +// message:error.debugDescription +// completion:nil]; +// } +//} #pragma mark - IBAction methods -- (IBAction)toggleBarcodeScanning:(id)sender { - UISwitch * switcher = sender; - switcher.enabled = NO; - switcher.alpha = 0.5; - - if (self.enableBarcodeSwitch.on) { - [self stopPlugin:self.meterScanViewPlugin]; - [self stopPlugin:self.barcodeScanViewPlugin]; //in some rare cases this can still be running, which stops the parallel scan view plugin from starting - [self setAsCurrentPlugin:self.parallelScanViewPlugin]; - } else { - //we probably don't want to keep these values from when the switch was previously enabled - self.barcodeResult = nil; - [self stopPlugin:self.parallelScanViewPlugin]; - if ([self.meterResult length]) { - //if we already have a meter result, and we no longer need a barcode, display the results immediately rather than trying to scan the meter again. - [self displayResultsIfPresent]; - } else { - [self setAsCurrentPlugin:self.meterScanViewPlugin]; - } - } - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - switcher.enabled = YES; - switcher.alpha = 1; - }); -} +//- (IBAction)toggleBarcodeScanning:(id)sender { +// UISwitch * switcher = sender; +// switcher.enabled = NO; +// switcher.alpha = 0.5; +// +// if (self.enableBarcodeSwitch.on) { +// [self stopPlugin:self.meterScanViewPlugin]; +// [self stopPlugin:self.barcodeScanViewPlugin]; //in some rare cases this can still be running, which stops the parallel scan view plugin from starting +// [self setAsCurrentPlugin:self.parallelScanViewPlugin]; +// } else { +// //we probably don't want to keep these values from when the switch was previously enabled +// self.barcodeResult = nil; +// [self stopPlugin:self.parallelScanViewPlugin]; +// if ([self.meterResult length]) { +// //if we already have a meter result, and we no longer need a barcode, display the results immediately rather than trying to scan the meter again. +// [self displayResultsIfPresent]; +// } else { +// [self setAsCurrentPlugin:self.meterScanViewPlugin]; +// } +// } +// +// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ +// switcher.enabled = YES; +// switcher.alpha = 1; +// }); +//} #pragma mark - Barcode View layouting -- (UIView *)createBarcodeSwitchView { - //Add UISwitch for toggling barcode scanning - self.enableBarcodeView = [[UIView alloc] init]; - self.enableBarcodeView.frame = CGRectMake(0, 0, 150, 50); - - self.enableBarcodeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; - self.enableBarcodeLabel.text = @"Barcode Detection"; - UIFont *font = [UIFont systemFontOfSize:14 weight:UIFontWeightThin]; - self.enableBarcodeLabel.font = font; - self.enableBarcodeLabel.numberOfLines = 0; - - self.enableBarcodeLabel.textColor = [UIColor whiteColor]; - [self.enableBarcodeLabel sizeToFit]; - - self.enableBarcodeSwitch = [[UISwitch alloc] init]; - [self.enableBarcodeSwitch setOn:false]; - [self.enableBarcodeSwitch setOnTintColor:[UIColor AL_NonSelectedToolBarItem]]; - [self.enableBarcodeSwitch useHighContrast]; - [self.enableBarcodeSwitch addTarget:self action:@selector(toggleBarcodeScanning:) forControlEvents:UIControlEventValueChanged]; - - [self.enableBarcodeView addSubview:self.enableBarcodeLabel]; - [self.enableBarcodeView addSubview:self.enableBarcodeSwitch]; - - return self.enableBarcodeView; -} - -- (void)updateLayoutBarcodeSwitchView { - self.enableBarcodeLabel.center = CGPointMake(self.enableBarcodeLabel.frame.size.width/2, - self.enableBarcodeView.frame.size.height/2); - - self.enableBarcodeSwitch.center = CGPointMake(self.enableBarcodeLabel.frame.size.width + self.enableBarcodeSwitch.frame.size.width/2 + padding, - self.enableBarcodeView.frame.size.height/2); - - CGFloat width = self.enableBarcodeSwitch.frame.size.width + padding + self.enableBarcodeLabel.frame.size.width; - self.enableBarcodeView.frame = CGRectMake(self.scanView.frame.size.width-width-15, - self.scanView.frame.size.height-self.enableBarcodeView.frame.size.height-55, - width, - 50); -} - -- (void)displayResultsIfPresent { - if ([self.meterResult length]) { - if (!self.enableBarcodeSwitch.on || self.barcodeResult) { - [self displayResults]; - } - } -} - -- (void)displayResults { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Meter Reading" value:self.meterResult]]; - if (self.barcodeResult) { - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode" value:self.barcodeResult shouldSpellOutValue:YES]]; - } - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:self.barcodeResult image:self.meterImage scanPlugin:self.meterScanPlugin viewPlugin:self.meterScanViewPlugin completion:^{ +//- (UIView *)createBarcodeSwitchView { +// //Add UISwitch for toggling barcode scanning +// self.enableBarcodeView = [[UIView alloc] init]; +// self.enableBarcodeView.frame = CGRectMake(0, 0, 150, 50); +// +// self.enableBarcodeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; +// self.enableBarcodeLabel.text = @"Barcode Detection"; +// UIFont *font = [UIFont systemFontOfSize:14 weight:UIFontWeightThin]; +// self.enableBarcodeLabel.font = font; +// self.enableBarcodeLabel.numberOfLines = 0; +// +// self.enableBarcodeLabel.textColor = [UIColor whiteColor]; +// [self.enableBarcodeLabel sizeToFit]; +// +// self.enableBarcodeSwitch = [[UISwitch alloc] init]; +// [self.enableBarcodeSwitch setOn:false]; +// [self.enableBarcodeSwitch setOnTintColor:[UIColor AL_NonSelectedToolBarItem]]; +// [self.enableBarcodeSwitch useHighContrast]; +// [self.enableBarcodeSwitch addTarget:self action:@selector(toggleBarcodeScanning:) forControlEvents:UIControlEventValueChanged]; +// +// [self.enableBarcodeView addSubview:self.enableBarcodeLabel]; +// [self.enableBarcodeView addSubview:self.enableBarcodeSwitch]; +// +// return self.enableBarcodeView; +//} +// +//- (void)updateLayoutBarcodeSwitchView { +// self.enableBarcodeLabel.center = CGPointMake(self.enableBarcodeLabel.frame.size.width/2, +// self.enableBarcodeView.frame.size.height/2); +// +// self.enableBarcodeSwitch.center = CGPointMake(self.enableBarcodeLabel.frame.size.width + self.enableBarcodeSwitch.frame.size.width/2 + padding, +// self.enableBarcodeView.frame.size.height/2); +// +// CGFloat width = self.enableBarcodeSwitch.frame.size.width + padding + self.enableBarcodeLabel.frame.size.width; +// self.enableBarcodeView.frame = CGRectMake(self.scanView.frame.size.width-width-15, +// self.scanView.frame.size.height-self.enableBarcodeView.frame.size.height-55, +// width, +// 50); +//} - ALResultViewController *vc = [[ALResultViewController alloc] - initWithResults:resultData]; - vc.imagePrimary = self.meterImage; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; +//- (void)displayResultsIfPresent { +// if ([self.meterResult length]) { +// if (!self.enableBarcodeSwitch.on || self.barcodeResult) { +// [self displayResults]; +// } +// } +//} - self.barcodeResult = @""; -} +//- (void)displayResults { +// NSMutableArray *resultData = [[NSMutableArray alloc] init]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Meter Reading" value:self.meterResult]]; +// if (self.barcodeResult) { +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode" value:self.barcodeResult shouldSpellOutValue:YES]]; +// } +// NSString *jsonString = [self JSONStringFromResultData:resultData]; +// +// __weak __block typeof(self) weakSelf = self; +// [self anylineDidFindResult:jsonString barcodeResult:self.barcodeResult image:self.meterImage scanPlugin:self.meterScanPlugin viewPlugin:self.meterScanViewPlugin completion:^{ +// +// ALResultViewController *vc = [[ALResultViewController alloc] +// initWithResults:resultData]; +// vc.imagePrimary = self.meterImage; +// [weakSelf.navigationController pushViewController:vc animated:YES]; +// }]; +// +// self.barcodeResult = @""; +//} #pragma mark - ALMeterScanPluginDelegate methods /* The main delegate method Anyline uses to report its scanned codes */ -- (void)anylineMeterScanPlugin:(ALMeterScanPlugin * _Nonnull)anylineMeterScanPlugin didFindResult:(ALMeterResult * _Nonnull)scanResult { - self.meterResult = scanResult.result; - self.meterImage = scanResult.image; - [self displayResultsIfPresent]; -} - - -- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin * _Nonnull)anylineBarcodeScanPlugin didFindResult:(ALBarcodeResult * _Nonnull)scanResult { - dispatch_async(dispatch_get_main_queue(), ^{ - if (scanResult.result) { - self.barcodeResult = [[scanResult.result firstObject] value]; - } else { - //if we get a nil barcode result for some reason, we don't want to just be stuck on the screen with no scanners running. - self.barcodeResult = @""; - } - [self displayResultsIfPresent]; - }); -} +//- (void)anylineMeterScanPlugin:(ALMeterScanPlugin * _Nonnull)anylineMeterScanPlugin didFindResult:(ALMeterResult * _Nonnull)scanResult { +// self.meterResult = scanResult.result; +// self.meterImage = scanResult.image; +// [self displayResultsIfPresent]; +//} +// +// +//- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin * _Nonnull)anylineBarcodeScanPlugin didFindResult:(ALBarcodeResult * _Nonnull)scanResult { +// dispatch_async(dispatch_get_main_queue(), ^{ +// if (scanResult.result) { +// self.barcodeResult = [[scanResult.result firstObject] value]; +// } else { +// //if we get a nil barcode result for some reason, we don't want to just be stuck on the screen with no scanners running. +// self.barcodeResult = @""; +// } +// [self displayResultsIfPresent]; +// }); +//} diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanResultViewController.h b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanResultViewController.h index 7840df2f4..ea7b5b24e 100755 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanResultViewController.h +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanResultViewController.h @@ -12,7 +12,7 @@ @interface ALMeterScanResultViewController : UIViewController -@property (nonatomic) ALScanMode scanMode; +//@property (nonatomic) ALScanMode scanMode; @property (nonatomic, strong) NSString *result; diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanResultViewController.m b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanResultViewController.m index 4e9a76ac3..b68d8c429 100755 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanResultViewController.m +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanResultViewController.m @@ -63,22 +63,21 @@ - (void)viewDidLoad { NSString *unit = @""; - switch (self.scanMode) { - case ALDigitalMeter: - case ALAutoAnalogDigitalMeter: - case ALDigitalMeter2Experimental: - unit = @"kWh"; - break; - case ALHeatMeter4: - case ALHeatMeter5: - case ALHeatMeter6: - case ALAnalogMeter: - unit = @"m\u00B3"; - break; - default: - unit = @""; - break; - } +// switch (self.scanMode) { +// case ALDigitalMeter: +// case ALAutoAnalogDigitalMeter: +// unit = @"kWh"; +// break; +// case ALHeatMeter4: +// case ALHeatMeter5: +// case ALHeatMeter6: +// case ALAnalogMeter: +// unit = @"m\u00B3"; +// break; +// default: +// unit = @""; +// break; +// } self.unitLabel.text = unit; if (![self.barcodeResult isEqualToString:@""] && self.barcodeResult.length > 0) { diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanViewController.swift b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanViewController.swift new file mode 100644 index 000000000..fb53440b0 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterScanViewController.swift @@ -0,0 +1,288 @@ +import Foundation + +class ALMeterScanViewController: ALBaseScanViewController { + + var scanViewPlugin: ALScanViewPluginBase? + + var scanMode: ALMeterConfigScanMode = .autoAnalogDigitalMeter() + + var meterResultEntries: [ALResultEntry]? + + var barcodeResultEntries: [ALResultEntry]? + + var meterImage: UIImage? + + var barcodeImage: UIImage? + + var barcodeString: String? + + var withBarcode: Bool = false { + didSet { + reloadScanView() + clearResults() + try! self.scanViewPlugin?.start() + } + } + + var configJSONFilename: String { + withBarcode ? "parallel_meter_barcode_config" : "meter_config" + } + + override func viewDidLoad() { + super.viewDidLoad() + + // fix title (but if you came by Meter Reading, the title will be prefilled) + if self.title == nil || self.title!.count < 1 { + self.title = "Analog/Digital Meter" + } + + if (self.title == "Digital (APAC)") { + self.scanMode = .digitalMeter2_Experimental() + } else if (self.title == "Dial Meter" || self.title == "Dial") { + self.scanMode = .dialMeter() + } else { + self.scanMode = .autoAnalogDigitalMeter() + } + + self.controllerType = ALScanHistoryElectricMeter + + setUpBarcodeSwitchView() + + reloadScanView() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + try! self.scanViewPlugin?.start() + } + + func clearResults() { + meterImage = nil + meterResultEntries = nil + barcodeResultEntries = nil + barcodeString = nil + barcodeImage = nil + } + + fileprivate func reloadScanView() { + guard let JSONStr = self.configJSONStr(withFilename: configJSONFilename), + let JSONDict = (JSONStr as NSString).asJSONObject() as? [String : Any] else { + print("error: unable to find json config") + return + } + + let scanViewPluginBase: ALScanViewPluginBase? = scanViewPluginConfig(fromDict: JSONDict, + scanMode: self.scanMode) + // ScanViewConfig + let configJSONDict: [AnyHashable: Any]! = [:] + let scanViewConfig: ALScanViewConfig? = .withJSONDictionary(configJSONDict) + + self.scanViewPlugin = scanViewPluginBase + + if self.scanView != nil { + do { + try self.scanView?.setScanViewPlugin(scanViewPluginBase!) + } catch { + print("unable to set scan view plugin: \(error.localizedDescription)") + } + } else { + do { + self.scanView = try .init(frame: .zero, + scanViewPlugin: scanViewPluginBase!, + scanViewConfig: scanViewConfig) + self.scanView?.delegate = self + + if let scanView = self.scanView { + self.installScanView(scanView) + self.view.sendSubviewToBack(scanView) + scanView.startCamera() + } + } catch { + print("unable to instantiate scan view: \(error.localizedDescription)") + } + } + } + + func scanViewPluginConfig(fromDict JSONDict: [String: Any], scanMode: ALMeterConfigScanMode) -> ALScanViewPluginBase? { + if withBarcode { + var composite = ALScanViewPluginFactory.withJSONDictionary(JSONDict) as! ALViewPluginComposite + // we have a composite with two children in this view controller (as per JSON). For the meter child, + // reconstruct it + var children = [ALScanViewPlugin]() + composite.children.forEach { child in + if let svpCopy = child as? ALScanViewPlugin { + // remake a scanViewPlugin with your change to the meter plugin scan mode + let scanPluginConfig = svpCopy.scanPlugin.scanPluginConfig + scanPluginConfig.pluginConfig.meterConfig?.scanMode = scanMode + if let newSVP: ALScanViewPlugin = try! .init(config: try! .init(scanPluginConfig: scanPluginConfig, + cutoutConfig: svpCopy.scanViewPluginConfig.cutoutConfig, + scanFeedbackConfig: svpCopy.scanViewPluginConfig.scanFeedbackConfig)) { + newSVP.delegate = self + newSVP.scanPlugin.delegate = self + children.append(newSVP) + } + } + } + + if let newComposite: ALViewPluginComposite = try! .init(id: composite.pluginID, + mode: composite.processingMode, + children: children) { + composite = newComposite + } + composite.delegate = self + return composite + + } else { + let config = ALScanViewPluginConfig.withJSONDictionary(JSONDict)! + var scanViewPlugin: ALScanViewPlugin? = try! .init(config: config) + + // NOTE: this won't work! ScanPlugin has already been created and the script loaded. You won't be changing it + // here. Recreate from scratch. + // scanViewPlugin?.scanPlugin.scanPluginConfig.pluginConfig.meterConfig?.scanMode = .dialMeter() + + if let svpCopy = scanViewPlugin { + let scanPluginConfig = svpCopy.scanPlugin.scanPluginConfig + scanPluginConfig.pluginConfig.meterConfig?.scanMode = scanMode + scanViewPlugin = try! .init(config: .init(scanPluginConfig: scanPluginConfig, + cutoutConfig: svpCopy.scanViewPluginConfig.cutoutConfig, + scanFeedbackConfig: svpCopy.scanViewPluginConfig.scanFeedbackConfig)) + } + + scanViewPlugin?.scanPlugin.delegate = self + scanViewPlugin?.delegate = self + return scanViewPlugin + } + } + + private func setUpBarcodeSwitchView() { + let container: UIView = .init() + container.translatesAutoresizingMaskIntoConstraints = false + + let label: UILabel = .init() + label.font = .al_proximaRegular(withSize: 14) + label.text = "Barcode Detection" + label.numberOfLines = 0 + label.textColor = .white + label.translatesAutoresizingMaskIntoConstraints = false + + let attributedString = NSMutableAttributedString(string: label.text!) + attributedString.addAttribute(NSAttributedString.Key.kern, value: CGFloat(0.03), range: NSRange(location: 0, length: attributedString.length)) + label.attributedText = attributedString + + let toggle: UISwitch = .init() + toggle.isOn = withBarcode + toggle.tintColor = .init(red: 0, green: 153/255.0, blue: 1, alpha: 1) + // toggle.useHighContrast() // ? + toggle.translatesAutoresizingMaskIntoConstraints = false + + toggle.addTarget(self, action: #selector(barcodeSwitchToggled(_:)), for: .valueChanged) + + container.addSubview(label) + container.addSubview(toggle) + + label.rightAnchor.constraint(equalTo: toggle.leftAnchor, constant: -10).isActive = true + label.centerYAnchor.constraint(equalTo: toggle.centerYAnchor).isActive = true + + toggle.rightAnchor.constraint(equalTo: container.rightAnchor, constant: -20).isActive = true + label.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true + + self.view.addSubview(container) + container.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true + container.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true + container.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor).isActive = true + container.heightAnchor.constraint(equalToConstant: 80).isActive = true + } + + @objc + func barcodeSwitchToggled(_ toggle: UISwitch?) { + self.withBarcode = toggle?.isOn ?? false + } +} + +extension ALMeterScanViewController: ALScanPluginDelegate, ALScanViewPluginDelegate, ALViewPluginCompositeDelegate { + + func scanPlugin(_ scanPlugin: ALScanPlugin, resultReceived scanResult: ALScanResult) { + if let _ = self.loadMeterResult(from: scanResult) { + if !withBarcode { + displayResults() + } + } + if let barcodeString = self.loadBarcodeResult(from: scanResult) { + self.barcodeString = barcodeString + } + } + + func viewPluginComposite(_ viewPluginComposite: ALViewPluginComposite, allResultsReceived scanResults: [ALScanResult]) { + displayResults() + } + + func loadBarcodeResult(from scanResult: ALScanResult) -> String? { + if let barcodeResult = scanResult.pluginResult.barcodeResult { + self.barcodeResultEntries = barcodeResult.resultEntryList + self.barcodeImage = scanResult.croppedImage + return barcodeResult.barcodes.first?.decoded() // get one for the barcode string to be used later + } + return nil + } + + func loadMeterResult(from scanResult: ALScanResult) -> String? { + if let meterResult = scanResult.pluginResult.meterResult { + var result = meterResult.value + if let meterUnit = meterResult.unit { + result += String(format: " %@", meterUnit) + } // move this result to extension + self.meterResultEntries = meterResult.resultEntryList + self.meterImage = scanResult.croppedImage + return result + } + return nil + } + + func displayResults() { + guard let scanViewPlugin = self.scanViewPlugin else { + print("error: need both ScanViewPlugin") + return + } + + var resultData: [ALResultEntry] = [] + if let resultEntries = self.meterResultEntries { + resultData.append(contentsOf: resultEntries) + } + if let resultEntries = self.barcodeResultEntries { + resultData.append(contentsOf: resultEntries) + } + + var scanPlugin: ALScanPlugin! + if let scanViewPlugin = self.scanViewPlugin as? ALScanViewPlugin { + // this is it + scanPlugin = scanViewPlugin.scanPlugin + } else if let composite = self.scanViewPlugin as? ALViewPluginComposite { + scanPlugin = composite.children.compactMap { base in + if let b = base as? ALScanViewPlugin { + return b.scanPlugin + } + return nil + }.first + } + + guard let scanPlugin = scanPlugin else { + return + } + + let JSONString = resultData.JSONStringFromResultData! + + self.anylineDidFindResult(JSONString, + barcodeResult: self.barcodeString, + image: self.meterImage, + scanPlugin: scanPlugin, + viewPlugin: scanViewPlugin) { [weak self] in + let resultVC: ALResultViewController = .init(results: resultData) + resultVC.imagePrimary = self?.meterImage + resultVC.imageSecondary = self?.barcodeImage + self?.navigationController?.pushViewController(resultVC, animated: true) + + self?.clearResults() + } + + } +} diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterSerialNumberScanViewController.m b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterSerialNumberScanViewController.m index 660a57367..943058bf0 100644 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterSerialNumberScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALMeterSerialNumberScanViewController.m @@ -16,12 +16,12 @@ static const NSInteger padding = 7; // The controller has to conform to to be able to receive results -@interface ALMeterSerialNumberScanViewController () +@interface ALMeterSerialNumberScanViewController() // // The Anyline plugins used to scan -@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; -@property (nonatomic, strong) ALMeterScanPlugin *meterScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; +//@property (nonatomic, strong) ALMeterScanPlugin *meterScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; //Native barcode scanning properties @property (nonatomic, strong) NSString *barcodeResult; @@ -46,163 +46,163 @@ - (void)viewDidLoad { //Add Meter Scan Plugin (Scan Process) NSError *error = nil; - self.meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"ENERGY" delegate:self error:&error]; - NSAssert(self.meterScanPlugin, @"Setup Error: %@", error.debugDescription); - - //Add Meter Scan View Plugin (Scan UI) - self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:self.meterScanPlugin]; - - - //Set ScanMode to ALSerialNumber - BOOL success = [self.meterScanPlugin setScanMode:ALSerialNumber error:&error]; - if( !success ) { - // Something went wrong. The error object contains the error description - __weak __block typeof(self) weakSelf = self; - [self showAlertWithTitle:@"Set ScanMode Error" - message:error.debugDescription completion:^{ - [weakSelf.navigationController popViewControllerAnimated:YES]; - }]; - - } - - //Add ScanView (Camera and Flashbutton) - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.meterScanViewPlugin]; - - //Enable Zoom Gesture - [self.scanView enableZoomPinchGesture:YES]; +// self.meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"ENERGY" delegate:self error:&error]; +// NSAssert(self.meterScanPlugin, @"Setup Error: %@", error.debugDescription); +// +// //Add Meter Scan View Plugin (Scan UI) +// self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:self.meterScanPlugin]; +// +// +// //Set ScanMode to ALSerialNumber +// BOOL success = [self.meterScanPlugin setScanMode:ALSerialNumber error:&error]; +// if( !success ) { +// // Something went wrong. The error object contains the error description +// __weak __block typeof(self) weakSelf = self; +// [self showAlertWithTitle:@"Set ScanMode Error" +// message:error.debugDescription completion:^{ +// [weakSelf.navigationController popViewControllerAnimated:YES]; +// }]; +// +// } +// +// //Add ScanView (Camera and Flashbutton) +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.meterScanViewPlugin]; +// +// //Enable Zoom Gesture +// [self.scanView enableZoomPinchGesture:YES]; //Adding the scanView - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - [self.scanView startCamera]; - - self.meterScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; +// [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; +// [self.view addSubview:self.scanView]; +// [self.view sendSubviewToBack:self.scanView]; +// NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], +// [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], +// [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], +// [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; +// [self.view addConstraints:scanViewConstraints]; +// [NSLayoutConstraint activateConstraints:scanViewConstraints]; +// [self.scanView startCamera]; + +// self.meterScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; self.controllerType = ALScanHistoryElectricMeter; - self.barcodeResult = @""; - [self.scanView addSubview:[self createBarcodeSwitchView]]; - [self.scanView bringSubviewToFront:self.enableBarcodeView]; +// self.barcodeResult = @""; +// [self.scanView addSubview:[self createBarcodeSwitchView]]; +// [self.scanView bringSubviewToFront:self.enableBarcodeView]; } /* This method will be called once the view controller and its subviews have appeared on screen */ -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self startPlugin:self.meterScanViewPlugin]; -} - -- (void)viewDidLayoutSubviews { - [super viewDidLayoutSubviews]; - [self updateLayoutBarcodeSwitchView]; -} +//- (void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// [self startPlugin:self.meterScanViewPlugin]; +//} +// +//- (void)viewDidLayoutSubviews { +// [super viewDidLayoutSubviews]; +// [self updateLayoutBarcodeSwitchView]; +//} /* Cancel scanning to allow the module to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.meterScanViewPlugin stopAndReturnError:nil]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [self.meterScanViewPlugin stopAndReturnError:nil]; +//} #pragma mark - IBAction methods -- (IBAction)toggleBarcodeScanning:(id)sender { - - if (self.scanView.captureDeviceManager.barcodeDelegates.count > 0) { - self.enableBarcodeSwitch.on = false; - [self.scanView.captureDeviceManager removeBarcodeDelegate:self]; - //reset found barcode - self.barcodeResult = @""; - } else { - self.enableBarcodeSwitch.on = true; - [self.scanView.captureDeviceManager addBarcodeDelegate:self error:nil]; - } -} +//- (IBAction)toggleBarcodeScanning:(id)sender { +// +// if (self.scanView.captureDeviceManager.barcodeDelegates.count > 0) { +// self.enableBarcodeSwitch.on = false; +// [self.scanView.captureDeviceManager removeBarcodeDelegate:self]; +// //reset found barcode +// self.barcodeResult = @""; +// } else { +// self.enableBarcodeSwitch.on = true; +// [self.scanView.captureDeviceManager addBarcodeDelegate:self error:nil]; +// } +//} #pragma mark - Barcode View layouting -- (UIView *)createBarcodeSwitchView { - //Add UISwitch for toggling barcode scanning - self.enableBarcodeView = [[UIView alloc] init]; - self.enableBarcodeView.frame = CGRectMake(100, 100, 150, 50); - - self.enableBarcodeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; - self.enableBarcodeLabel.text = @"Barcode Detection"; - UIFont *font = [UIFont systemFontOfSize:14 weight:UIFontWeightThin]; - self.enableBarcodeLabel.font = font; - self.enableBarcodeLabel.numberOfLines = 0; - - self.enableBarcodeLabel.textColor = [UIColor whiteColor]; - [self.enableBarcodeLabel sizeToFit]; - - self.enableBarcodeSwitch = [[UISwitch alloc] init]; - [self.enableBarcodeSwitch setOn:false]; - [self.enableBarcodeSwitch setOnTintColor:[UIColor colorWithRed:0.0/255.0 green:153.0/255.0 blue:255.0/255.0 alpha:1.0]]; - [self.enableBarcodeSwitch useHighContrast]; - [self.enableBarcodeSwitch addTarget:self action:@selector(toggleBarcodeScanning:) forControlEvents:UIControlEventValueChanged]; - - [self.enableBarcodeView addSubview:self.enableBarcodeLabel]; - [self.enableBarcodeView addSubview:self.enableBarcodeSwitch]; - - return self.enableBarcodeView; -} - -- (void)updateLayoutBarcodeSwitchView { - self.enableBarcodeLabel.center = CGPointMake(self.enableBarcodeLabel.frame.size.width/2, - self.enableBarcodeView.frame.size.height/2); - - self.enableBarcodeSwitch.center = CGPointMake(self.enableBarcodeLabel.frame.size.width + self.enableBarcodeSwitch.frame.size.width/2 + padding, - self.enableBarcodeView.frame.size.height/2); +//- (UIView *)createBarcodeSwitchView { +// //Add UISwitch for toggling barcode scanning +// self.enableBarcodeView = [[UIView alloc] init]; +// self.enableBarcodeView.frame = CGRectMake(100, 100, 150, 50); +// +// self.enableBarcodeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; +// self.enableBarcodeLabel.text = @"Barcode Detection"; +// UIFont *font = [UIFont systemFontOfSize:14 weight:UIFontWeightThin]; +// self.enableBarcodeLabel.font = font; +// self.enableBarcodeLabel.numberOfLines = 0; +// +// self.enableBarcodeLabel.textColor = [UIColor whiteColor]; +// [self.enableBarcodeLabel sizeToFit]; +// +// self.enableBarcodeSwitch = [[UISwitch alloc] init]; +// [self.enableBarcodeSwitch setOn:false]; +// [self.enableBarcodeSwitch setOnTintColor:[UIColor colorWithRed:0.0/255.0 green:153.0/255.0 blue:255.0/255.0 alpha:1.0]]; +// [self.enableBarcodeSwitch useHighContrast]; +// [self.enableBarcodeSwitch addTarget:self action:@selector(toggleBarcodeScanning:) forControlEvents:UIControlEventValueChanged]; +// +// [self.enableBarcodeView addSubview:self.enableBarcodeLabel]; +// [self.enableBarcodeView addSubview:self.enableBarcodeSwitch]; +// +// return self.enableBarcodeView; +//} - CGFloat width = self.enableBarcodeSwitch.frame.size.width + padding + self.enableBarcodeLabel.frame.size.width; - self.enableBarcodeView.frame = CGRectMake(self.scanView.frame.size.width-width-15, - self.scanView.frame.size.height-self.enableBarcodeView.frame.size.height-55, - width, - 50); -} +//- (void)updateLayoutBarcodeSwitchView { +// self.enableBarcodeLabel.center = CGPointMake(self.enableBarcodeLabel.frame.size.width/2, +// self.enableBarcodeView.frame.size.height/2); +// +// self.enableBarcodeSwitch.center = CGPointMake(self.enableBarcodeLabel.frame.size.width + self.enableBarcodeSwitch.frame.size.width/2 + padding, +// self.enableBarcodeView.frame.size.height/2); +// +// CGFloat width = self.enableBarcodeSwitch.frame.size.width + padding + self.enableBarcodeLabel.frame.size.width; +// self.enableBarcodeView.frame = CGRectMake(self.scanView.frame.size.width-width-15, +// self.scanView.frame.size.height-self.enableBarcodeView.frame.size.height-55, +// width, +// 50); +//} #pragma mark - ALMeterScanPluginDelegate methods /* The main delegate method Anyline uses to report its scanned codes */ -- (void)anylineMeterScanPlugin:(ALMeterScanPlugin *)anylineMeterScanPlugin - didFindResult:(ALMeterResult *)scanResult { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Meter Serial Number" value:scanResult.result]]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode" value:self.barcodeResult shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:self.barcodeResult image:(UIImage*)scanResult.image scanPlugin:anylineMeterScanPlugin viewPlugin:self.meterScanViewPlugin completion:^{ - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = scanResult.image; - - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; - - //reset found barcodes - self.barcodeResult = @""; -} +//- (void)anylineMeterScanPlugin:(ALMeterScanPlugin *)anylineMeterScanPlugin +// didFindResult:(ALMeterResult *)scanResult { +// NSMutableArray *resultData = [[NSMutableArray alloc] init]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Meter Serial Number" value:scanResult.result]]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode" value:self.barcodeResult shouldSpellOutValue:YES]]; +// NSString *jsonString = [self JSONStringFromResultData:resultData]; +// +// __weak __block typeof(self) weakSelf = self; +// [self anylineDidFindResult:jsonString barcodeResult:self.barcodeResult image:(UIImage*)scanResult.image scanPlugin:anylineMeterScanPlugin viewPlugin:self.meterScanViewPlugin completion:^{ +// ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; +// vc.imagePrimary = scanResult.image; +// +// [weakSelf.navigationController pushViewController:vc animated:YES]; +// }]; +// +// //reset found barcodes +// self.barcodeResult = @""; +//} #pragma mark - AnylineNativeBarcodeDelegate methods /* An additional delegate which will add all found, and unique, barcodes to a Dictionary simultaneously. */ -- (void)anylineCaptureDeviceManager:(ALCaptureDeviceManager *)captureDeviceManager didFindBarcodeResult:(NSString *)scanResult type:(NSString *)barcodeType { - dispatch_async(dispatch_get_main_queue(), ^{ - if ([scanResult length] > 0 && ![self.barcodeResult isEqualToString:scanResult]) { - self.barcodeResult = scanResult; - } - }); -} +//- (void)anylineCaptureDeviceManager:(ALCaptureDeviceManager *)captureDeviceManager didFindBarcodeResult:(NSString *)scanResult type:(NSString *)barcodeType { +// dispatch_async(dispatch_get_main_queue(), ^{ +// if ([scanResult length] > 0 && ![self.barcodeResult isEqualToString:scanResult]) { +// self.barcodeResult = scanResult; +// } +// }); +//} @end diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALParallelMeterScanViewController.h b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALParallelMeterScanViewController.h deleted file mode 100644 index 8f2909fd9..000000000 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALParallelMeterScanViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// ALParallelMeterScanViewController.h -// AnylineExamples -// -// Created by Angela Brett on 21.11.19. -// - -#import "ALBaseScanViewController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface ALParallelMeterScanViewController : ALBaseScanViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALParallelMeterScanViewController.m b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALParallelMeterScanViewController.m index 4573fdc0f..e69de29bb 100644 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALParallelMeterScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ALParallelMeterScanViewController.m @@ -1,357 +0,0 @@ -// -// ALParallelMeterScanViewController.m -// AnylineExamples -// -// Created by Angela Brett on 21.11.19. -// - -#import "ALParallelMeterScanViewController.h" - -#import "AnylineExamples-Swift.h" -#import "NSUserDefaults+ALExamplesAdditions.h" -#import "UISwitch+ALExamplesAdditions.h" - -// In a parallel setup with meter, time allowed to check barcode before results are turned in -const NSTimeInterval kBarcodeInParallelTimeout = 1.0; -NSString * const kMeterScanViewPluginID = @"ENERGY"; -NSString * const kBarcodeScanViewPluginID = @"BARCODE"; -NSString * const kParallelScanViewPluginID = @"PARALLEL (Energy + Barcode)"; - -@interface ALParallelMeterScanViewController() - -@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; -@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin; -@property (nonatomic, strong) ALParallelScanViewPluginComposite *parallelScanViewPlugin; - -@property (nullable, nonatomic, strong) ALScanView *scanView; - -@property (nonatomic, strong) NSString *barcodeResultStr; -@property (nonatomic, strong) NSString *meterResultStr; -@property (nonatomic, strong) UIImage *meterImage; - -@property (nonatomic, strong) UIView *enableBarcodeSwitchView; -@property (nonatomic, strong) UISwitch *enableBarcodeSwitch; -@property (nonatomic, strong) UILabel *enableBarcodeLabel; - -@end - -@implementation ALParallelMeterScanViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - // ALMeterCollectionViewController can give it its title - if (!self.title.length) { - self.title = @"Analog/Digital Meter"; - } - - ALScanMode scanMode = ALAutoAnalogDigitalMeter; - if ([self.title isEqualToString:@"Digital (APAC)"]) { - scanMode = ALDigitalMeter2Experimental; - } - - NSError *error = nil; - ALMeterScanPlugin *meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:kMeterScanViewPluginID - delegate:self - error:&error]; - NSAssert(meterScanPlugin, @"Setup Error: %@", error.debugDescription); - - // Set ScanMode to ALAutoAnalogDigitalMeter - BOOL success = [meterScanPlugin setScanMode:scanMode error:&error]; - if (!success) { - __weak __block typeof(self) weakSelf = self; - [self showAlertWithTitle:@"Set ScanMode Error" message:error.debugDescription completion:^{ - [weakSelf.navigationController popViewControllerAnimated:YES]; - }]; - } - - self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:meterScanPlugin]; - - // since barcode cutout region (full screen) doesn't match meter, we will disable have both's cutout - // BG colors be clear so as to avoid having visible areas where the cutout mask don't intersect while - // parallel scanning mode is on. - ALScanViewPluginConfig *meterScanViewPluginConfig = [ALScanViewPluginConfig defaultMeterConfig]; - meterScanViewPluginConfig.cutoutConfig.backgroundColor = [UIColor clearColor]; - self.meterScanViewPlugin.scanViewPluginConfig = meterScanViewPluginConfig; - - ALBarcodeScanPlugin *barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] - initWithPluginID:kBarcodeScanViewPluginID - delegate:self // we don't needed this, but must - error:&error]; - - NSAssert(barcodeScanPlugin, @"Setup Error: %@", error.debugDescription); - [barcodeScanPlugin setBarcodeFormatOptions:@[kCodeTypeAll]]; - - ALScanViewPluginConfig *barcodeScanViewPluginConfig = [self.class barcodeScanViewPluginConfig]; - self.barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] initWithScanPlugin:barcodeScanPlugin - scanViewPluginConfig:barcodeScanViewPluginConfig]; - - // In a parallel scan setup, this means that the scan view will wait only a short period, - // (i.e., kBarcodeInParallelTimeout) for the barcode to be scanned, before giving up and - // returning the composite result: in this situation, with only the meter result. - [self.barcodeScanViewPlugin setIsOptional:YES]; - - self.parallelScanViewPlugin = [[ALParallelScanViewPluginComposite alloc] - initWithPluginID:kParallelScanViewPluginID]; - [self.parallelScanViewPlugin addPlugin:self.meterScanViewPlugin]; - [self.parallelScanViewPlugin addPlugin:self.barcodeScanViewPlugin]; - [self.parallelScanViewPlugin addDelegate:self]; - [self.parallelScanViewPlugin setOptionalTimeoutDelay:@(kBarcodeInParallelTimeout)]; - - CGRect frame = [self scanViewFrame]; - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:[self selectedPlugin]]; - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - - [self.scanView enableZoomPinchGesture:YES]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - - NSArray *scanViewConstraints = @[ - [self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor] - ]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - - // Barcode Switch - [self.scanView addSubview:[self createBarcodeSwitchView]]; - [self.scanView bringSubviewToFront:self.enableBarcodeSwitchView]; - - self.controllerType = ALScanHistoryElectricMeter; - - [self.scanView startCamera]; -} - -+ (ALScanViewPluginConfig *)barcodeScanViewPluginConfig { - ALScanViewPluginConfig *barcodeScanViewPluginConfig = [ALScanViewPluginConfig defaultBarcodeConfig]; - barcodeScanViewPluginConfig.cutoutConfig = [ALCutoutConfig defaultCutoutConfig]; - barcodeScanViewPluginConfig.cutoutConfig.path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 1024, 1920)]; - barcodeScanViewPluginConfig.cutoutConfig.strokeWidth = 0; // hide this - barcodeScanViewPluginConfig.cutoutConfig.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0]; - barcodeScanViewPluginConfig.cutoutConfig.cornerRadius = 0; - barcodeScanViewPluginConfig.cutoutConfig.alignment = ALCutoutAlignmentMiddle; - barcodeScanViewPluginConfig.scanFeedbackConfig.strokeWidth = 0; - barcodeScanViewPluginConfig.scanFeedbackConfig.beepOnResult = NO; - barcodeScanViewPluginConfig.scanFeedbackConfig.vibrateOnResult = NO; - barcodeScanViewPluginConfig.scanFeedbackConfig.fillColor = [UIColor clearColor]; - barcodeScanViewPluginConfig.scanFeedbackConfig.strokeColor = [UIColor clearColor]; - return barcodeScanViewPluginConfig; -} - -// MARK: - UIViewController Lifecycle Methods - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self setAsCurrentPlugin:[self selectedPlugin]]; -} - -- (void)viewDidLayoutSubviews { - [super viewDidLayoutSubviews]; - [self updateLayoutBarcodeSwitchView]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - [self.parallelScanViewPlugin stopAndReturnError:nil]; - [self.meterScanViewPlugin stopAndReturnError:nil]; - [self.barcodeScanViewPlugin stopAndReturnError:nil]; -} - -// MARK: - Plugin Control - -- (ALAbstractScanViewPlugin *)selectedPlugin { - if (self.enableBarcodeSwitch.on) { - return self.parallelScanViewPlugin; - } else { - return self.meterScanViewPlugin; - } -} - -- (void)setAsCurrentPlugin:(ALAbstractScanViewPlugin *)plugin { - [self stopPlugin:plugin]; - self.scanView.scanViewPlugin = plugin; - [self startPlugin:plugin]; - [self.scanView bringSubviewToFront:self.enableBarcodeSwitchView]; -} - -- (void)stopPlugin:(ALAbstractScanViewPlugin *)plugin { - NSError *error = nil; - [plugin stopAndReturnError:&error]; - if (error) { - [self showAlertWithTitle:@"Error stopping scanning" - message:error.debugDescription - completion:nil]; - } -} - -#pragma mark - View Layout - -- (UIView *)createBarcodeSwitchView { - // Add UISwitch for toggling barcode scanning - self.enableBarcodeSwitchView = [[UIView alloc] init]; - self.enableBarcodeSwitchView.frame = CGRectMake(100, 100, 250, 50); - - UIFont *font = [UIFont systemFontOfSize:14 weight:UIFontWeightThin]; - self.enableBarcodeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 30)]; - self.enableBarcodeLabel.font = font; - self.enableBarcodeLabel.text = @"Barcode Detection"; - self.enableBarcodeLabel.numberOfLines = 0; - self.enableBarcodeLabel.textColor = [UIColor whiteColor]; - [self.enableBarcodeLabel sizeToFit]; - - self.enableBarcodeSwitch = [[UISwitch alloc] init]; - [self.enableBarcodeSwitch setOn:false]; - [self.enableBarcodeSwitch setOnTintColor:[UIColor colorWithRed:0.0/255.0 - green:153.0/255.0 - blue:255.0/255.0 - alpha:1.0]]; - [self.enableBarcodeSwitch useHighContrast]; - [self.enableBarcodeSwitch addTarget:self action:@selector(toggleBarcodeScanning:) - forControlEvents:UIControlEventValueChanged]; - - [self.enableBarcodeSwitchView addSubview:self.enableBarcodeLabel]; - [self.enableBarcodeSwitchView addSubview:self.enableBarcodeSwitch]; - - return self.enableBarcodeSwitchView; -} - -- (void)updateLayoutBarcodeSwitchView { - CGFloat padding = 7.0f; - - self.enableBarcodeLabel.center = CGPointMake(self.enableBarcodeLabel.frame.size.width / 2, - self.enableBarcodeSwitchView.frame.size.height / 2); - - self.enableBarcodeSwitch.center = CGPointMake(self.enableBarcodeLabel.frame.size.width + - self.enableBarcodeSwitch.frame.size.width / 2 + padding, - self.enableBarcodeSwitchView.frame.size.height / 2); - - CGFloat width = (self.enableBarcodeSwitch.frame.size.width + - padding + - self.enableBarcodeLabel.frame.size.width); - - self.enableBarcodeSwitchView.frame = CGRectMake(self.scanView.frame.size.width - width - 15, - self.scanView.frame.size.height - self.enableBarcodeSwitchView.frame.size.height - 55, - width, 50); -} - -// MARK: - Results Handling - -- (void)displayResults { - - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Meter Reading" value:self.meterResultStr]]; - if (self.barcodeResultStr) { - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode" value:self.barcodeResultStr - shouldSpellOutValue:YES]]; - } - - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - // stop scanning, since we don't need to scan the serial and the barcode, only one of them - [self anylineDidFindResult:jsonString - barcodeResult:self.barcodeResultStr - image:self.meterImage - scanPlugin:self.meterScanViewPlugin.meterScanPlugin - viewPlugin:self.parallelScanViewPlugin completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = weakSelf.meterImage; - - [weakSelf.navigationController pushViewController:vc animated:YES]; - NSError *error; - [self.parallelScanViewPlugin stopAndReturnError:&error]; - [self.meterScanViewPlugin stopAndReturnError:&error]; - [self.barcodeScanViewPlugin stopAndReturnError:&error]; - - // reset results (needs to be run inside the closure in case there is a delay - // from showing an award view) - self.barcodeResultStr = nil; - self.meterResultStr = @""; - self.meterImage = nil; - }]; -} - -// MARK: - ScanViewPluginDelegate Methods - -// Meter can go alone or with barcode in a parallel (hence shall need its own delegate), -// but barcode when returned by a delegate is always as child of parallel -- (void)anylineCompositeScanPlugin:(ALAbstractScanViewPluginComposite *)compositeScanPlugin - didFindResult:(ALCompositeResult *)scanResult { - NSDictionary *composite = (NSDictionary *)scanResult.result; - ALBarcode *barcodeResult = [[composite[@"BARCODE"] result] firstObject]; - ALMeterResult *meterResult = composite[@"ENERGY"]; - - if (!meterResult) { // it's fine for barcode to be nil because it's optional - return; - } - - [self stopPlugin:compositeScanPlugin]; - - self.barcodeResultStr = [barcodeResult value]; - if (self.barcodeResultStr == nil) { - // if we can't get barcode from this delegate we are going to make that known - // explicitly on the results - self.barcodeResultStr = @""; - } - - self.meterResultStr = meterResult.result; - self.meterImage = meterResult.image; - - [self displayResults]; -} - -- (void)anylineMeterScanPlugin:(ALMeterScanPlugin * _Nonnull)anylineMeterScanPlugin - didFindResult:(ALMeterResult * _Nonnull)scanResult { - - if (self.enableBarcodeSwitch.on) { - return; - } - - self.meterResultStr = scanResult.result; - self.meterImage = scanResult.image; - - [self displayResults]; -} - -- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin * _Nonnull)anylineBarcodeScanPlugin didFindResult:(ALBarcodeResult*_Nonnull)scanResult { - // do nothing here - barcode result handling should now be exclusively handled by - // `anylineCompositeScanPlugin:didFindResult:`. -} - -// MARK: - IBActions - -- (IBAction)toggleBarcodeScanning:(id)sender { - UISwitch *switcher = sender; - switcher.enabled = NO; - switcher.alpha = 0.5; - - if (self.enableBarcodeSwitch.on) { - // going to use parallel scanning (meter and barcode) - [self stopPlugin:self.meterScanViewPlugin]; - [self stopPlugin:self.barcodeScanViewPlugin]; - [self setAsCurrentPlugin:self.parallelScanViewPlugin]; - } else { - // revert to simple old meter scanning - self.barcodeResultStr = nil; - [self stopPlugin:self.parallelScanViewPlugin]; - if ([self.meterResultStr length]) { - // if we already have a meter result, and we no longer need a barcode, display - // the results immediately rather than trying to scan the meter again. - [self displayResults]; - } else { - [self setAsCurrentPlugin:self.meterScanViewPlugin]; - } - } - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - switcher.enabled = YES; - switcher.alpha = 1; - }); -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ElectricMeterBlackWhiteScanViewController.swift b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ElectricMeterBlackWhiteScanViewController.swift index a14eaddab..1e93e296c 100644 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ElectricMeterBlackWhiteScanViewController.swift +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/ElectricMeterBlackWhiteScanViewController.swift @@ -9,12 +9,11 @@ import Foundation import UIKit -@objc class ElectricMeterBlackWhiteScanViewController: ALBaseScanViewController, ALMeterScanPluginDelegate { +@objc class ElectricMeterBlackWhiteScanViewController: ALBaseScanViewController { //, ALMeterScanPluginDelegate // The Anyline plugins used to scan - var meterScanViewPlugin : ALMeterScanViewPlugin!; - var meterScanPlugin : ALMeterScanPlugin!; - var scanView : ALScanView!; +// var meterScanViewPlugin : ALMeterScanViewPlugin!; +// var meterScanPlugin : ALMeterScanPlugin!; override func viewDidLoad() { super.viewDidLoad(); @@ -22,22 +21,22 @@ import UIKit self.title = "Electric Meter"; do { - self.meterScanPlugin = try ALMeterScanPlugin.init(pluginID:"ENERGY", delegate: self); - try self.meterScanPlugin.setScanMode(ALScanMode.analogMeter); - - self.meterScanViewPlugin = ALMeterScanViewPlugin.init(scanPlugin: self.meterScanPlugin); - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - self.scanView = ALScanView.init(frame: self.view.bounds, scanViewPlugin: self.meterScanViewPlugin); +// self.meterScanPlugin = try ALMeterScanPlugin.init(pluginID:"ENERGY", delegate: self); +// try self.meterScanPlugin.setScanMode(ALScanMode.analogMeter); +// +// self.meterScanViewPlugin = ALMeterScanViewPlugin.init(scanPlugin: self.meterScanPlugin); +// // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen +// self.scanView = ALScanView.init(frame: self.view.bounds, scanViewPlugin: self.meterScanViewPlugin); } catch _ as NSError { //Handle error here } //Add Anyline to view hierachy - self.view.addSubview(self.scanView); +// self.view.addSubview(self.scanView); //Start Camera with Anyline - self.scanView.startCamera(); +// self.scanView.startCamera(); - self.view.sendSubviewToBack(self.scanView); +// self.view.sendSubviewToBack(self.scanView); self.controllerType = ALScanHistoryElectricMeter; } @@ -47,7 +46,7 @@ import UIKit //Stop Anyline do { - try self.meterScanViewPlugin.stop(); +// try self.meterScanViewPlugin.stop(); } catch {} } @@ -56,19 +55,19 @@ import UIKit //Start Anyline do { - try self.meterScanViewPlugin.start(); +// try self.meterScanViewPlugin.start(); } catch {} } - - func anylineMeterScanPlugin(_ anylineMeterScanPlugin: ALMeterScanPlugin, didFind scanResult: ALMeterResult) { - self.anylineDidFindResult(scanResult.result as String, barcodeResult:"", image: scanResult.image, scanPlugin: anylineMeterScanPlugin, viewPlugin: self.meterScanViewPlugin, completion: {() in - let vc = ALMeterScanResultViewController.init(); - - vc.scanMode = scanResult.scanMode; - vc.meterImage = scanResult.image; - vc.result = scanResult.result as String; - - self.navigationController?.pushViewController(vc, animated: true); - }); - } +// +// func anylineMeterScanPlugin(_ anylineMeterScanPlugin: ALMeterScanPlugin, didFind scanResult: ALMeterResult) { +// self.anylineDidFindResult(scanResult.result as String, barcodeResult:"", image: scanResult.image, scanPlugin: anylineMeterScanPlugin, viewPlugin: self.meterScanViewPlugin, completion: {() in +// let vc = ALMeterScanResultViewController.init(); +// +// vc.scanMode = scanResult.scanMode; +// vc.meterImage = scanResult.image; +// vc.result = scanResult.result as String; +// +// self.navigationController?.pushViewController(vc, animated: true); +// }); +// } } diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/meter_barcode_view_config.json b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/meter_barcode_view_config.json deleted file mode 100644 index 7488e1bd3..000000000 --- a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/meter_barcode_view_config.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "viewPlugin": { - "cutoutConfig": { - "style": "rect", - "maxWidthPercent": "100%", - "maxHeightPercent": "100%", - "alignment": "center", - "strokeWidth": 0, - "cornerRadius": 3, - "strokeColor": "FFFFFF", - "outerColor": "000000", - "outerAlpha": 0.3 - }, - "scanFeedback": { - "style": "rect", - "strokeWidth": 4, - "strokeColor": "FF9900", - "fillColor": "11FF9900", - "animationDuration": 150, - "blinkOnResult": true, - "beepOnResult": true, - "vibrateOnResult": true - }, - "cancelOnResult": true - } -} diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/meter_config.json b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/meter_config.json new file mode 100644 index 000000000..898a9d791 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/meter_config.json @@ -0,0 +1,44 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p" + }, + "flashConfig": { + "mode": "manual_on", + "alignment": "top_left" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.auto-meter", + "meterConfig": { + "scanMode": "auto_analog_digital_meter" + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "style": "rect", + "maxWidthPercent": "100%", + "width": 768, + "alignment": "top_half", + "ratioFromSize": { "width": 9, "height": 4 }, + "offset": { "x": 0, "y": 80 }, + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "contour_rect", + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "220099FF", + "cornerRadius": 2, + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true, + "redrawTimeout": 200, + "animationDuration": 75 + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/parallel_meter_barcode_config.json b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/parallel_meter_barcode_config.json new file mode 100644 index 000000000..c1d137858 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/MeterScan/ViewController/parallel_meter_barcode_config.json @@ -0,0 +1,87 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p" + }, + "flashConfig": { + "mode": "manual_off", + "alignment": "bottom_left" + }, + "viewPluginCompositeConfig": { + "id": "meter_barcode_parallel_scan", + "processingMode": "parallel", + "viewPlugins": [ + { + "viewPluginConfig": { + "pluginConfig": { + "id": "meter", + "meterConfig": { + "scanMode": "auto_analog_digital_meter" + }, + "cancelOnResult": true, + "startScanDelay": 0 + }, + "cutoutConfig": { + "style": "rect", + "maxWidthPercent": "100%", + "width": 768, + "alignment": "top_half", + "ratioFromSize": { "width": 9, "height": 4 }, + "offset": { "x": 0, "y": 80 }, + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "contour_rect", + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "220099FF", + "cornerRadius": 2, + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true, + "redrawTimeout": 200, + "animationDuration": 75 + } + } + }, + { + "viewPluginConfig": { + "pluginConfig": { + "id": "barcode", + "barcodeConfig": { + "barcodeFormats": [ "ALL" ] + }, + "cancelOnResult": true, + "startScanDelay": 100 + }, + "cutoutConfig": { + "style": "none", + "maxWidthPercent": "100%", + "alignment": "center", + "ratioFromSize": { "width": 1, "height": 1 }, + "offset": { "x": 0, "y": 0 }, + "outerColor": "000000", + "outerAlpha": 0, + "strokeWidth": 0, + "strokeColor": "0099FF", + "cornerRadius": 0, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig": { + "style": "contour_rect", + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "220099FF", + "beepOnResult": false, + "vibrateOnResult": false, + "blinkAnimationOnResult": false + } + } + } + ] + } +} diff --git a/AnylineExamples/Anyline Examples Source/MultiformatBarcode/ViewController/ALPDF417ScanViewController.m b/AnylineExamples/Anyline Examples Source/MultiformatBarcode/ViewController/ALPDF417ScanViewController.m index 46bdc6f74..187743268 100644 --- a/AnylineExamples/Anyline Examples Source/MultiformatBarcode/ViewController/ALPDF417ScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/MultiformatBarcode/ViewController/ALPDF417ScanViewController.m @@ -1,128 +1,100 @@ -// -// ALPDF417ScanViewController.m -// AnylineExamples -// -// Created by Matthias Gasser on 22/04/15. -// Copyright (c) 2015 9yards GmbH. All rights reserved. -// - #import "ALPDF417ScanViewController.h" #import #import "NSUserDefaults+ALExamplesAdditions.h" #import "AnylineExamples-Swift.h" #import "ALBarcodeResultUtil.h" -// The controller has to conform to to be able to receive results -@interface ALPDF417ScanViewController() -// The Anyline plugin used to scan barcodes -@property (nonatomic, strong) ALBarcodeScanPlugin *barcodeScanPlugin; -@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +NSString * const kBarcodePDF417_configJSONFilename = @"barcode_pdf417_in_id"; + +@interface ALPDF417ScanViewController() + +@property (nonatomic, strong) ALScanViewPlugin *scanViewPlugin; @end @implementation ALPDF417ScanViewController -/* - We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed. - */ - (void)viewDidLoad { [super viewDidLoad]; self.title = @"PDF417"; - CGRect frame = [self scanViewFrame]; - - //Add Barcode Scan Plugin (Scan Process) - NSError *error = nil; - self.barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] initWithPluginID:@"BARCODE" delegate:self error:&error]; - self.barcodeScanPlugin.parsePDF417 = YES; - NSAssert(self.barcodeScanPlugin, @"Setup Error: %@", error.debugDescription); - - //Set Barcode Format to PDF417 only - [self.barcodeScanPlugin setBarcodeFormatOptions:@[kCodeTypePDF417, kCodeTypeMICRO_PDF]]; - - //Change cutout appearance to fit the PDF417 use case better - ALScanViewPluginConfig *uiConfig = [ALScanViewPluginConfig defaultBarcodeConfig]; - uiConfig.cutoutConfig.alignment = ALCutoutAlignmentTopHalf; - uiConfig.cutoutConfig.maxPercentWidth = 0.9; - uiConfig.cutoutConfig.widthPercent = 0.9; - uiConfig.cutoutConfig.strokeWidth = 2; - uiConfig.cutoutConfig.path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 250, 90)]; - - //Add Barcode Scan View Plugin (Scan UI) - self.barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] initWithScanPlugin:self.barcodeScanPlugin scanViewPluginConfig:uiConfig]; - NSAssert(self.barcodeScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.barcodeScanViewPlugin addScanViewPluginDelegate:self]; + NSDictionary *configJSONDictionary = [[self configJSONStrWithFilename:kBarcodePDF417_configJSONFilename] asJSONObject]; + self.scanViewPlugin = [[ALScanViewPlugin alloc] initWithJSONDictionary:configJSONDictionary error:nil]; - self.controllerType = ALScanHistoryBarcodePDF417; + self.scanViewPlugin.scanPlugin.delegate = self; + + ALScanViewConfig *scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:configJSONDictionary error:nil]; + + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.scanViewPlugin + scanViewConfig:scanViewConfig + error:nil]; - //Add ScanView (Camera and Flashbutton) - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.barcodeScanViewPlugin]; - [self.scanView.captureDeviceManager setValue:@(1) forKey:@"disableNative"]; - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; + [self installScanView:self.scanView]; + [self.scanView startCamera]; - self.barcodeScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO; - - // After setup is complete we add the scanView to the view of this view controller - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; + self.controllerType = ALScanHistoryBarcodePDF417; } -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { +- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - [self startPlugin:self.barcodeScanViewPlugin]; + [self.scanViewPlugin startWithError:nil]; } -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.barcodeScanViewPlugin stopAndReturnError:nil]; -} -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; ++ (ALScanViewPluginConfig *)defaultScanViewPluginConfig { + NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:kBarcodePDF417_configJSONFilename + ofType:@"json"]; + NSString *configStr = [NSString stringWithContentsOfFile:jsonFilePath + encoding:NSUTF8StringEncoding + error:NULL]; + return [[ALScanViewPluginConfig alloc] initWithJSONDictionary:[configStr asJSONObject] error:nil]; } -#pragma mark -- AnylineBarcodeModuleDelegate +// MARK: - ALScanPluginDelegate -/* - The main delegate method Anyline uses to report its scanned codes - */ -- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin *)anylineBarcodeScanPlugin didFindResult:(ALBarcodeResult *)scanResult { - - NSArray *resultData = [ALBarcodeResultUtil barcodeResultDataFromBarcodeResultArray:scanResult.result]; +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + + if (!scanResult.croppedImage) { // reject any result that doesn't come with an image. + // ACO this is a known bug in the core (at the moment) + // In doing this, the plugin config (on JSON) needs `cancelOnResult` to be false. + return; + } + + NSArray *barcodes = scanResult.pluginResult.barcodeResult.barcodes; + if (barcodes.count < 1) { + return; + } + + [self showResultControllerWithResults:scanResult]; +} + +- (void)showResultControllerWithResults:(ALScanResult *)scanResult { - NSString *jsonString = [self jsonStringFromResultData:resultData]; + [self.scanViewPlugin stop]; - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString - barcodeResult:@"" - image:scanResult.image - scanPlugin:self.barcodeScanPlugin - viewPlugin:self.barcodeScanViewPlugin - completion:^{ + // copy the barcodes array and image before clearing + NSArray *barcodesFound = [NSArray arrayWithArray:scanResult.pluginResult + .barcodeResult.barcodes]; + UIImage *image = [scanResult.croppedImage copy]; - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = scanResult.image; + NSAssert(barcodesFound.count > 0, @"no barcodes found"); + + NSArray *resultData = scanResult.pluginResult.barcodeResult.resultEntryList; + NSString *resultDataJSONStr = [ALResultEntry JSONStringFromList:resultData]; + __weak __block typeof(self) weakSelf = self; + [self anylineDidFindResult:resultDataJSONStr + barcodeResult:barcodesFound[0].value + image:image + scanPlugin:self.scanViewPlugin.scanPlugin + viewPlugin:self.scanViewPlugin completion:^{ + ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; + vc.imagePrimary = image; [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; + }]; } @end + diff --git a/AnylineExamples/Anyline Examples Source/NFC/ViewController/ALNFCScanViewController.h b/AnylineExamples/Anyline Examples Source/NFC/ViewController/ALNFCScanViewController.h index 382461de8..c42447c4f 100644 --- a/AnylineExamples/Anyline Examples Source/NFC/ViewController/ALNFCScanViewController.h +++ b/AnylineExamples/Anyline Examples Source/NFC/ViewController/ALNFCScanViewController.h @@ -1,10 +1,3 @@ -// -// ALNFCScanViewController.h -// AnylineExamples -// -// Created by Angela Brett on 08.10.19. -// - #import "ALBaseScanViewController.h" NS_ASSUME_NONNULL_BEGIN diff --git a/AnylineExamples/Anyline Examples Source/NFC/ViewController/ALNFCScanViewController.m b/AnylineExamples/Anyline Examples Source/NFC/ViewController/ALNFCScanViewController.m index 48bfccb0b..23b83a549 100644 --- a/AnylineExamples/Anyline Examples Source/NFC/ViewController/ALNFCScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/NFC/ViewController/ALNFCScanViewController.m @@ -1,27 +1,21 @@ -// -// ALNFCScanViewController.m -// AnylineExamples -// -// Created by Angela Brett on 08.10.19. -// - #import "ALNFCScanViewController.h" #import "AnylineExamples-Swift.h" -#import "ALUniversalIDFieldnameUtil.h" +#import API_AVAILABLE(ios(13.0)) -@interface ALNFCScanViewController () +@interface ALNFCScanViewController () -@property (nonatomic, strong) ALIDScanViewPlugin *mrzScanViewPlugin; -@property (nonatomic, strong) ALIDScanPlugin *mrzScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; @property (nonatomic, strong) ALNFCDetector *nfcDetector; -@property (nullable, nonatomic, strong) UIView *hintView; +@property (nonatomic, strong) ALScanViewPlugin *scanViewPlugin; +@property (nonatomic, strong) ALScanViewConfig *scanViewConfig; + +@property (nonatomic, strong, nullable) UIView *hintView; -//keep the last values we read from the MRZ so we can retry reading NFC if NFC failed for reasons other than getting these details wrong -@property NSString *passportNumberForNFC; -@property NSDate *dateOfBirth; -@property NSDate *dateOfExpiry; +// keep the last values we read from the MRZ so we can retry reading NFC if +// NFC failed for reasons other than getting these details wrong +@property (nonatomic, copy) NSString *passportNumberForNFC; +@property (nonatomic, strong) NSDate *dateOfBirth; +@property (nonatomic, strong) NSDate *dateOfExpiry; @end @@ -30,230 +24,240 @@ @implementation ALNFCScanViewController - (void)viewDidLoad { [super viewDidLoad]; self.title = @"NFC"; - CGFloat hintMargin = 7; - - UILabel * hintViewLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - UIView * hintView = [[UILabel alloc] initWithFrame:CGRectZero]; - hintViewLabel.text = @"Scan MRZ"; - [hintViewLabel sizeToFit]; - [hintView addSubview:hintViewLabel]; - hintView.frame = UIEdgeInsetsInsetRect(hintViewLabel.frame, UIEdgeInsetsMake(-hintMargin, -hintMargin, -hintMargin, -hintMargin)); - hintView.center = CGPointMake(self.view.center.x, 0); - hintViewLabel.translatesAutoresizingMaskIntoConstraints = NO; - [hintViewLabel.centerYAnchor constraintEqualToAnchor:hintView.centerYAnchor constant:0].active = YES; - [hintViewLabel.centerXAnchor constraintEqualToAnchor:hintView.centerXAnchor constant:0].active = YES; - hintView.layer.cornerRadius = 8; - hintView.layer.masksToBounds = true; - hintView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; - hintViewLabel.textColor = [UIColor whiteColor]; - self.hintView = hintView; - [self.view addSubview:hintView]; - - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - ALMRZConfig *mrzConfig = [[ALMRZConfig alloc] init]; - //we want to be quite confident of these fields to ensure we can read the NFC with them - ALMRZFieldConfidences *fieldConfidences = [[ALMRZFieldConfidences alloc] init]; - fieldConfidences.documentNumber = 90; - fieldConfidences.dateOfBirth = 90; - fieldConfidences.dateOfExpiry = 90; - mrzConfig.idFieldConfidences = fieldConfidences; - - //Create fieldScanOptions to configure individual scannable fields - ALMRZFieldScanOptions *scanOptions = [[ALMRZFieldScanOptions alloc] init]; - scanOptions.vizAddress = ALDefault; - scanOptions.vizDateOfIssue = ALDefault; - scanOptions.vizSurname = ALDefault; - scanOptions.vizGivenNames = ALDefault; - scanOptions.vizDateOfBirth = ALDefault; - scanOptions.vizDateOfExpiry = ALDefault; - - //Set scanOptions for MRZConfig - mrzConfig.idFieldScanOptions = scanOptions; - - NSError *error = nil; + self.controllerType = ALScanHistoryNFC; + + BOOL NFCEnabled = [self checkNFCCapability]; + if (!NFCEnabled) { + return; + } - //Init the anyline ID ScanPlugin with an ID, Licensekey, the delegate, - // the MRZConfig (which will configure the scan Plugin for MRZ scanning), and an error - self.mrzScanPlugin = [[ALIDScanPlugin alloc] initWithPluginID:@"ModuleID" delegate:self idConfig:mrzConfig error:&error]; if (@available(iOS 13.0, *)) { - self.nfcDetector=[[ALNFCDetector alloc] initWithDelegate:self]; - } else { - // Fallback on earlier versions + self.nfcDetector = [[ALNFCDetector alloc] initWithDelegate:self]; } - NSAssert(self.mrzScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.mrzScanPlugin addInfoDelegate:self]; - - - self.mrzScanViewPlugin = [[ALIDScanViewPlugin alloc] initWithScanPlugin:self.mrzScanPlugin]; - NSAssert(self.mrzScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.mrzScanViewPlugin addScanViewPluginDelegate:self]; - - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.mrzScanViewPlugin]; - - self.controllerType = ALScanHistoryNFC; + + self.hintView = [self.class makeHintView]; + [self.view addSubview:self.hintView]; + [self.hintView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES; + [self.hintView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES; + + NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:@"mrz_nfc_config" + ofType:@"json"]; + NSString *configStr = [NSString stringWithContentsOfFile:jsonFilePath + encoding:NSUTF8StringEncoding + error:NULL]; + id JSONConfigObj = [configStr asJSONObject]; + + // instead of directly creating a scan view plugin, we can let a factory determine + // whether the result is a plain ALScanViewPlugin or an ALViewPluginComposite. + self.scanViewPlugin = (ALScanViewPlugin *)[ALScanViewPluginFactory withJSONDictionary:JSONConfigObj]; + + self.scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:JSONConfigObj error:nil]; + + // Tweak the MRZ tolerances here if necessary. + // [self configureScanViewConfig]; + + self.scanViewPlugin.scanPlugin.delegate = self; + + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.scanViewPlugin + scanViewConfig:self.scanViewConfig + error:nil]; - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - //Start Camera: + [self installScanView:self.scanView]; + [self.scanView startCamera]; - [self startListeningForMotion]; -} -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; + // self.mrzScanViewPlugin = [[ALIDScanViewPlugin alloc] initWithScanPlugin:self.mrzScanPlugin]; + // NSAssert(self.mrzScanViewPlugin, @"Setup Error: %@", error.debugDescription); + // [self.mrzScanViewPlugin addScanViewPluginDelegate:self]; + // + // + // self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.mrzScanViewPlugin]; + - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startMRZScanning]; -} + [self.view addSubview:self.scanView]; -- (void)updateHintPosition:(CGFloat)newPosition { - self.hintView.center = CGPointMake(self.hintView.center.x, newPosition); + // TODO: we also used the erstwhile ScanInfoDelegate in the old version + // to track the cutout position. + // [self startListeningForMotion]; } -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; - [self updateHintPosition:cutoutRect.origin.y + - self.scanView.frame.origin.y - - 50]; +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self.scanViewPlugin startWithError:nil]; + self.startTime = CACurrentMediaTime(); + self.hintView.hidden = NO; } -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self stopMRZScanning]; +- (BOOL)checkNFCCapability { + // NOTE: Apart from the iOS version + device requirement, also make sure to + // check that the app was provisioned with the Near Field Communications + // Tag Reading capability. + if (@available(iOS 13.0, *)) { + if ([ALNFCDetector readingAvailable]) { + return YES; + } + } + + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"NFC Not Supported" + message:@"NFC Tag Reading is not enabled for this device." + preferredStyle:UIAlertControllerStyleAlert]; + __weak __block typeof(self) weakSelf = self; + [alert addAction:[UIAlertAction actionWithTitle:@"Okay" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [weakSelf.navigationController popToRootViewControllerAnimated:YES]; + }]]; + [self.navigationController presentViewController:alert animated:YES completion:nil]; + return NO; } +// MARK: - ALScanPluginDelegate -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startMRZScanning { - [self startPlugin:self.mrzScanViewPlugin]; - self.startTime = CACurrentMediaTime(); - self.hintView.hidden = NO; -} +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + // get passport number, date of birth, date of expiry -/* - Cancel scanning to allow the module to clean up - */ -- (void)stopMRZScanning { - [self.mrzScanViewPlugin stopAndReturnError:nil]; - self.hintView.hidden = YES; -} + ALMrzResult *mrzResult = scanResult.pluginResult.mrzResult; -- (void)readNFCChip { - /* - This is where we start reading the NFC chip of the passport. We use data from the MRZ to authenticate with the chip. - */ - [self.nfcDetector startNfcDetectionWithPassportNumber:self.passportNumberForNFC dateOfBirth:self.dateOfBirth expirationDate:self.dateOfExpiry]; -} + NSDate *dateOfBirth = [self.class formattedStringToDate:mrzResult.dateOfBirthObject]; + NSDate *dateOfExpiry = [self.class formattedStringToDate:mrzResult.dateOfExpiryObject]; -#pragma mark -- ALIDPluginDelegate - -/* - This is the main delegate method Anyline uses to report its results from an ID plugin such as MRZ - */ -- (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin didFindResult:(ALIDResult *)scanResult { - ALMRZIdentification *identification = (ALMRZIdentification*)scanResult.result; - NSString *passportNumber = [[identification documentNumber] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; - NSDate *dateOfBirth = [identification dateOfBirthObject]; - NSDate *dateOfExpiry = [identification dateOfExpiryObject]; - //The passport number passed to the NFC chip must have a trailing < if there is one in the MRZ string. - NSString *mrzString = [identification mrzString]; - NSMutableString *passportNumberForNFC = [passportNumber mutableCopy]; - NSRange passportNumberRange = [mrzString rangeOfString:passportNumber]; + NSMutableString *passportNumberForNFC = [[mrzResult.documentNumber stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] mutableCopy]; + NSRange passportNumberRange = [mrzResult.mrzString rangeOfString:passportNumberForNFC]; if (passportNumberRange.location != NSNotFound) { - if ([mrzString characterAtIndex:NSMaxRange(passportNumberRange)] == '<') { + if ([mrzResult.mrzString characterAtIndex:NSMaxRange(passportNumberRange)] == '<') { [passportNumberForNFC appendString:@"<"]; } } - [self stopMRZScanning]; - self.passportNumberForNFC = passportNumberForNFC; + + if (passportNumberForNFC.length > 0) { + [self.scanViewPlugin stop]; + self.hintView.hidden = YES; + + __weak __block typeof(self) weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf.nfcDetector startNfcDetectionWithPassportNumber:passportNumberForNFC + dateOfBirth:dateOfBirth + expirationDate:dateOfExpiry]; + }); + } + + self.dateOfBirth = dateOfBirth; self.dateOfExpiry = dateOfExpiry; - dispatch_async(dispatch_get_main_queue(), ^{ - [self readNFCChip]; - }); + self.passportNumberForNFC = passportNumberForNFC; } -#pragma mark -- ALNFCDetectorDelegate +// MARK: - ALNFCDetectorDelegate -/* This method is called after all the data has been read from the NFC chip. - To display data as it is read instead of waiting until everything has been read, we could also implement nfcSucceededWithDataGroup1: or nfcSucceededWithDataGroup2: */ -- (void)nfcSucceededWithResult:(ALNFCResult * _Nonnull)nfcResult API_AVAILABLE(ios(13.0)){ - dispatch_async(dispatch_get_main_queue(), ^{ - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"First Name" value:nfcResult.dataGroup1.firstName]]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Last Name" value:nfcResult.dataGroup1.lastName]]; - [resultData addObject:[self resultEntryWithDate:nfcResult.dataGroup1.dateOfBirth dateString:nil title:@"Date of Birth"]]; - [resultData addObject:[self resultEntryWithDate:nfcResult.dataGroup1.dateOfExpiry dateString:nil title:@"Date of Expiry"]]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Document Number" value:nfcResult.dataGroup1.documentNumber shouldSpellOutValue:YES]]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Issuing State Code" value:nfcResult.dataGroup1.issuingStateCode]]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Gender" value:nfcResult.dataGroup1.gender]]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Nationality" value:nfcResult.dataGroup1.nationality]]; - - resultData = [ALUniversalIDFieldnameUtil sortResultDataUsingFieldNamesWithSpace:resultData].mutableCopy; - NSString *jsonString = [self jsonStringFromResultData:resultData]; +/// This method is called after all the data has been read from the NFC chip. To display +/// data as it is read instead of waiting until everything has been read, we could also +/// implement nfcSucceededWithDataGroup1: or nfcSucceededWithDataGroup2: +/// - Parameter nfcResult: NFCResult object +- (void)nfcSucceededWithResult:(ALNFCResult * _Nonnull)nfcResult API_AVAILABLE(ios(13.0)) { - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:nfcResult.dataGroup2.faceImage scanPlugin:nil viewPlugin:nil completion:^{ - - NSMutableDictionary *resultDataDict = [[NSMutableDictionary alloc] init]; - [resultDataDict setObject:resultData forKey:@"NFC"]; + NSMutableArray *resultData = [[NSMutableArray alloc] init]; + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"First Name" value:nfcResult.dataGroup1.firstName]]; + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Last Name" value:nfcResult.dataGroup1.lastName]]; + [resultData addObject:[self resultEntryWithDate:nfcResult.dataGroup1.dateOfBirth dateString:nil title:@"Date of Birth"]]; + [resultData addObject:[self resultEntryWithDate:nfcResult.dataGroup1.dateOfExpiry dateString:nil title:@"Date of Expiry"]]; + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Document Number" value:nfcResult.dataGroup1.documentNumber shouldSpellOutValue:YES]]; + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Issuing State Code" value:nfcResult.dataGroup1.issuingStateCode]]; + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Gender" value:nfcResult.dataGroup1.gender]]; + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Nationality" value:nfcResult.dataGroup1.nationality]]; + + // resultData = [ALUniversalIDFieldnameUtil sortResultDataUsingFieldNamesWithSpace:resultData].mutableCopy; + + NSString *jsonString = [ALResultEntry JSONStringFromList:resultData]; + + __weak __block typeof(self) weakSelf = self; + [self anylineDidFindResult:jsonString + barcodeResult:nil + image:nfcResult.dataGroup2.faceImage + scanPlugin:self.scanViewPlugin.scanPlugin + viewPlugin:self.scanViewPlugin + completion:^{ + NSMutableDictionary *resultDataDict = [[NSMutableDictionary alloc] init]; + [resultDataDict setObject:resultData forKey:@"NFC"]; + + dispatch_async(dispatch_get_main_queue(), ^{ ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; vc.imagePrimary = nfcResult.dataGroup2.faceImage; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; - }); + }); + }]; } -- (void)nfcFailedWithError:(NSError * _Nonnull)error { - NSLog(@"NFC failed with error:%@, mrz:%@",error.localizedDescription,self.passportNumberForNFC); - //In most cases we don't really need to do anything special here since the NFC UI already shows that it failed. We shouldn't get ALNFCTagErrorNFCNotSupported either because we check +readingAvailable before even showing NFC, so this is just an example of how else that situation could be handled. +- (void)nfcFailedWithError:(NSError *)error API_AVAILABLE(ios(13.0)) { + + __weak __block typeof(self) weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ + + NSLog(@"NFC failed with error code: %ld, document number: %@", (long)error.code, weakSelf.passportNumberForNFC); + // In most cases we don't really need to do anything special here since the NFC UI already shows + // that it failed. We shouldn't get ALNFCTagErrorNFCNotSupported either because we check +readingAvailable + // before even showing NFC, so this is just an example of how else that situation could be handled. + if (error.code == ALNFCTagErrorNFCNotSupported) { - [self showAlertWithTitle:@"NFC Not Supported" - message:@"NFC passport reading is not supported on this device." - completion:nil]; + [weakSelf showAlertWithTitle:@"NFC Not Supported" + message:@"NFC passport reading is not supported on this device." + completion:nil]; } - if (error.code == ALNFCTagErrorResponseError || //error ALNFCTagErrorResponseError can mean the MRZ key was wrong - error.code == ALNFCTagErrorUnexpectedError) { //error ALNFCTagErrorUnexpectedError can mean the user pressed the 'Cancel' button while scanning. It could also mean the phone lost the connection with the NFC chip because it was moved. - [self startMRZScanning]; //run the MRZ scanner so we can try again. + if (error.code == ALNFCTagErrorResponseError || // error ALNFCTagErrorResponseError can mean the MRZ key was wrong + error.code == ALNFCTagErrorUnexpectedError) { // error ALNFCTagErrorUnexpectedError can mean the user pressed the + + // we could do this, but the dialog error would already be sufficient so this would be redundant. +// NSString *NFCErrorMessage = [NSString stringWithFormat:@"There was an error reading the NFC passport: %@", error.localizedDescription]; +// [weakSelf showAlertWithTitle:@"NFC Error" +// message:NFCErrorMessage +// completion:nil]; + + // 'Cancel' button while scanning. It could also mean the phone lost the connection with the NFC chip because it was moved. + [weakSelf.scanViewPlugin startWithError:nil]; + weakSelf.startTime = CACurrentMediaTime(); } else { - //the MRZ details are correct, but something else went wrong. We can try reading the NFC chip again without rescanning the MRZ. - [self readNFCChip]; - + // the MRZ details are correct, but something else went wrong. We can try reading the NFC chip again without rescanning the MRZ. + [weakSelf.nfcDetector startNfcDetectionWithPassportNumber:weakSelf.passportNumberForNFC + dateOfBirth:weakSelf.dateOfBirth + expirationDate:weakSelf.dateOfExpiry]; } + }); + + +} + +// MARK: - Accessories + ++ (UIView *)makeHintView { + CGFloat hintMargin = 7; + + UILabel *hintViewLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + UIView *hintView = [[UILabel alloc] initWithFrame:CGRectZero]; + hintViewLabel.text = @"Scan MRZ"; + [hintViewLabel sizeToFit]; // this may not be necessary + [hintView addSubview:hintViewLabel]; + + // TODO: how do i write this better (pref using constraints) + hintView.frame = UIEdgeInsetsInsetRect(hintViewLabel.frame, UIEdgeInsetsMake(-hintMargin, -hintMargin, -hintMargin, -hintMargin)); + hintView.translatesAutoresizingMaskIntoConstraints = NO; + // hintView.center = CGPointMake(self.view.center.x, 0); + hintViewLabel.translatesAutoresizingMaskIntoConstraints = NO; + [hintViewLabel.centerXAnchor constraintEqualToAnchor:hintView.centerXAnchor constant:0].active = YES; + [hintViewLabel.centerYAnchor constraintEqualToAnchor:hintView.centerYAnchor constant:0].active = YES; + hintView.layer.cornerRadius = 8; + hintView.layer.masksToBounds = true; + hintView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; + hintViewLabel.textColor = [UIColor whiteColor]; + + return hintView; } +- (ALResultEntry *)resultEntryWithDate:(NSDate *)date + dateString:(NSString *)dateString + title:(NSString *)title { -- (ALResultEntry *)resultEntryWithDate:(NSDate *)date dateString:(NSString *)dateString title:(NSString *)title { BOOL isAvailable = [self checkDateIfAvailable:date dateString:dateString]; if (!isAvailable) { return [[ALResultEntry alloc] initWithTitle:title value:nil]; @@ -270,6 +274,15 @@ - (BOOL)checkDateIfAvailable:(NSDate *)date dateString:(NSString *)dateString { return YES; } ++ (NSDate *)formattedStringToDate:(NSString *)formattedStr { + // From this: "Sun Apr 12 00:00:00 UTC 1977" to this: "04/12/1977" + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT+0:00"]]; + dateFormatter.dateFormat = @"E MMM d HH:mm:ss zzz yyyy"; + NSDate *d = [dateFormatter dateFromString:formattedStr]; + return d; +} + - (NSString *)stringForDate:(NSDate *)date { if (!date) { return @"Date not valid"; @@ -283,4 +296,30 @@ - (NSString *)stringForDate:(NSDate *)date { return [dateFormatter stringFromDate:date]; } +- (void)configureScanViewConfig { + // ALMRZConfig *mrzConfig = [[ALMRZConfig alloc] init]; + // //we want to be quite confident of these fields to ensure we can read the NFC with them + // ALMRZFieldConfidences *fieldConfidences = [[ALMRZFieldConfidences alloc] init]; + // fieldConfidences.documentNumber = 90; + // fieldConfidences.dateOfBirth = 90; + // fieldConfidences.dateOfExpiry = 90; + // mrzConfig.idFieldConfidences = fieldConfidences; + // + // //Create fieldScanOptions to configure individual scannable fields + // ALMRZFieldScanOptions *scanOptions = [[ALMRZFieldScanOptions alloc] init]; + // scanOptions.vizAddress = ALDefault; + // scanOptions.vizDateOfIssue = ALDefault; + // scanOptions.vizSurname = ALDefault; + // scanOptions.vizGivenNames = ALDefault; + // scanOptions.vizDateOfBirth = ALDefault; + // scanOptions.vizDateOfExpiry = ALDefault; + // + // //Set scanOptions for MRZConfig + // mrzConfig.idFieldScanOptions = scanOptions; +} + +//- (void)updateHintPosition:(CGFloat)newPosition { +// self.hintView.center = CGPointMake(self.hintView.center.x, newPosition); +//} + @end diff --git a/AnylineExamples/Anyline Examples Source/NFC/ViewController/mrz_nfc_config.json b/AnylineExamples/Anyline Examples Source/NFC/ViewController/mrz_nfc_config.json new file mode 100644 index 000000000..6e7390bd3 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/NFC/ViewController/mrz_nfc_config.json @@ -0,0 +1,45 @@ +{ + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.mrz", + "mrzConfig": { + "strictMode": false, + "cropAndTransformID": false + } + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "85%", + "maxHeightPercent": "70%", + "width": 0, + "alignment": "center", + "ratioFromSize": { + "width": 86, + "height": 54 + }, + "offset": { + "x": 0, + "y": 20 + }, + "cropPadding": { + "x": 25, + "y": 25 + }, + "outerColor": "000000", + "outerAlpha": 0.3, + "strokeWidth": 2, + "strokeColor": "0099FF", + "cornerRadius": 2, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig": { + "style": "rect", + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": false + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeter.h b/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeter.h index 789009b3e..ad33edd36 100755 --- a/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeter.h +++ b/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeter.h @@ -36,14 +36,14 @@ typedef NS_ENUM(NSUInteger, ALScannerType) { + (UIImage *)symbolImageForMeterType:(ALScannerType)type; + (ALScannerType)scannerTypeForMeterTypeString:(NSString *)meterTypeString; -+ (ALScanMode)scanModeForScannerType:(ALScannerType)scannerType; -+ (ALScannerType)scannerTypeForScanMode:(ALScanMode)scanMode; +//+ (ALScanMode)scanModeForScannerType:(ALScannerType)scannerType; +//+ (ALScannerType)scannerTypeForScanMode:(ALScanMode)scanMode; /** * Returns a readable string representation of the passed scan mode * * @return - readable string or nil */ -+ (NSString *)readableStringForScanMode:(ALScanMode)scanMode; +//+ (NSString *)readableStringForScanMode:(ALScanMode)scanMode; @end diff --git a/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeter.m b/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeter.m index db96f2efa..21bb9929f 100755 --- a/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeter.m +++ b/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeter.m @@ -82,143 +82,143 @@ + (ALScannerType)scannerTypeForMeterTypeString:(NSString *)meterTypeString { } } -+ (ALScanMode)scanModeForScannerType:(ALScannerType)scannerType { - switch (scannerType) { - case ALScannerTypeAnalog: { - return ALAnalogMeter; - } break; - - case ALScannerTypeGas: { - return ALAnalogMeter; - } break; - - case ALScannerTypePower: { - return ALAnalogMeter; - } break; - - case ALScannerTypeWaterBlackBackground: { - return ALAnalogMeter; - } break; - - case ALScannerTypeWaterWhiteBackground: { - return ALAnalogMeter; - } break; - - case ALScannerTypeSerialNumber: { - return ALSerialNumber; - } break; - - case ALScannerTypeQRCode: - case ALScannerTypeBarcode: { - return ALMeterBarcode; - } break; - - case ALScannerTypeDigital: { - return ALDigitalMeter; - } break; - - case ALScannerTypeHeat4: { - return ALHeatMeter4; - } break; - - case ALScannerTypeHeat5: { - return ALHeatMeter5; - } break; - - case ALScannerTypeHeat6: { - return ALHeatMeter6; - } break; - - case ALScannerTypeAutoAnalogDigital: { - return ALAutoAnalogDigitalMeter; - } break; - case ALScannerTypeUnknown: { - @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Cannot convert an unknown scanner type to an ALScanMode" userInfo:nil]; - } break; - } -} +//+ (ALScanMode)scanModeForScannerType:(ALScannerType)scannerType { +// switch (scannerType) { +// case ALScannerTypeAnalog: { +// return ALAnalogMeter; +// } break; +// +// case ALScannerTypeGas: { +// return ALAnalogMeter; +// } break; +// +// case ALScannerTypePower: { +// return ALAnalogMeter; +// } break; +// +// case ALScannerTypeWaterBlackBackground: { +// return ALAnalogMeter; +// } break; +// +// case ALScannerTypeWaterWhiteBackground: { +// return ALAnalogMeter; +// } break; +// +// case ALScannerTypeSerialNumber: { +// return ALSerialNumber; +// } break; +// +// case ALScannerTypeQRCode: +// case ALScannerTypeBarcode: { +// return ALMeterBarcode; +// } break; +// +// case ALScannerTypeDigital: { +// return ALDigitalMeter; +// } break; +// +// case ALScannerTypeHeat4: { +// return ALHeatMeter4; +// } break; +// +// case ALScannerTypeHeat5: { +// return ALHeatMeter5; +// } break; +// +// case ALScannerTypeHeat6: { +// return ALHeatMeter6; +// } break; +// +// case ALScannerTypeAutoAnalogDigital: { +// return ALAutoAnalogDigitalMeter; +// } break; +// case ALScannerTypeUnknown: { +// @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Cannot convert an unknown scanner type to an ALScanMode" userInfo:nil]; +// } break; +// } +//} -+ (ALScannerType)scannerTypeForScanMode:(ALScanMode)scanMode { - switch (scanMode) { - case ALAnalogMeter: { - return ALScannerTypeAnalog; - } break; - - case ALAutoAnalogDigitalMeter: { - return ALScannerTypeAutoAnalogDigital; - } break; - - case ALMeterBarcode: { - return ALScannerTypeBarcode; - } break; - - case ALDigitalMeter: { - return ALScannerTypeDigital; - } break; - case ALHeatMeter4: { - return ALScannerTypeHeat4; - } break; - case ALHeatMeter5: { - return ALScannerTypeHeat5; - } break; - case ALHeatMeter6: { - return ALScannerTypeHeat6; - } break; - - default: - { - //WARNING: These are unimplemented as of yet - return ALScannerTypeUnknown; - } break; - } - return ALScannerTypeGas; -} +//+ (ALScannerType)scannerTypeForScanMode:(ALScanMode)scanMode { +// switch (scanMode) { +// case ALAnalogMeter: { +// return ALScannerTypeAnalog; +// } break; +// +// case ALAutoAnalogDigitalMeter: { +// return ALScannerTypeAutoAnalogDigital; +// } break; +// +// case ALMeterBarcode: { +// return ALScannerTypeBarcode; +// } break; +// +// case ALDigitalMeter: { +// return ALScannerTypeDigital; +// } break; +// case ALHeatMeter4: { +// return ALScannerTypeHeat4; +// } break; +// case ALHeatMeter5: { +// return ALScannerTypeHeat5; +// } break; +// case ALHeatMeter6: { +// return ALScannerTypeHeat6; +// } break; +// +// default: +// { +// //WARNING: These are unimplemented as of yet +// return ALScannerTypeUnknown; +// } break; +// } +// return ALScannerTypeGas; +//} -+ (NSString *)readableStringForScanMode:(ALScanMode)scanMode { - switch (scanMode) { - case ALAnalogMeter: { - return @"Analog Meter"; - } break; - - case ALAutoAnalogDigitalMeter: { - return @"Auto Analog Digital Meter"; - } break; - - case ALDialMeter: { - return @"Dial Meter"; - } break; - - case ALDotMatrixMeter: { - return @"Dot Matrix Meter Meter"; - } break; - case ALMeterBarcode: { - return @"Barcode"; - } break; - - case ALDigitalMeter: { - return @"Digital Meter"; - } break; - - case ALHeatMeter4: { - return @"Heat Meter"; - } break; - - case ALHeatMeter5: { - return @"Heat Meter"; - } break; - - case ALHeatMeter6: { - return @"Heat Meter"; - } break; - - case ALSerialNumber: { - return @"Serial Number"; - } break; - default: { - return nil; - } break; - } - return nil; -} +//+ (NSString *)readableStringForScanMode:(ALScanMode)scanMode { +// switch (scanMode) { +// case ALAnalogMeter: { +// return @"Analog Meter"; +// } break; +// +// case ALAutoAnalogDigitalMeter: { +// return @"Auto Analog Digital Meter"; +// } break; +// +// case ALDialMeter: { +// return @"Dial Meter"; +// } break; +// +// case ALDotMatrixMeter: { +// return @"Dot Matrix Meter Meter"; +// } break; +// case ALMeterBarcode: { +// return @"Barcode"; +// } break; +// +// case ALDigitalMeter: { +// return @"Digital Meter"; +// } break; +// +// case ALHeatMeter4: { +// return @"Heat Meter"; +// } break; +// +// case ALHeatMeter5: { +// return @"Heat Meter"; +// } break; +// +// case ALHeatMeter6: { +// return @"Heat Meter"; +// } break; +// +// case ALSerialNumber: { +// return @"Serial Number"; +// } break; +// default: { +// return nil; +// } break; +// } +// return nil; +//} @end diff --git a/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeterReading.m b/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeterReading.m index 638e1f7e3..37afd0306 100755 --- a/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeterReading.m +++ b/AnylineExamples/Anyline Examples Source/Processes/Energy/ALMeterReading.m @@ -26,7 +26,7 @@ - (instancetype)initWithType:(ALScannerType)type image:(UIImage *)meterImage ful if (self = [super initWithType:type]) { if (!meterImage) @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"`meterImage` is required when instantiating a ALMeterReading" userInfo:nil]; if (!result) @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"`result` is required when instantiating a ALMeterReading" userInfo:nil]; - + self.image = meterImage; self.fullImage = fullImage; self.result = result; @@ -51,7 +51,7 @@ - (NSString *)readingValue { - (NSUInteger)insignificantDigitsCount { NSArray *components = [self.readingString componentsSeparatedByString:@"."]; NSUInteger fractionalCount = components.count >= 2 ? [components[1] length] : 0; - + return fractionalCount; } @@ -70,66 +70,66 @@ - (instancetype)initWithType:(ALScannerType)type { - (id)copyWithZone:(NSZone *)zone { __typeof__(self) copy = [[self class] allocWithZone:zone]; - + copy.type = self.type; copy.image = [self.image copy]; copy.result = [self.result copy]; - - return copy; -} - -@end - -@interface ALResultDebuggingSubclass : ALResult - -@property (strong, nonatomic) NSDictionary *values; - -@end - -@implementation ALResultDebuggingSubclass - -#pragma mark - Overrides - -- (instancetype)init { - if (self = [super init]) { - self.values = @{ - @"alam_1": @(1), - @"alam_2": @(2), - @"alam_3": @(3), - @"alam_4": @(4), - @"alam_5": @(5), - @"alam_6": @(6), - @"alam_7": @(7), - }; - } - - return self; -} - -- (BOOL)valid { - return YES; -} - -- (NSArray *)identifiers { - return self.values.allKeys; -} - -- (id)resultForIdentifier:(NSString *)identifier { - return self.values[identifier]; -} -#pragma mark - NSCopying - -- (id)copyWithZone:(NSZone *)zone { - __typeof__(self) copy = [[self class] allocWithZone:zone]; - - copy.values = [self.values copy]; - return copy; } @end +//@interface ALResultDebuggingSubclass : ALResult +// +//@property (strong, nonatomic) NSDictionary *values; +// +//@end +// +//@implementation ALResultDebuggingSubclass +// +//#pragma mark - Overrides +// +//- (instancetype)init { +// if (self = [super init]) { +// self.values = @{ +// @"alam_1": @(1), +// @"alam_2": @(2), +// @"alam_3": @(3), +// @"alam_4": @(4), +// @"alam_5": @(5), +// @"alam_6": @(6), +// @"alam_7": @(7), +// }; +// } +// +// return self; +//} +// +//- (BOOL)valid { +// return YES; +//} +// +//- (NSArray *)identifiers { +// return self.values.allKeys; +//} +// +//- (id)resultForIdentifier:(NSString *)identifier { +// return self.values[identifier]; +//} +// +//#pragma mark - NSCopying +// +//- (id)copyWithZone:(NSZone *)zone { +// __typeof__(self) copy = [[self class] allocWithZone:zone]; +// +// copy.values = [self.values copy]; +// +// return copy; +//} +// +//@end + @implementation ALMeterReading (DebuggingAdditions) + (instancetype)debuggingInstance { @@ -147,35 +147,35 @@ + (NSString *)fallbackResultForScannerType:(ALScannerType)type { case ALScannerTypeAnalog:{ return @"83744.9"; } break; - + case ALScannerTypeGas:{ return @"00613.839"; } break; - + case ALScannerTypePower:{ return @"83744.9"; } break; - + case ALScannerTypeWaterWhiteBackground:{ return @"00626.451"; } break; - + case ALScannerTypeWaterBlackBackground:{ return @"00000.020"; } break; - + case ALScannerTypeHeat4: case ALScannerTypeHeat5: case ALScannerTypeHeat6: case ALScannerTypeDigital:{ return @"12827.3"; } break; - + case ALScannerTypeBarcode: case ALScannerTypeQRCode:{ return @"01241385 001"; } - + case ALScannerTypeUnknown: case ALScannerTypeSerialNumber:{ return nil; @@ -188,34 +188,34 @@ + (UIImage *)fallbackCroppedImageForScannerType:(ALScannerType)type { case ALScannerTypeAnalog:{ return [UIImage imageNamed:@"analog electricity cutout"]; } break; - + case ALScannerTypeAutoAnalogDigital:{ return [UIImage imageNamed:@"analog electricity cutout"]; } break; - + case ALScannerTypeGas:{ return [UIImage imageNamed:@"gas meter cutout"]; } break; - + case ALScannerTypePower:{ return [UIImage imageNamed:@"analog electricity cutout"]; } break; - + case ALScannerTypeWaterWhiteBackground:{ return [UIImage imageNamed:@"water white cutout"]; } break; - + case ALScannerTypeWaterBlackBackground:{ return [UIImage imageNamed:@"water meter black cutout"]; } break; - + case ALScannerTypeHeat4: case ALScannerTypeHeat5: case ALScannerTypeHeat6: case ALScannerTypeDigital:{ return [UIImage imageNamed:@"digital cutout"]; } break; - + case ALScannerTypeUnknown: case ALScannerTypeSerialNumber: case ALScannerTypeBarcode: @@ -230,34 +230,34 @@ + (UIImage *)fallbackFullImageForScannerType:(ALScannerType)type { case ALScannerTypeAnalog:{ return [UIImage imageNamed:@"analog electricity meter full"]; } break; - + case ALScannerTypeAutoAnalogDigital:{ return [UIImage imageNamed:@"analog electricity meter full"]; } break; - + case ALScannerTypeGas:{ return [UIImage imageNamed:@"gas meter full"]; } break; - + case ALScannerTypePower:{ return [UIImage imageNamed:@"analog electricity meter full"]; } break; - + case ALScannerTypeWaterWhiteBackground:{ return [UIImage imageNamed:@"water meter white full"]; } break; - + case ALScannerTypeWaterBlackBackground:{ return [UIImage imageNamed:@"water meter black full"]; } break; - + case ALScannerTypeHeat4: case ALScannerTypeHeat5: case ALScannerTypeHeat6: case ALScannerTypeDigital:{ return [UIImage imageNamed:@"digital meter full"]; } break; - + case ALScannerTypeUnknown: case ALScannerTypeSerialNumber: case ALScannerTypeBarcode: diff --git a/AnylineExamples/Anyline Examples Source/Processes/Energy/Configs/serial_meter_barcode_config.json b/AnylineExamples/Anyline Examples Source/Processes/Energy/Configs/serial_meter_barcode_config.json new file mode 100644 index 000000000..1c4549ce9 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Processes/Energy/Configs/serial_meter_barcode_config.json @@ -0,0 +1,90 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "720p" + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left" + }, + "viewPluginCompositeConfig": { + "id": "energy_process", + "processingMode": "sequential", + "viewPlugins": [ + { + "viewPluginConfig": { + "pluginConfig": { + "id": "meter", + "meterConfig": { + "scanMode": "auto_analog_digital_meter" + }, + "cancelOnResult": true, + "startScanDelay": 0 + }, + "cutoutConfig": { + "style": "rect", + "maxWidthPercent": "100%", + "width": 768, + "alignment": "top_half", + "ratioFromSize": { "width": 9, "height": 4 }, + "offset": { "x": 0, "y": 80 }, + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "contour_rect", + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "220099FF", + "cornerRadius": 2, + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true, + "redrawTimeout": 200, + "animationDuration": 75 + } + } + }, + { + "viewPluginConfig": { + "pluginConfig": { + "id": "barcode", + "barcodeConfig": { + "barcodeFormats": [ "ALL" ] + }, + "cancelOnResult": true, + "startScanDelay": 100 + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "75%", + "alignment": "center", + "ratioFromSize": { "width": 4, "height": 1 }, + "offset": { "x": 0, "y": 0 }, + "cropOffset": { "x": 0, "y": 0 }, + "cropPadding": { "x": 0, "y": 0 }, + "cornerRadius": 4, + "strokeColor": "0099FF", + "strokeWidth": 2, + "outerColor": "000000", + "feedbackStrokeColor": "0099FF", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "animated_rect", + "strokeWidth": 2, + "strokeColor": "000000", + "fillColor": "330099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true + } + } + } + ] + } +} + diff --git a/AnylineExamples/Anyline Examples Source/Processes/Energy/ScanViewController/ALEnergyMeterScanViewController.h b/AnylineExamples/Anyline Examples Source/Processes/Energy/ScanViewController/ALEnergyMeterScanViewController.h index 62b2f613d..4e8ea715b 100644 --- a/AnylineExamples/Anyline Examples Source/Processes/Energy/ScanViewController/ALEnergyMeterScanViewController.h +++ b/AnylineExamples/Anyline Examples Source/Processes/Energy/ScanViewController/ALEnergyMeterScanViewController.h @@ -1,11 +1,3 @@ -// -// ALEnergyMeterScanViewController.h -// AnylineExamples -// -// Created by Philipp Müller on 10/01/18. -// Copyright © 2018 Anyline GmbH. All rights reserved. -// - #import #import "ALBaseScanViewController.h" diff --git a/AnylineExamples/Anyline Examples Source/Processes/Energy/ScanViewController/ALEnergyMeterScanViewController.m b/AnylineExamples/Anyline Examples Source/Processes/Energy/ScanViewController/ALEnergyMeterScanViewController.m index bca387ffb..c6df0a324 100644 --- a/AnylineExamples/Anyline Examples Source/Processes/Energy/ScanViewController/ALEnergyMeterScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/Processes/Energy/ScanViewController/ALEnergyMeterScanViewController.m @@ -1,117 +1,69 @@ -// -// ALEnergyMeterScanViewController.m -// AnylineExamples -// -// Created by Philipp Mueller on 10/01/18 -// Copyright © 2018 Anyline GmbH. All rights reserved. -// - -#import "NSUserDefaults+ALExamplesAdditions.h" #import "ALEnergyMeterScanViewController.h" -#import "ALMeterScanResultViewController.h" #import -#import "ALUtils.h" -#import "NSString+Util.h" - +#import "ALMeterScanResultViewController.h" +#import "CustomerSelfReadingResultViewController.h" +#import "WorkforceToolResultViewController.h" #import "CustomerDataView.h" - #import "ALMeterReading.h" -#import "CustomerDataView.h" #import "Reading.h" -#import "CustomerSelfReadingResultViewController.h" -#import "WorkforceToolResultViewController.h" - -NSString * const kMeterScanPluginID = @"METER_READING"; - -// The controller has to conform to to be able to receive results -@interface ALEnergyMeterScanViewController () +#import "ALUtils.h" +#import "ALPluginResultHelper.h" +#import "NSUserDefaults+ALExamplesAdditions.h" +#import "NSString+Util.h" -// The Anyline plugin used to scan -@property (nonatomic, strong) ALSerialScanViewPluginComposite *serialComposite; -@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +@interface ALEnergyMeterScanViewController () -@property (nonatomic, strong) NSString *barcodeResult; +//@property (nonatomic, strong, nullable) ALScanView *scanView; +@property (nonatomic, strong, nullable) ALViewPluginComposite *viewPluginComposite; +@property (nonatomic, strong, nullable) NSString *barcodeResult; @property (nonatomic, strong) UIView *customerDataContainer; -@property (strong, nonatomic) NSLayoutConstraint *customerDataContainerViewHeightConstraint; -@property (nonatomic, assign, readonly) ALScanMode scanMode; +@property (strong, nonatomic) NSLayoutConstraint *customerDataContainerViewHeightConstraint; @end + @implementation ALEnergyMeterScanViewController -/* - We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed. - */ - (void)viewDidLoad { self.title = @"Barcode"; - CGRect frame = [self scanViewFrame]; - - - /* - * Create Meter Scanning components - */ - //Add Meter Scan Plugin (Scan Process) - NSError *error = nil; - - - ALMeterScanPlugin *meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:kMeterScanPluginID - delegate:self - error:&error]; - NSAssert(meterScanPlugin, @"Setup Error: %@", error.debugDescription); - BOOL success = [meterScanPlugin setScanMode:ALAutoAnalogDigitalMeter error:&error]; - if( !success ) { - // Something went wrong. The error object contains the error description - __weak __block typeof(self) weakSelf = self; - [self showAlertWithTitle:@"Set ScanMode Error" message:error.debugDescription completion:^{ - [weakSelf.navigationController popViewControllerAnimated:YES]; - }]; + + NSString *configJSONStr = [self configJSONStrWithFilename:@"serial_meter_barcode_config"]; + NSDictionary *JSONDict = [configJSONStr asJSONObject]; + + id obj = [ALScanViewPluginFactory withJSONDictionary:JSONDict ]; + NSAssert([obj isKindOfClass:ALViewPluginComposite.class], @"should be a plugin composite!"); + + ALScanViewConfig *scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:JSONDict error:nil]; + + self.viewPluginComposite = (ALViewPluginComposite *)obj; + self.viewPluginComposite.delegate = self; + + for (id child in self.viewPluginComposite.children) { + if ([child isKindOfClass:ALScanViewPlugin.class]) { + ((ALScanViewPlugin *)child).scanPlugin.delegate = self; + ((ALScanViewPlugin *)child).delegate = self; + } } - //Add Meter Scan View Plugin (Scan UI) - ALMeterScanViewPlugin *meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:meterScanPlugin]; - //We use this as a property, to use it for the example scan history - self.meterScanViewPlugin = meterScanViewPlugin; - - /* - * Create Barcode Scanning components - */ - ALBarcodeScanPlugin *barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] initWithPluginID:@"BARCODE" - delegate:self error:&error]; - barcodeScanPlugin.barcodeFormatOptions = @[kCodeTypeAll]; - NSAssert(barcodeScanPlugin, @"Setup Error: %@", error.debugDescription); - - ALBarcodeScanViewPlugin *barcodeScanViewPlugiun = [[ALBarcodeScanViewPlugin alloc] initWithScanPlugin:barcodeScanPlugin]; - - - /* - * Combine Barcode and Meter Scanning in a SerialComposite - */ - self.serialComposite = [[ALSerialScanViewPluginComposite alloc] initWithPluginID:@""]; - [self.serialComposite addDelegate:self]; - [self.serialComposite addPlugin:barcodeScanViewPlugiun]; - [self.serialComposite addPlugin:meterScanViewPlugin]; - - //Add ScanView (Camera and Flashbutton) - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.serialComposite]; - - [self.view addSubview:self.scanView]; - [self.scanView startCamera]; - - + + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.viewPluginComposite + scanViewConfig:scanViewConfig + error:nil]; self.scanView.translatesAutoresizingMaskIntoConstraints = NO; - - // After setup is complete we add the scanView to the view of this view controller - - [[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView}]]; - id topGuide = self.topLayoutGuide; - [[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-0-[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView, @"topGuide" : topGuide}]]; + + [self installScanView:self.scanView]; + [self.scanView startCamera]; + + // [[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView}]]; + // id topGuide = self.topLayoutGuide; + // [[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-0-[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView, @"topGuide" : topGuide}]]; self.controllerType = ALScanHistoryElectricMeter; - //Init customer data container view + // Init customer data container view [self setupCustomerDataContainer]; if (self.customer) { @@ -121,25 +73,11 @@ - (void)viewDidLoad { self.barcodeResult = @""; } -/* - This method will be called once the view controller and its subviews have appeared on screen - */ - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - [self startAnyline]; + [self.viewPluginComposite startWithError:nil]; } -- (void)viewDidLayoutSubviews { - [super viewDidLayoutSubviews]; - -} - -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [self.serialComposite stopAndReturnError:nil]; -} #pragma mark - Customer Methods @@ -170,7 +108,9 @@ - (void)_addCustomerDataView { } } } + #pragma mark - UI Setup Methods + - (void)setupCustomerDataContainer { //Init customerDatacontainer view self.customerDataContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 359, 195)]; @@ -181,17 +121,15 @@ - (void)setupCustomerDataContainer { [self.view addSubview:self.customerDataContainer]; - //Trailing - NSLayoutConstraint *trailing =[NSLayoutConstraint - constraintWithItem:self.customerDataContainer - attribute:NSLayoutAttributeTrailing - relatedBy:NSLayoutRelationEqual - toItem:self.view - attribute:NSLayoutAttributeTrailing - multiplier:1.0f - constant:-5.f]; + NSLayoutConstraint *trailing = [NSLayoutConstraint + constraintWithItem:self.customerDataContainer + attribute:NSLayoutAttributeTrailing + relatedBy:NSLayoutRelationEqual + toItem:self.view + attribute:NSLayoutAttributeTrailing + multiplier:1.0f + constant:-5.f]; - //Leading NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:self.customerDataContainer attribute:NSLayoutAttributeLeading @@ -200,16 +138,15 @@ - (void)setupCustomerDataContainer { attribute:NSLayoutAttributeLeading multiplier:1.0f constant:5.f]; - - //Bottom - NSLayoutConstraint *bottom =[NSLayoutConstraint - constraintWithItem:self.customerDataContainer - attribute:NSLayoutAttributeBottom - relatedBy:NSLayoutRelationEqual - toItem:self.view - attribute:NSLayoutAttributeBottom - multiplier:1.0f - constant:-5.f]; + + NSLayoutConstraint *bottom = [NSLayoutConstraint + constraintWithItem:self.customerDataContainer + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationEqual + toItem:self.view + attribute:NSLayoutAttributeBottom + multiplier:1.0f + constant:-5.f]; [self.view addConstraint:trailing]; [self.view addConstraint:bottom]; @@ -228,62 +165,62 @@ - (void)setupCustomerDataContainer { [self.customerDataContainer addConstraint:height]; } -#pragma mark - Anyline Result Delegates -- (void)anylineMeterScanPlugin:(ALMeterScanPlugin *)anylineMeterScanPlugin didFindResult:(ALMeterResult *)scanResult { - //TODO: (RNR) convert this result to the json string so we have the same types across the scanmodes - [self anylineDidFindResult:scanResult.result barcodeResult:self.barcodeResult image:(UIImage*)scanResult.image scanPlugin:anylineMeterScanPlugin viewPlugin:self.meterScanViewPlugin completion:^{ - [self displayReading:scanResult]; - }]; -} +// MARK: - ALScanPluginDelegate, ALViewPluginCompositeDelegate -- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin *)anylineBarcodeScanPlugin didFindResult:(ALBarcodeResult *)scanResult { - BOOL stopped = [self.serialComposite stopAndReturnError:nil]; - - [self evaluateMeterId:[scanResult.result firstObject]]; - if (self.customer) { - self.barcodeResult = [scanResult.result firstObject].value; - //if we have a 'Customer Not Found' message showing because we read a bad barcode previously and they haven't dismissed the message yet, dismiss it, since we have now found a customer. - if ([self.presentedViewController isKindOfClass:UIAlertController.class]) { - [self dismissViewControllerAnimated:YES completion:nil]; - } - [self.serialComposite startFromID:kMeterScanPluginID andReturnError:nil]; - self.title = @"Analog/Digital Meter"; - } else { - //we don't want the composite to be running when we return from this method, or it may do something with the barcode result when it gets this delegate message - [self.serialComposite performSelector:@selector(startAndReturnError:) withObject:nil afterDelay:0.0]; - self.barcodeResult = @""; - self.customer = nil; - } - -} +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + // from the config at serial_meter_barcode_config.json, the ids are + // "meter" and "barcode" with meter coming in first + if ([scanPlugin.pluginID isEqualToString:@"meter"]) { + NSString *meterReading = scanResult.pluginResult.meterResult.value; + __weak __block typeof(self) weakSelf = self; + [self anylineDidFindResult:meterReading + barcodeResult:nil + image:scanResult.croppedImage + scanPlugin:scanPlugin + viewPlugin:self.viewPluginComposite completion:^{ + [weakSelf displayReading:scanResult]; + }]; + } else if ([scanPlugin.pluginID isEqualToString:@"barcode"]) { + NSString *barcodeReading = scanResult.pluginResult.barcodeResult.barcodes.firstObject.decoded; + [self evaluateMeterId:barcodeReading]; -- (void)anylineCompositeScanPlugin:(ALAbstractScanViewPluginComposite *)anylineCompositeScanPlugin - didFindResult:(ALCompositeResult *)scanResult { - //If you only need the final result, you can use this method - // ALCompositeResult *scanResult will contain one result per added scanViewPlugin. -} + if (self.customer) { + self.barcodeResult = barcodeReading; + // if we have a 'Customer Not Found' message showing because we read a bad barcode previously and + // they haven't dismissed the message yet, dismiss it, since we have now found a customer. + if ([self.presentedViewController isKindOfClass:UIAlertController.class]) { + [self dismissViewControllerAnimated:YES completion:nil]; + } + + // TODO: work around this unsupported functionality (maybe just restart the whole plugin) + // [self.viewPluginComposite startFromID:kMeterScanPluginID andReturnError:nil]; -#pragma mark - Anyline Utility Methods + self.title = @"Analog/Digital Meter"; + + } else { + // we don't want the composite to be running when we return from this method, or it may do + // something with the barcode result when it gets this delegate message + [self.viewPluginComposite performSelector:@selector(startAndReturnError:) withObject:nil afterDelay:0.0]; + self.barcodeResult = @""; + self.customer = nil; + } -- (void)startAnyline { - /* - This is the place where we tell Anyline to start receiving and displaying images from the camera. - Success/error tells us if everything went fine. - */ - if (![self.serialComposite isRunning]) { - [self startPlugin:self.serialComposite]; } } -#pragma mark - Customer<->reading Utility Methods +- (void)viewPluginComposite:(ALViewPluginComposite *)viewPluginComposite allResultsReceived:(NSArray *)scanResults { + // this is here if you plan on getting notified if both meter and barcode scan results. +} + +// MARK: - Customer<->Reading Utility Methods -- (void)evaluateMeterId:(ALBarcode *)barcode { +- (void)evaluateMeterId:(NSString *)barcode { if (self.order) { - self.customer = [self.order customerWithMeterID:[barcode.value stringByCleaningWhitespace]]; + self.customer = [self.order customerWithMeterID:[barcode stringByCleaningWhitespace]]; } else if (self.csr) { - self.customer = [self.csr customerWithMeterID:[barcode.value stringByCleaningWhitespace]]; + self.customer = [self.csr customerWithMeterID:[barcode stringByCleaningWhitespace]]; } - + if (!self.customer) { [self showAlertWithTitle:@"Customer not found" message:@"Make sure you are scanning a meter reading customer from the Anyline Examples sheet." @@ -292,38 +229,43 @@ - (void)evaluateMeterId:(ALBarcode *)barcode { } - (void)displayReading:(ALScanResult *)scanResult { - if (self.customer) { - ALScannerType scannerType = [ALMeterReading scannerTypeForMeterTypeString:self.customer.meterType]; - - NSError *error; - Reading *reading = [Reading insertNewObjectWithReadingValue:scanResult.result - sort:@(self.customer.readings.count) - scannedImage:scanResult.fullImage - readingDate:[NSDate date] - customer:self.customer - inManagedObjectContext:self.customer.managedObjectContext - error:&error]; - if (error) { - NSLog(@"Persitence Error: %@", [error localizedDescription]); - } - - [self.customer addReadingsObject:reading]; - - ALMeterReading *mr = [ALMeterReading meterReadingWithType:scannerType - image:scanResult.image - fullImage:scanResult.fullImage - result:scanResult.result]; - - if(self.order) { - WorkforceToolResultViewController *resultVC = [[WorkforceToolResultViewController alloc]initWithReading:reading andMeterReading:mr]; - resultVC.delegate = self; - [self.navigationController pushViewController:resultVC animated:YES]; - - } else if (self.csr) { - CustomerSelfReadingResultViewController *resultVC = [[CustomerSelfReadingResultViewController alloc]initWithReading:reading andMeterReading:mr]; - resultVC.delegate = self; - [self.navigationController pushViewController:resultVC animated:YES]; - } + + if (!self.customer) { + return; + } + + NSString *meterReading = scanResult.pluginResult.meterResult.value; + + ALScannerType scannerType = [ALMeterReading scannerTypeForMeterTypeString:self.customer.meterType]; + + NSError *error; + Reading *reading = [Reading insertNewObjectWithReadingValue:meterReading + sort:@(self.customer.readings.count) + scannedImage:scanResult.fullSizeImage + readingDate:[NSDate date] + customer:self.customer + inManagedObjectContext:self.customer.managedObjectContext + error:&error]; + if (error) { + NSLog(@"Persistence Error: %@", error.localizedDescription); + } + + [self.customer addReadingsObject:reading]; + + ALMeterReading *mr = [ALMeterReading meterReadingWithType:scannerType + image:scanResult.croppedImage + fullImage:scanResult.fullSizeImage + result:meterReading]; + + if (self.order) { + WorkforceToolResultViewController *resultVC = [[WorkforceToolResultViewController alloc]initWithReading:reading andMeterReading:mr]; + resultVC.delegate = self; + [self.navigationController pushViewController:resultVC animated:YES]; + + } else if (self.csr) { + CustomerSelfReadingResultViewController *resultVC = [[CustomerSelfReadingResultViewController alloc]initWithReading:reading andMeterReading:mr]; + resultVC.delegate = self; + [self.navigationController pushViewController:resultVC animated:YES]; } } @@ -339,19 +281,21 @@ - (void)startWithReset:(BOOL)isReset { [self _addCustomerDataView]; //reset found barcode self.barcodeResult = @""; - [self.serialComposite startAndReturnError:nil]; + [self.viewPluginComposite startWithError:nil]; self.title = @"Barcode"; } else { - [self startAnyline]; + [self.viewPluginComposite startWithError:nil]; } } - -#pragma mark - CustomerSelfReadingResultDelegate methods + +// MARK: - CustomerSelfReadingResultDelegate methods - (void)backFromResultView:(CustomerSelfReadingResultViewController *)customerSelfReadingResultView isReset:(BOOL)isReset { [self startWithReset:isReset]; } + - (void)backFromWorkforceResultView:(WorkforceToolResultViewController *)workforceToolResultViewController isReset:(BOOL)isReset { [self startWithReset:isReset]; } + @end diff --git a/AnylineExamples/Anyline Examples Source/RB/ViewController/ALRBScanViewController.m b/AnylineExamples/Anyline Examples Source/RB/ViewController/ALRBScanViewController.m index dad96ff4f..d3763eeba 100644 --- a/AnylineExamples/Anyline Examples Source/RB/ViewController/ALRBScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/RB/ViewController/ALRBScanViewController.m @@ -13,12 +13,12 @@ #import "AnylineExamples-Swift.h" // The controller has to conform to to be able to receive results -@interface ALRBScanViewController () +@interface ALRBScanViewController () // // The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *rbScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *rbScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALOCRScanViewPlugin *rbScanViewPlugin; +//@property (nonatomic, strong) ALOCRScanPlugin *rbScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; @end @@ -33,37 +33,37 @@ - (void)viewDidLoad { // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen CGRect frame = [self scanViewFrame]; - ALOCRConfig *config = [[ALOCRConfig alloc] init]; - config.scanMode = ALGrid; - config.charHeight = ALRangeMake(22, 45); - config.characterWhitelist = @"2346789ABCDEFGHKLMNPQRTUVWXYZ"; - config.minConfidence = 55; - config.validationRegex = @"^[0-9A-Z]{4}\n[0-9A-Z]{4}"; - - config.charCountX = 4; - config.charCountY = 2; - config.charPaddingXFactor = 0.3; - config.charPaddingYFactor = 0.5; - config.isBrightTextOnDark = YES; +// ALOCRConfig *config = [[ALOCRConfig alloc] init]; +// config.scanMode = ALGrid; +// config.charHeight = ALRangeMake(22, 45); +// config.characterWhitelist = @"2346789ABCDEFGHKLMNPQRTUVWXYZ"; +// config.minConfidence = 55; +// config.validationRegex = @"^[0-9A-Z]{4}\n[0-9A-Z]{4}"; +// +// config.charCountX = 4; +// config.charCountY = 2; +// config.charPaddingXFactor = 0.3; +// config.charPaddingYFactor = 0.5; +// config.isBrightTextOnDark = YES; NSError *error = nil; - self.rbScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.rbScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.rbScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"rb_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.rbScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.rbScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - NSAssert(self.rbScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.rbScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.rbScanViewPlugin]; +// self.rbScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" +// delegate:self +// ocrConfig:config +// error:&error]; +// NSAssert(self.rbScanPlugin, @"Setup Error: %@", error.debugDescription); +// [self.rbScanPlugin addInfoDelegate:self]; +// +// NSString *confPath = [[NSBundle mainBundle] pathForResource:@"rb_config" ofType:@"json"]; +// ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +// +// self.rbScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.rbScanPlugin +// scanViewPluginConfig:scanViewPluginConfig]; +// NSAssert(self.rbScanViewPlugin, @"Setup Error: %@", error.debugDescription); +// [self.rbScanViewPlugin addScanViewPluginDelegate:self]; +// +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.rbScanViewPlugin]; // After setup is complete we add the scanView to the view of this view controller [self.view addSubview:self.scanView]; @@ -71,7 +71,7 @@ - (void)viewDidLoad { //Start Camera: [self.scanView startCamera]; - [self startListeningForMotion]; +// [self startListeningForMotion]; self.controllerType = ALScanHistoryRedBull; } @@ -79,21 +79,21 @@ - (void)viewDidLoad { /* This method will be called once the view controller and its subviews have appeared on screen */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} +//-(void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// +// // We use this subroutine to start Anyline. The reason it has its own subroutine is +// // so that we can later use it to restart the scanning process. +// [self startAnyline]; +//} /* Cancel scanning to allow the module to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.rbScanViewPlugin stopAndReturnError:nil]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [self.rbScanViewPlugin stopAndReturnError:nil]; +//} /* This method is used to tell Anyline to start scanning. It gets called in @@ -102,47 +102,47 @@ is found scanning will stop automatically (you can change this behaviour with cancelOnResult:). When the user dismisses self.identificationView this method will get called again. */ -- (void)startAnyline { - [self startPlugin:self.rbScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} +//- (void)startAnyline { +// [self startPlugin:self.rbScanViewPlugin]; +// self.startTime = CACurrentMediaTime(); +//} + +//- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { +// //Update Position of Warning Indicator +// [self updateWarningPosition: +// cutoutRect.origin.y + +// cutoutRect.size.height + +// self.scanView.frame.origin.y + +// 80]; +//} #pragma mark -- AnylineOCRModuleDelegate /* This is the main delegate method Anyline uses to report its results */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { - // We are done. Cancel scanning - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"RedBull Mobile Collect Code" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.rbScanViewPlugin completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] - initWithResults:resultData]; - vc.imagePrimary = result.image; - - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.rbScanViewPlugin]; - } - -} +//- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { +// // We are done. Cancel scanning +// NSMutableArray *resultData = [[NSMutableArray alloc] init]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"RedBull Mobile Collect Code" value:result.result shouldSpellOutValue:YES]]; +// NSString *jsonString = [self JSONStringFromResultData:resultData]; +// +// __weak __block typeof(self) weakSelf = self; +// [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.rbScanViewPlugin completion:^{ +// +// ALResultViewController *vc = [[ALResultViewController alloc] +// initWithResults:resultData]; +// vc.imagePrimary = result.image; +// +// [weakSelf.navigationController pushViewController:vc animated:YES]; +// }]; +//} +// +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ +// if ([info.variableName isEqualToString:@"$brightness"]) { +// [self updateBrightness:[info.value floatValue] forModule:self.rbScanViewPlugin]; +// } +// +//} @end diff --git a/AnylineExamples/Anyline Examples Source/RB/rb_config.json b/AnylineExamples/Anyline Examples Source/RB/rb_config.json index a763daaf8..e8e2dcd3d 100644 --- a/AnylineExamples/Anyline Examples Source/RB/rb_config.json +++ b/AnylineExamples/Anyline Examples Source/RB/rb_config.json @@ -12,7 +12,7 @@ }, "strokeWidth": 2, "cornerRadius": 80, - "strokeColor": "FFFFFF", + "strokeColor": "0099FF", "outerColor": "000000", "outerAlpha": 0.3, "feedbackStrokeColor": "0099FF" @@ -21,8 +21,8 @@ "style": "rect", "strokeColor": "0099FF", "fillColor": "330099FF", - "strokeWidth": 1, - "cornerRadius": 10, + "strokeWidth": 2, + "cornerRadius": 4, "beepOnResult": true, "vibrateOnResult": true, "blinkAnimationOnResult": true diff --git a/AnylineExamples/Anyline Examples Source/RecordNumber/ViewController/ALRecordNumberScanViewController.m b/AnylineExamples/Anyline Examples Source/RecordNumber/ViewController/ALRecordNumberScanViewController.m index 5e7c3c1bb..1b5809568 100644 --- a/AnylineExamples/Anyline Examples Source/RecordNumber/ViewController/ALRecordNumberScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/RecordNumber/ViewController/ALRecordNumberScanViewController.m @@ -12,12 +12,12 @@ #import "NSUserDefaults+ALExamplesAdditions.h" // The controller has to conform to to be able to receive results -@interface ALRecordNumberScanViewController () +@interface ALRecordNumberScanViewController () // // The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *recordScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *recordScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALOCRScanViewPlugin *recordScanViewPlugin; +//@property (nonatomic, strong) ALOCRScanPlugin *recordScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; @end @@ -32,32 +32,32 @@ - (void)viewDidLoad { // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen CGRect frame = [self scanViewFrame]; - ALOCRConfig *config = [[ALOCRConfig alloc] init]; - config.charHeight = ALRangeMake(22, 105); - config.characterWhitelist = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-."; - config.minConfidence = 75; - config.validationRegex = @"^([A-Z]+\\s*-*\\s*)?[0-9A-Z-\\s\\.]{3,}$"; - config.scanMode = ALLine; - config.removeSmallContours = NO; - +// ALOCRConfig *config = [[ALOCRConfig alloc] init]; +// config.charHeight = ALRangeMake(22, 105); +// config.characterWhitelist = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-."; +// config.minConfidence = 75; +// config.validationRegex = @"^([A-Z]+\\s*-*\\s*)?[0-9A-Z-\\s\\.]{3,}$"; +// config.scanMode = ALLine; +// config.removeSmallContours = NO; +// NSError *error = nil; - self.recordScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.recordScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.recordScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"record_number_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.recordScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.recordScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - NSAssert(self.recordScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.recordScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.recordScanViewPlugin]; +// self.recordScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" +// delegate:self +// ocrConfig:config +// error:&error]; +// NSAssert(self.recordScanPlugin, @"Setup Error: %@", error.debugDescription); +// [self.recordScanPlugin addInfoDelegate:self]; +// +// NSString *confPath = [[NSBundle mainBundle] pathForResource:@"record_number_config" ofType:@"json"]; +// ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +// +// self.recordScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.recordScanPlugin +// scanViewPluginConfig:scanViewPluginConfig]; +// NSAssert(self.recordScanViewPlugin, @"Setup Error: %@", error.debugDescription); +// [self.recordScanViewPlugin addScanViewPluginDelegate:self]; +// +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.recordScanViewPlugin]; // After setup is complete we add the scanView to the view of this view controller [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; @@ -72,7 +72,7 @@ - (void)viewDidLoad { //Start Camera: [self.scanView startCamera]; - [self startListeningForMotion]; +// [self startListeningForMotion]; self.controllerType = ALScanHistoryRecordNumber; } @@ -85,7 +85,7 @@ -(void)viewDidAppear:(BOOL)animated { // We use this subroutine to start Anyline. The reason it has its own subroutine is // so that we can later use it to restart the scanning process. - [self startAnyline]; +// [self startAnyline]; } /* @@ -93,7 +93,7 @@ -(void)viewDidAppear:(BOOL)animated { */ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - [self.recordScanViewPlugin stopAndReturnError:nil]; +// [self.recordScanViewPlugin stopAndReturnError:nil]; } /* @@ -103,40 +103,40 @@ is found scanning will stop automatically (you can change this behaviour with cancelOnResult:). When the user dismisses self.identificationView this method will get called again. */ -- (void)startAnyline { - [self startPlugin:self.recordScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} +//- (void)startAnyline { +// [self startPlugin:self.recordScanViewPlugin]; +// self.startTime = CACurrentMediaTime(); +//} -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} +//- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { +// //Update Position of Warning Indicator +// [self updateWarningPosition: +// cutoutRect.origin.y + +// cutoutRect.size.height + +// self.scanView.frame.origin.y + +// 80]; +//} #pragma mark -- AnylineOCRModuleDelegate /* This is the main delegate method Anyline uses to report its results */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { - //TODO: (RNR) convert this result to the json string so we have the same types across the scanmodes - [self anylineDidFindResult:result.result barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.recordScanViewPlugin completion:^{ - ALBaseViewController *vc = [[ALBaseViewController alloc] init]; - vc.result = result.result; - NSString *url = [NSString stringWithFormat:@"https://www.google.at/search?q=\"%@\" site:discogs.com OR site:musbrainz.org OR site:allmusic.com", result.result]; - [vc startWebSearchWithURL:url]; - [self.navigationController pushViewController:vc animated:YES]; - }]; -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.recordScanViewPlugin]; - } -} +//- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { +// //TODO: (RNR) convert this result to the json string so we have the same types across the scanmodes +// [self anylineDidFindResult:result.result barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.recordScanViewPlugin completion:^{ +// ALBaseViewController *vc = [[ALBaseViewController alloc] init]; +// vc.result = result.result; +// NSString *url = [NSString stringWithFormat:@"https://www.google.at/search?q=\"%@\" site:discogs.com OR site:musbrainz.org OR site:allmusic.com", result.result]; +// [vc startWebSearchWithURL:url]; +// [self.navigationController pushViewController:vc animated:YES]; +// }]; +//} +// +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ +// if ([info.variableName isEqualToString:@"$brightness"]) { +// [self updateBrightness:[info.value floatValue] forModule:self.recordScanViewPlugin]; +// } +//} @end diff --git a/AnylineExamples/Anyline Examples Source/RecordNumber/record_number_config.json b/AnylineExamples/Anyline Examples Source/RecordNumber/record_number_config.json index 82786561f..e0a661ba4 100644 --- a/AnylineExamples/Anyline Examples Source/RecordNumber/record_number_config.json +++ b/AnylineExamples/Anyline Examples Source/RecordNumber/record_number_config.json @@ -11,16 +11,16 @@ "height": 1 }, "strokeWidth": 2, - "cornerRadius": 10, - "strokeColor": "FFFFFF", + "cornerRadius": 4, + "strokeColor": "0099FF", "outerColor": "000000", "outerAlpha": 0.3, - "feedbackStrokeColor": "990099FF" + "feedbackStrokeColor": "0099FF" }, "scanFeedback" : { "style": "contour_underline", "strokeColor": "990099FF", - "strokeWidth": 3, + "strokeWidth": 2, "beepOnResult": true, "vibrateOnResult": true, "blinkAnimationOnResult": true diff --git a/AnylineExamples/Anyline Examples Source/Scrabble/ViewController/ALScrabbleScanViewController.m b/AnylineExamples/Anyline Examples Source/Scrabble/ViewController/ALScrabbleScanViewController.m index f544c67ea..8a6f1ac9e 100644 --- a/AnylineExamples/Anyline Examples Source/Scrabble/ViewController/ALScrabbleScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/Scrabble/ViewController/ALScrabbleScanViewController.m @@ -14,12 +14,12 @@ #import "NSUserDefaults+ALExamplesAdditions.h" // The controller has to conform to to be able to receive results -@interface ALScrabbleScanViewController () +@interface ALScrabbleScanViewController () // // The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *scrabbleScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *scrabbleScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALOCRScanViewPlugin *scrabbleScanViewPlugin; +//@property (nonatomic, strong) ALOCRScanPlugin *scrabbleScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; @end @@ -34,29 +34,29 @@ - (void)viewDidLoad { // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen CGRect frame = [self scanViewFrame]; - ALOCRConfig *config = [[ALOCRConfig alloc] init]; - config.scanMode = ALAuto; - config.characterWhitelist = @"ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖ"; - config.validationRegex = @"^[A-ZÄÜÖ]{7,10}$"; - - NSError *error = nil; - - self.scrabbleScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.scrabbleScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.scrabbleScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"scrabble_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.scrabbleScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.scrabbleScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - NSAssert(self.scrabbleScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.scrabbleScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.scrabbleScanViewPlugin]; +// ALOCRConfig *config = [[ALOCRConfig alloc] init]; +// config.scanMode = ALAuto; +// config.characterWhitelist = @"ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖ"; +// config.validationRegex = @"^[A-ZÄÜÖ]{7,10}$"; +// +// NSError *error = nil; +// +// self.scrabbleScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" +// delegate:self +// ocrConfig:config +// error:&error]; +// NSAssert(self.scrabbleScanPlugin, @"Setup Error: %@", error.debugDescription); +// [self.scrabbleScanPlugin addInfoDelegate:self]; +// +// NSString *confPath = [[NSBundle mainBundle] pathForResource:@"scrabble_config" ofType:@"json"]; +// ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +// +// self.scrabbleScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.scrabbleScanPlugin +// scanViewPluginConfig:scanViewPluginConfig]; +// NSAssert(self.scrabbleScanViewPlugin, @"Setup Error: %@", error.debugDescription); +// [self.scrabbleScanViewPlugin addScanViewPluginDelegate:self]; +// +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.scrabbleScanViewPlugin]; // After setup is complete we add the scanView to the view of this view controller [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; @@ -71,7 +71,7 @@ - (void)viewDidLoad { //Start Camera: [self.scanView startCamera]; - [self startListeningForMotion]; +// [self startListeningForMotion]; self.controllerType = ALScanHistoryScrabble; } @@ -84,7 +84,7 @@ -(void)viewDidAppear:(BOOL)animated { // We use this subroutine to start Anyline. The reason it has its own subroutine is // so that we can later use it to restart the scanning process. - [self startAnyline]; +// [self startAnyline]; } /* @@ -93,7 +93,7 @@ -(void)viewDidAppear:(BOOL)animated { - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - [self.scrabbleScanViewPlugin stopAndReturnError:nil]; +// [self.scrabbleScanViewPlugin stopAndReturnError:nil]; } /* @@ -103,62 +103,62 @@ is found scanning will stop automatically (you can change this behaviour with cancelOnResult:). When the user dismisses self.identificationView this method will get called again. */ -- (void)startAnyline { - [self startPlugin:self.scrabbleScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} - -- (void)stopAnyline { - if (self.scrabbleScanPlugin.isRunning) { - [self.scrabbleScanViewPlugin stopAndReturnError:nil]; - } -} +//- (void)startAnyline { +// [self startPlugin:self.scrabbleScanViewPlugin]; +// self.startTime = CACurrentMediaTime(); +//} +// +//- (void)stopAnyline { +// if (self.scrabbleScanPlugin.isRunning) { +// [self.scrabbleScanViewPlugin stopAndReturnError:nil]; +// } +//} -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} +//- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { +// //Update Position of Warning Indicator +// [self updateWarningPosition: +// cutoutRect.origin.y + +// cutoutRect.size.height + +// self.scanView.frame.origin.y + +// 80]; +//} #pragma mark -- AnylineOCRModuleDelegate /* This is the main delegate method Anyline uses to report its results */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { - //TODO: (RNR) convert this result to the json string so we have the same types across the scanmodes - [self anylineDidFindResult:result.result barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.scrabbleScanViewPlugin completion:^{ - [self stopAnyline]; - ALScrabbleViewController *vc = [[ALScrabbleViewController alloc] init]; - [vc setResult:result.result]; - [self.navigationController pushViewController:vc animated:YES]; - }]; -} +//- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { +// //TODO: (RNR) convert this result to the json string so we have the same types across the scanmodes +// [self anylineDidFindResult:result.result barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.scrabbleScanViewPlugin completion:^{ +// [self stopAnyline]; +// ALScrabbleViewController *vc = [[ALScrabbleViewController alloc] init]; +// [vc setResult:result.result]; +// [self.navigationController pushViewController:vc animated:YES]; +// }]; +//} -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.scrabbleScanViewPlugin]; - } - -} +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ +// if ([info.variableName isEqualToString:@"$brightness"]) { +// [self updateBrightness:[info.value floatValue] forModule:self.scrabbleScanViewPlugin]; +// } +// +//} -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin runSkipped:(ALRunSkippedReason *)runSkippedReason { - switch (runSkippedReason.reason) { - case ALRunFailureResultNotValid: - break; - case ALRunFailureConfidenceNotReached: - break; - case ALRunFailureNoLinesFound: - break; - case ALRunFailureNoTextFound: - break; - case ALRunFailureUnknown: - break; - default: - break; - } -} +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin runSkipped:(ALRunSkippedReason *)runSkippedReason { +// switch (runSkippedReason.reason) { +// case ALRunFailureResultNotValid: +// break; +// case ALRunFailureConfidenceNotReached: +// break; +// case ALRunFailureNoLinesFound: +// break; +// case ALRunFailureNoTextFound: +// break; +// case ALRunFailureUnknown: +// break; +// default: +// break; +// } +//} @end diff --git a/AnylineExamples/Anyline Examples Source/Scrabble/scrabble_config.json b/AnylineExamples/Anyline Examples Source/Scrabble/scrabble_config.json index 7ab3718a1..5236bac45 100644 --- a/AnylineExamples/Anyline Examples Source/Scrabble/scrabble_config.json +++ b/AnylineExamples/Anyline Examples Source/Scrabble/scrabble_config.json @@ -12,10 +12,10 @@ }, "strokeWidth": 2, "cornerRadius": 4, - "strokeColor": "FFFFFF", + "strokeColor": "0099FF", "outerColor": "000000", "outerAlpha": 0.3, - "feedbackStrokeColor": "660099FF" + "feedbackStrokeColor": "0099FF" }, "scanFeedback" : { "style": "CONTOUR_POINT", diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALLeftCheckmarkCell.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALLeftCheckmarkCell.swift new file mode 100644 index 000000000..ee3eabaa7 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALLeftCheckmarkCell.swift @@ -0,0 +1,40 @@ +// +// ALLeftCheckmarkCell.swift +// AnylineExamples +// +// Created by Angela Brett on 15.07.20. +// + +import UIKit + +// alas, there is not standard way of having a checkmark on the left, even though it's done in settings, so we fake it with an image view showing our own checkmark +class ALLeftCheckmarkCell : UITableViewCell { + + public var rowWasChecked: (UITableViewCell) -> () = { _ in } + + lazy private var tapGestureRecognizer:UITapGestureRecognizer = { + let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(checkMe(tapGestureRecognizer:))) + //without this line, we don't get the action + gestureRecognizer.cancelsTouchesInView = false + return gestureRecognizer + }() + + var isChecked:Bool = false { + didSet { + imageView?.tintColor = self.tintColor + imageView?.image = UIImage.init(named: isChecked ? "ic_done_white_48pt" : "unchecked")?.withRenderingMode(.alwaysTemplate) + if (!isChecked) { + imageView?.isUserInteractionEnabled = true + imageView?.addGestureRecognizer(tapGestureRecognizer) + } else { + imageView?.removeGestureRecognizer(tapGestureRecognizer) + imageView?.isUserInteractionEnabled = false + } + } + } + + @objc func checkMe(tapGestureRecognizer: UITapGestureRecognizer) { + self.isChecked = true + rowWasChecked(self) + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALRatioTableViewCell.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALRatioTableViewCell.swift new file mode 100644 index 000000000..91d4955ea --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALRatioTableViewCell.swift @@ -0,0 +1,230 @@ +// +// ALRatioTableViewCell.swift +// AnylineExamples +// +// Created by Angela Brett on 31.07.20. +// + +import Foundation + +class ALRatioTableViewCell : UITableViewCell, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate { + + let spacing:CGFloat = 8 //we could change this to use equalToSystemSpacingBelow: etc if we change the target to iOS 11 + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + let margin:CGFloat = 10 + let spacingAroundColon:CGFloat = 20 + contentView.addSubview(titleLabel) + contentView.addSubview(firstTermLabel) + contentView.addSubview(firstTermValue) + contentView.addSubview(colonLabel) + contentView.addSubview(secondTermLabel) + contentView.addSubview(secondTermValue) + NSLayoutConstraint.activate([ + titleLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor, constant: 0), + titleLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor, constant: margin), + titleLabel.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor, constant:-margin), + colonLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), + colonLabel.centerYAnchor.constraint(equalTo: firstTermLabel.bottomAnchor), + firstTermLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: spacing), + firstTermLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor), + firstTermLabel.trailingAnchor.constraint(equalTo: colonLabel.leadingAnchor, constant: -spacingAroundColon), + secondTermLabel.leadingAnchor.constraint(equalTo:colonLabel.trailingAnchor, constant: spacingAroundColon), + //secondTermLabel.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor), + secondTermLabel.topAnchor.constraint(equalTo: firstTermLabel.topAnchor), + firstTermValue.topAnchor.constraint(equalTo: firstTermLabel.bottomAnchor, constant: spacing), + firstTermValue.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -spacing), + firstTermValue.leadingAnchor.constraint(equalTo:firstTermLabel.leadingAnchor), + firstTermValue.trailingAnchor.constraint(equalTo: firstTermLabel.trailingAnchor), + secondTermValue.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -spacing), + secondTermValue.leadingAnchor.constraint(equalTo: secondTermLabel.leadingAnchor) + //secondTermValue.trailingAnchor.constraint(equalTo: secondTermLabel.trailingAnchor) + ]) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + var title:String? = nil { + didSet { + titleLabel.text = title + pickerLabel.text = title + } + } + + var firstTermTitle:String? = nil { + didSet { + firstTermLabel.text = firstTermTitle + } + } + + var secondTermTitle:String? = nil { + didSet { + secondTermLabel.text = secondTermTitle + } + } + + var minimumValue:Int = 0 + var maximumValue:Int = 10 + + var value:Int { + set { + secondTermValue.text = "\(newValue.clamped(to: (minimumValue...maximumValue)))" + } + get { + return Int(secondTermValue.text ?? "0")?.clamped(to: (minimumValue...maximumValue)) ?? minimumValue + } + } + + // MARK: Reusing Cells + + override func prepareForReuse() { + super.prepareForReuse() + } + + func label() -> UILabel { + let label = UILabel(frame: .zero) + label.translatesAutoresizingMaskIntoConstraints = false + return label + } + + lazy private var firstTermLabel: UILabel = { + return label() + }() + + //this could be turned into a text field if we decide we need that to be editable + lazy private var firstTermValue: UILabel = { + let firstValue = label() + firstValue.text = "1" + firstValue.isEnabled = false; //this part of the ratio is not editable + return firstValue + }() + + lazy private var secondTermLabel: UILabel = { + return label() + }() + + lazy private var pickerLabel:UILabel = { + let pickerLabel: UILabel = UILabel.init(frame: .zero) + pickerLabel.text = self.title + pickerLabel.sizeToFit() + pickerLabel.textAlignment = .center + return pickerLabel + }() + + lazy private var termPicker: UIPickerView = { + let picker = UIPickerView() + picker.dataSource = self + picker.delegate = self + picker.addSubview(pickerLabel) + pickerLabel.topAnchor.constraint(equalTo: picker.topAnchor, constant: spacing).isActive = true + pickerLabel.leadingAnchor.constraint(equalTo: picker.leadingAnchor).isActive = true + pickerLabel.trailingAnchor.constraint(equalTo: picker.trailingAnchor).isActive = true + pickerLabel.translatesAutoresizingMaskIntoConstraints = false + return picker + }() + + lazy private var secondTermValue: UITextField = { + let textField = UITextField(frame: .zero) + textField.translatesAutoresizingMaskIntoConstraints = false + textField.inputView = termPicker + textField.delegate = self + return textField + }() + + lazy private var colonLabel: UILabel = { + let colonLabel = label() + colonLabel.text = ":" + return colonLabel + }() + + lazy private var titleLabel: UILabel = { + return label() + }() + + // MARK: Handling Text Input + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + secondTermValue.becomeFirstResponder() + secondTermValue.selectedTextRange = nil + } + + public var valueDidChange: (Int) -> () = { _ in } + + @objc private func textDidChange() { + if let text = secondTermValue.text, !text.isEmpty { + secondTermValue.text = "\(value)" //show the clamped value + valueDidChange(value) + } + } + + //MARK: UIPickerView + func numberOfComponents(in pickerView: UIPickerView) -> Int { + return 1 + } + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + return maximumValue + } + + func titleForRow(_ row:Int) -> String { + return "1:\(row+1)" + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + return titleForRow(row) + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + secondTermValue.text = "\(row+1)" + secondTermValue.selectedTextRange = nil + //secondTermValue.endEditing(true) //this is probably too soon to dismiss the picker. We will do it when they save instead. + valueDidChange(value) + } + + //MARK: Dismissing Picker on tap + + //a little bit hacky, but we need the enclosing table view so that we can dismiss the picker when they tap elsewhere on it. + var tableView: UITableView? { + return parentView(of: UITableView.self) + } + + lazy private var tapGestureRecognizer : UIGestureRecognizer = { + let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture)) + tap.cancelsTouchesInView = false + return tap; + }() + + @objc func handleTapGesture(sender: AnyObject) + { + //if they tapped outside of either the picker or this cell, dismiss the picker + //taps anywhere on this cell don't dismiss it because we already show the picker whenever they tap anywhere on the cell, so it would be inconsistent + let subview = tableView?.hitTest(sender.location(in: tableView), with: nil) + + if(!(subview?.isDescendant(of: termPicker) ?? false || subview?.isDescendant(of: self) ?? false)) + { + secondTermValue.endEditing(true) + } + } + + //only have the tap gesture recognizer on while the picker is shown + //(we would have to add/remove it on didMove/willMoveToSuperview otherwise, so this is not any extra code) + func textFieldDidBeginEditing(_ textField: UITextField) { + self.tableView?.addGestureRecognizer(self.tapGestureRecognizer) + } + + func textFieldDidEndEditing(_ textField: UITextField) { + self.tableView?.removeGestureRecognizer(self.tapGestureRecognizer) + } +} + +extension UIView { + func parentView(of type: T.Type) -> T? { + guard let view = superview else { + return nil + } + return (view as? T) ?? view.parentView(of: T.self) + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALSliderTableViewCell.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALSliderTableViewCell.swift new file mode 100644 index 000000000..d02ca4a64 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALSliderTableViewCell.swift @@ -0,0 +1,137 @@ +// +// ALSliderTableViewCell.swift +// AnylineExamples +// +// Created by Angela Brett on 22.07.20. +// + +import Foundation + +final class ALSliderTableViewCell: UITableViewCell { + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + let spacing:CGFloat = 8 //we could change this to use equalToSystemSpacingBelow: etc if we change the target to iOS 11 + let margin:CGFloat = 10 //this can't be too close to the edge, because moving the finger from the edge of the screen is also the 'go back' gesture, and we don't want to do that accidentally. + contentView.addSubview(slider) + contentView.addSubview(titleLabel) + contentView.addSubview(currentValueLabel) + NSLayoutConstraint.activate([ + titleLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor, constant: 0), + titleLabel.bottomAnchor.constraint(equalTo: slider.topAnchor, constant: -spacing), + titleLabel.leadingAnchor.constraint(equalTo: slider.leadingAnchor), + currentValueLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor, constant: 0), + currentValueLabel.bottomAnchor.constraint(equalTo: slider.topAnchor, constant: -spacing), + currentValueLabel.trailingAnchor.constraint(equalTo: slider.trailingAnchor, constant: -spacing), + slider.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -spacing), + slider.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor, constant: margin), + slider.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor, constant:-margin) + ]) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + var title:String? = nil { + didSet { + titleLabel.text = title + } + } + + var minimumValue:Float = 100 { + didSet { + slider.minimumValue = minimumValue + } + } + + var maximumValue:Float = 0 { + didSet { + slider.maximumValue = maximumValue + } + } + + //this will be called whenever the value changes + var sliderValueDidChange:((ALSliderTableViewCell)->())? = nil + + var value:Float { + set { + slider.value = newValue + updateValueDisplay() + } + get { + return slider.value + } + } + + var isPercentage:Bool = true { + didSet { + //numberFormatter.numberStyle = isPercentage ? .percent : .none + numberFormatter.positiveSuffix = isPercentage ? "%" : "" + if (isPercentage) { + minimumValue = 0 + maximumValue = 100 + } + updateValueDisplay() + } + } + + var minimumValueImage:UIImage? = nil { + didSet { + slider.minimumValueImage = minimumValueImage + } + } + + var maximumValueImage:UIImage? = nil { + didSet { + slider.maximumValueImage = maximumValueImage + } + } + + private lazy var numberFormatter:NumberFormatter = { + let formatter = NumberFormatter() + formatter.maximumFractionDigits = 0 + formatter.minimumIntegerDigits = 1 + return formatter + }() + + private func updateValueDisplay() { + currentValueLabel.text = numberFormatter.string(from: NSNumber(value: slider.value)) + } + + // MARK: Reusing Cells + + override func prepareForReuse() { + super.prepareForReuse() + } + + lazy private var slider: UISlider = { + let slider = UISlider(frame: .zero) + slider.translatesAutoresizingMaskIntoConstraints = false + slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged) + return slider + }() + + lazy private var currentValueLabel: UILabel = { + let label = UILabel(frame: .zero) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + lazy private var titleLabel: UILabel = { + let label = UILabel(frame: .zero) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + // MARK: Handling Slider Input + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + slider.becomeFirstResponder() + } + + @objc func sliderValueChanged() { + updateValueDisplay() + sliderValueDidChange?(self) + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALTextInputTableViewCell.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALTextInputTableViewCell.swift new file mode 100644 index 000000000..704e9226a --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALTextInputTableViewCell.swift @@ -0,0 +1,81 @@ +// +// ALTextInputTableViewCell.swift +// AnylineExamples +// +// Created by Angela Brett on 22.07.20. +// + +import UIKit + +final class ALTextInputTableViewCell: UITableViewCell { + + public var placeholder:String? { + didSet { + editableTextField.placeholder = placeholder + } + } + + public var capitalsOnly = true { + didSet { + setCapitalization() + } + } + + public var value:String? { + get { + return editableTextField.text + } + set { + editableTextField.text = newValue + } + } + + private func setCapitalization() { + editableTextField.autocapitalizationType = capitalsOnly ? .allCharacters : .none + } + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + //self.backgroundColor = .clear + contentView.addSubview(editableTextField) + NSLayoutConstraint.activate([ + editableTextField.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + editableTextField.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor), + editableTextField.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor), + ]) + setCapitalization() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Reusing Cells + + override func prepareForReuse() { + super.prepareForReuse() + } + + lazy private var editableTextField: UITextField = { + let textField = UITextField(frame: .zero) + textField.translatesAutoresizingMaskIntoConstraints = false + textField.keyboardType = .alphabet + textField.autocorrectionType = .no + textField.addTarget(self, action: #selector(Self.textDidChange), for: .editingChanged) + //dismiss the keyboard when they press return + textField.addTarget(textField, action: #selector(resignFirstResponder), for: .editingDidEndOnExit) + return textField + }() + + // MARK: Handling Text Input + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + editableTextField.becomeFirstResponder() + } + + public var valueDidChange: (String) -> () = { _ in } + + @objc private func textDidChange() { + valueDidChange(value ?? "") + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALUnselectableLinkableTextView.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALUnselectableLinkableTextView.swift new file mode 100644 index 000000000..d8d365cf9 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ALUnselectableLinkableTextView.swift @@ -0,0 +1,12 @@ +// +// ALUnselectableLinkableTextView.swift +// AnylineExamples +// +// Created by Angela Brett on 13.10.20. +// + +import UIKit + +class ALUnselectableLinkableTextView : UITextView { + +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/AdvancedSettingsViewController.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/AdvancedSettingsViewController.swift new file mode 100644 index 000000000..48d042302 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/AdvancedSettingsViewController.swift @@ -0,0 +1,164 @@ +// +// AdvancedSettingsViewController.swift +// AnylineExamples +// +// Created by Angela Brett on 15.07.20. +// + +import UIKit + +class AdvancedSettingsViewController: BaseSettingsViewController { + static let textCellReuseIdentifier = "AdvancedSettingsTextCellIdentifier" + + var regex = SerialNumberSettings.shared.regex + var allowlist = SerialNumberSettings.shared.allowlist + + var isRegularExpressionValid = true { + didSet { + //update the footer below the regex text box to show that there's an error + UIView.setAnimationsEnabled(false) + tableView.beginUpdates() + + if let footer = footerView(section: Section.regex), let textLabel = footer.textLabel { + textLabel.text = regexFooterText() + //set to red if the regex is invalid, otherwise the text colour of the header + //this is the easiest way to get the standard text colour in both dark and light mode, since UIColor.label etc. are not available in all iOS versions + let invalidRegexColor = UIColor.systemRed + if let headerText = headerView(section: Section.regex)?.textLabel { + textLabel.textColor = isRegularExpressionValid ? headerText.textColor : invalidRegexColor + } + footer.sizeToFit() + } + + tableView.endUpdates() + UIView.setAnimationsEnabled(true) + } + } + + enum Section : Int, CaseIterable { + //we might decide to bring back allowlist in the future + case regex/*,allowlist*/,reset + static func getSection(_ section: Int) -> Section { + return self.allCases[section] + } + } + + override func viewDidLoad() { + super.viewDidLoad() + addSaveButton() + tableView.register(ALTextInputTableViewCell.self, forCellReuseIdentifier: Self.textCellReuseIdentifier) + self.title = "Advanced character settings" + } + + func footerView(section:Section) -> UITableViewHeaderFooterView? { + return tableView.footerView(forSection: section.rawValue) + } + + func headerView(section:Section) -> UITableViewHeaderFooterView? { + return tableView.headerView(forSection: section.rawValue) + } + + // MARK: - Table view data source + + override func numberOfSections(in tableView: UITableView) -> Int { + return Section.allCases.count + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + var cell = tableView.dequeueReusableCell(withIdentifier: Self.textCellReuseIdentifier, for: indexPath) + if let textInputCell = cell as? ALTextInputTableViewCell { + switch Section.getSection(indexPath.section) { + case .regex: + textInputCell.placeholder = "Type in your desired regular expression" + textInputCell.capitalsOnly = false //they won't want to match any literal lowercase characters, but might need to use shorthands such as \d + textInputCell.valueDidChange = { + value in + let regex = try? NSRegularExpression(pattern: value) + if (regex != nil) != self.isRegularExpressionValid { + self.isRegularExpressionValid = regex != nil + } + if self.isRegularExpressionValid { + self.regex = value + self.settingsDidChange() + } + } + textInputCell.value = regex + //we might bring this back in future + /*case .allowlist: + textInputCell.placeholder = "Type in your allowed characters list" + textInputCell.value = allowlist + textInputCell.valueDidChange = { value in + self.allowlist = value + self.settingsDidChange() + }*/ + case .reset: + cell = UITableViewCell() + cell.textLabel?.text = "Reset advanced settings to default" + setUpResetCell(cell) + } + } + return cell + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch Section.getSection(section) { + case .regex: + return "Regex" + //we might bring this back in future + /*case .allowlist: + return "Character allow list"*/ + case .reset: + return resetSectionHeading + } + } + + func regexFooterText() -> String { + let example = "Example: [A-Z0-9]{4,}" + if isRegularExpressionValid { + return example + } else { + return "Use a valid regex format\n\(example)" + } + } + + override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { + switch Section.getSection(section) { + case .regex: + return regexFooterText() + //we might bring this back in future + /*case .allowlist: + return """ + • Numbers 0–9 + • Capital letters only + + Example: ABCDEFG01256789 + """*/ + case .reset: + return nil + } + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.section == Section.reset.rawValue { + resetSettings() + } + } + + override func reset() { + SerialNumberSettings.shared.resetAdvancedSettings() + regex = SerialNumberSettings.shared.regex + allowlist = SerialNumberSettings.shared.allowlist + tableView.reloadData() + } + + override func saveSettings() { + SerialNumberSettings.shared.characterSetting = .advanced(regularExpression: self.regex, allowlist: self.allowlist) + self.view.endEditing(true) + super.saveSettings() + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/BaseSettingsViewController.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/BaseSettingsViewController.swift new file mode 100644 index 000000000..8560fb9c6 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/BaseSettingsViewController.swift @@ -0,0 +1,86 @@ +// +// BaseSettingsViewController.swift +// AnylineExamples +// +// Created by Angela Brett on 24.07.20. +// + +import Foundation + +public class BaseSettingsViewController: UITableViewController { + + public let resetSectionHeading = "Reset Settings" + var saveButton:UIBarButtonItem? = nil + + public override func viewDidLoad() { + super.viewDidLoad() + } + + public func addSaveButton() { + saveButton = UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(saveSettings)) + saveButton?.isEnabled = false + self.navigationItem.setRightBarButton(saveButton, animated: false) + } + + func confirmReset(_ handler:((UIAlertAction)->())?) { + let alert = UIAlertController(title: "Are you sure you want to reset these values?", message: "You are about to reset to preset configuration values", preferredStyle: .alert) + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + alert.addAction(cancelAction) + let okAction = UIAlertAction(title: "Reset", style: .destructive, handler: handler) + alert.addAction(okAction) + present(alert, animated: true, completion: nil) + } + + @objc func resetSettings() { + confirmReset { (action) in + self.reset() + //reset saves the defaults it just set + self.saveButton?.isEnabled = false + } + } + + func askToSaveChanges() { + let alert = UIAlertController(title: "Apply new settings?", message: "You have unsaved changes; do you want to apply them?", preferredStyle: .alert) + let discardChangesAction = UIAlertAction(title: "Discard", style: .destructive, handler: nil) + alert.addAction(discardChangesAction) + let applyChangesAction = UIAlertAction(title: "Apply", style: .default, handler: { alertAction in + self.saveSettings() + }) + alert.addAction(applyChangesAction) + present(alert, animated: true, completion: nil) + } + + public func setChecked(for cell:UITableViewCell?, to:Bool) { + cell?.accessoryType = to ? .checkmark : .none + } + + func setUpResetCell(_ cell:UITableViewCell) { + cell.textLabel?.textColor = UIColor.systemRed + cell.selectionStyle = .none + } + + + //override this in subclasses to save the settings on each specific screen. Call super once the settings are saved. + @objc func saveSettings () { + saveButton?.isEnabled = false + } + + func settingsDidChange() { + saveButton?.isEnabled = true + } + + func reset() { + //override this in subclasses to reset the settings on each specific screen + } + + //ask if they want to save changes if they attempt to go back while they have unsaved changes. + //this is a bit nicer than doing it on viewWillDisappear, because the view is still in the view hierarchy so we can present the UIAlert ourselves instead of on UIApplication.shared.keyWindow?.rootViewController? + //in both cases, we move to the parent view before the alert is dismissed, which might not be ideal UI, but at least doing it this way we could potentially block until the alert is dismissed by using a semaphore or something + public override func willMove(toParent parent: UIViewController?) { + if parent == nil { + if let saveButton = saveButton, saveButton.isEnabled { + askToSaveChanges() + } + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/BasicSettingsViewController.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/BasicSettingsViewController.swift new file mode 100644 index 000000000..add818141 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/BasicSettingsViewController.swift @@ -0,0 +1,199 @@ +// +// BasicSettingsViewController.swift +// AnylineExamples +// +// Created by Angela Brett on 15.07.20. +// + +import UIKit + +class BasicSettingsViewController: BaseSettingsViewController { + static let cellReuseIdentifier = "BasicSettingsPlainCellIdentifier" + static let textCellReuseIdentifier = "BasicSettingsTextCellIdentifier" + static let sliderCellReuseIdentifier = "BasicSettingsSliderCellIdentifier" + + enum Section : Int, CaseIterable { + case numberOfCharacters,include,excludedCharacters,reset + static func getSection(_ section: Int) -> Section { + return self.allCases[section] + } + } + + enum NumberOfCharactersSetting : Int, CaseIterable { + case minimum,maximum + static func getSetting(_ section: Int) -> NumberOfCharactersSetting { + return self.allCases[section] + } + } + + var selectedIncludeSetting = SerialNumberSettings.shared.includeSetting + var minCharacters = SerialNumberSettings.shared.minCharacters + var maxCharacters = SerialNumberSettings.shared.maxCharacters + var excludedCharacters = SerialNumberSettings.shared.excludedCharacters + + + override func viewDidLoad() { + super.viewDidLoad() + addSaveButton() + tableView.register(UITableViewCell.self, forCellReuseIdentifier: Self.cellReuseIdentifier) + tableView.register(ALTextInputTableViewCell.self, forCellReuseIdentifier: Self.textCellReuseIdentifier) + tableView.register(ALSliderTableViewCell.self, forCellReuseIdentifier: Self.sliderCellReuseIdentifier) + self.title = "Basic character settings" + } + + // MARK: - Table view data source + + override func numberOfSections(in tableView: UITableView) -> Int { + return Section.allCases.count + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch Section.getSection(section) { + case .numberOfCharacters: + return NumberOfCharactersSetting.allCases.count + case .include: + return IncludeSetting.allCases.count + case .excludedCharacters: + return 1 + case .reset: + return 1 + } + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch Section.getSection(section) { + case .numberOfCharacters: + return "Number of characters" + case .include: + return "Include" + case .excludedCharacters: + return "Exclude characters" + case .reset: + return resetSectionHeading + } + } + + override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { + if section == Section.excludedCharacters.rawValue { + return """ +• Numbers 0–9 +• Capital letters only +""" + } + return nil + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell:UITableViewCell = { + switch Section.getSection(indexPath.section) { + case .numberOfCharacters: + let cell = tableView.dequeueReusableCell(withIdentifier: Self.sliderCellReuseIdentifier, for: indexPath) + if let sliderCell = cell as? ALSliderTableViewCell { + sliderCell.maximumValue = 20 + sliderCell.minimumValue = 4 + sliderCell.isPercentage = false + switch NumberOfCharactersSetting.getSetting(indexPath.row) { + case .minimum: + sliderCell.title = "Minimum" + sliderCell.sliderValueDidChange = { + cell in + self.minCharacters = UInt(lroundf(cell.value)) + let maximumPath = IndexPath(row: NumberOfCharactersSetting.maximum.rawValue, section: indexPath.section) + if let maximumCell = tableView.cellForRow(at: maximumPath) as? ALSliderTableViewCell { + if maximumCell.value < cell.value { + maximumCell.value = cell.value + } + } + self.settingsDidChange() + } + sliderCell.value = Float(minCharacters) + sliderCell.isPercentage = false + case .maximum: + sliderCell.title = "Maximum" + sliderCell.sliderValueDidChange = { + cell in + self.maxCharacters = UInt(lroundf(cell.value)) + let minimumPath = IndexPath(row: NumberOfCharactersSetting.minimum.rawValue, section: indexPath.section) + if let minimumCell = tableView.cellForRow(at: minimumPath) as? ALSliderTableViewCell { + if minimumCell.value > cell.value { + minimumCell.value = cell.value + } + } + self.settingsDidChange() + } + sliderCell.value = Float(maxCharacters) + } + } + return cell + case .include: + let includeSetting = IncludeSetting.getSetting(indexPath.row) + let cell = tableView.dequeueReusableCell(withIdentifier: Self.cellReuseIdentifier, for: indexPath) + switch includeSetting { + case .numbersAndCapitals: + cell.textLabel?.text = "Numbers and capital letters" + case .numbersOnly: + cell.textLabel?.text = "Numbers only" + case .capitalsOnly: + cell.textLabel?.text = "Capital letters only" + } + setChecked(for: cell, to: (includeSetting == selectedIncludeSetting)) + return cell + case .excludedCharacters: + let cell = tableView.dequeueReusableCell(withIdentifier: Self.textCellReuseIdentifier, for: indexPath) + (cell as? ALTextInputTableViewCell)?.placeholder = "Type in your excluded characters list" + (cell as? ALTextInputTableViewCell)?.value = excludedCharacters + (cell as? ALTextInputTableViewCell)?.valueDidChange = { value in + self.excludedCharacters = value + self.settingsDidChange() + } + return cell + case .reset: + let cell = tableView.dequeueReusableCell(withIdentifier: Self.cellReuseIdentifier, for: indexPath) + cell.textLabel?.text = "Reset basic settings to default" + setUpResetCell(cell) + return cell + } + }() + cell.selectionStyle = .none + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + switch Section.getSection(indexPath.section) { + case .numberOfCharacters: + break + case .include: + let newSetting = IncludeSetting.getSetting(indexPath.row) + if newSetting != selectedIncludeSetting { + let oldSelectedCell = tableView.cellForRow(at: IndexPath(row: selectedIncludeSetting.rawValue, section: indexPath.section)) + setChecked(for: oldSelectedCell, to: false) + selectedIncludeSetting = newSetting + setChecked(for: tableView.cellForRow(at: indexPath), to:true) + self.settingsDidChange() + } + case .excludedCharacters: + break + case .reset: + resetSettings() + } + } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return UITableView.automaticDimension + } + + override func reset() { + SerialNumberSettings.shared.resetBasicSettings() + selectedIncludeSetting = SerialNumberSettings.shared.includeSetting + minCharacters = SerialNumberSettings.shared.minCharacters + maxCharacters = SerialNumberSettings.shared.maxCharacters + excludedCharacters = SerialNumberSettings.shared.excludedCharacters + tableView.reloadData() + } + + override func saveSettings() { + SerialNumberSettings.shared.characterSetting = .basic(minCharacters: self.minCharacters, maxCharacters: self.maxCharacters, includeSetting: self.selectedIncludeSetting, excludedCharacters: self.excludedCharacters) + self.view.endEditing(true) + super.saveSettings() + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/CutoutSettings.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/CutoutSettings.swift new file mode 100644 index 000000000..d53fb375b --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/CutoutSettings.swift @@ -0,0 +1,95 @@ +import Foundation +import Anyline + +enum VerticalAlignment : Int, CaseIterable { + static var alignmentStringArray = ["top_half", "center", "bottom_half"] + case top,center,bottom + static func getRow(_ row: Int) -> VerticalAlignment { + return self.allCases[row] + } +} + +@objc class CutoutSettings : NSObject { + + @objc static let shared = CutoutSettings() + + static let kcornerRadiusKey = "cornerRadius" + static let kMaxWidthPercentKey = "maxWidthPercent" + static let kRatioFromSizeKey = "ratioFromSize" + static let kAlignmentKey = "alignment" + static let maxCornerRadius = 100 //in case we change this to 50 + + override init() { + super.init() + UserDefaults.standard.register(defaults: [ + Self.kcornerRadiusKey : 4, + Self.kMaxWidthPercentKey : 67, + Self.kRatioFromSizeKey : 5, + Self.kAlignmentKey : VerticalAlignment.top.rawValue + ]) + } + + var cornerRadius:Int { + get { + UserDefaults.standard.integer(forKey: Self.kcornerRadiusKey ) + } + set { + UserDefaults.standard.set(newValue.clamped(to: 1...CutoutSettings.maxCornerRadius), forKey: Self.kcornerRadiusKey) + } + } + + var maxWidthPercent:Int { + get { + UserDefaults.standard.integer(forKey: Self.kMaxWidthPercentKey ) + } + set { + UserDefaults.standard.set(newValue.clamped(to: 1...100), forKey: Self.kMaxWidthPercentKey) + } + } + + var ratioFromSize:Int { + get { + UserDefaults.standard.integer(forKey: Self.kRatioFromSizeKey ) + } + set { + UserDefaults.standard.set(newValue.clamped(to: 1...10), forKey: Self.kRatioFromSizeKey) + } + } + + var alignment:VerticalAlignment { + get { + return VerticalAlignment(rawValue: UserDefaults.standard.integer(forKey:Self.kAlignmentKey)) ?? .center + } + set { + UserDefaults.standard.set(newValue.rawValue, forKey: Self.kAlignmentKey) + } + } + + func reset() { + //reset to default settings by removing any values we've set + let defaults = UserDefaults.standard + defaults.removeObject(forKey: Self.kcornerRadiusKey) + defaults.removeObject(forKey: Self.kMaxWidthPercentKey) + defaults.removeObject(forKey: Self.kRatioFromSizeKey) + defaults.removeObject(forKey: Self.kAlignmentKey) + } + + @objc func customizedCutoutConfig(from cutoutConfig: ALCutoutConfig) -> Dictionary { + var cutoutJSONNSString = cutoutConfig.asJSONString() as NSString + + var tempCutoutConfigDictionary = cutoutJSONNSString.asJSONObject() as? Dictionary ?? [:] + + tempCutoutConfigDictionary[CutoutSettings.kcornerRadiusKey] = cornerRadius + tempCutoutConfigDictionary[CutoutSettings.kMaxWidthPercentKey] = maxWidthPercent + tempCutoutConfigDictionary[CutoutSettings.kRatioFromSizeKey] = ["width" : ratioFromSize, "height" : "1"] + tempCutoutConfigDictionary[CutoutSettings.kAlignmentKey] = VerticalAlignment.alignmentStringArray[alignment.rawValue] + + return tempCutoutConfigDictionary; + } +} + +extension Comparable { + func clamped(to limits: ClosedRange) -> Self { + return min(max(self, limits.lowerBound), limits.upperBound) + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ScanAreaEditorViewController.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ScanAreaEditorViewController.swift new file mode 100644 index 000000000..b42051c44 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/ScanAreaEditorViewController.swift @@ -0,0 +1,167 @@ +import UIKit + +class ScanAreaEditorViewController: BaseSettingsViewController { + static let sliderCellReuseIdentifier = "ScanAreaSliderCellIdentifier" + static let cellReuseIdentifier = "ScanAreaPlainCellIdentifier" + static let ratioCellReuseIdentifier = "ScanAreaRatioCellIdentifier" + + enum ScanAreaSection : CaseIterable { + case sizes,verticalAlignment,reset + static func getSection(_ row: Int) -> ScanAreaSection { + return self.allCases[row] + } + } + + enum ScanAreaRow : CaseIterable { + case ratio,width/*,verticalAlignment*/,cornerRadius + static func getRow(_ row: Int) -> ScanAreaRow { + return self.allCases[row] + } + } + + var selectedVerticalAlignment = CutoutSettings.shared.alignment + var cornerRadius = CutoutSettings.shared.cornerRadius + var width = CutoutSettings.shared.maxWidthPercent + var ratio = CutoutSettings.shared.ratioFromSize + + override func viewDidLoad() { + super.viewDidLoad() + addSaveButton() + tableView.register(ALSliderTableViewCell.self, forCellReuseIdentifier: Self.sliderCellReuseIdentifier) + tableView.register(UITableViewCell.self, forCellReuseIdentifier: Self.cellReuseIdentifier) + tableView.register(ALRatioTableViewCell.self, forCellReuseIdentifier: Self.ratioCellReuseIdentifier) + self.title = "Scan area editor" + } + + override func numberOfSections(in tableView: UITableView) -> Int { + return ScanAreaSection.allCases.count + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch ScanAreaSection.getSection(section) { + case .sizes: + return ScanAreaRow.allCases.count + case .verticalAlignment: + return VerticalAlignment.allCases.count + case .reset: + return 1 + } + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch ScanAreaSection.getSection(section) { + case .sizes: + return "Shape" + case .verticalAlignment: + return "Vertical Center" + case .reset: + return resetSectionHeading + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + switch ScanAreaSection.getSection(indexPath.section) { + case .sizes: + var cell:UITableViewCell? = nil + switch ScanAreaRow.getRow(indexPath.row) { + case .width: + if let sliderCell = tableView.dequeueReusableCell(withIdentifier: Self.sliderCellReuseIdentifier, for: indexPath) as? ALSliderTableViewCell { + sliderCell.title = "Width" + sliderCell.isPercentage = true + sliderCell.value = Float(width) + sliderCell.sliderValueDidChange = { sliderCell in + self.width = lroundf(sliderCell.value) + self.settingsDidChange() + } + cell = sliderCell + } + case .ratio: + if let ratioCell = tableView.dequeueReusableCell(withIdentifier: Self.ratioCellReuseIdentifier, for: indexPath) as? ALRatioTableViewCell { + ratioCell.title = "Aspect Ratio" + ratioCell.firstTermTitle = "Height" + ratioCell.secondTermTitle = "Width" + ratioCell.minimumValue = 1 + ratioCell.maximumValue = 10 + ratioCell.value = ratio + ratioCell.valueDidChange = { value in + self.ratio = value + self.settingsDidChange() + } + cell = ratioCell + } + case .cornerRadius: + if let sliderCell = tableView.dequeueReusableCell(withIdentifier: Self.sliderCellReuseIdentifier, for: indexPath) as? ALSliderTableViewCell { + sliderCell.minimumValueImage = UIImage.init(named: "Rectangle") + sliderCell.maximumValueImage = UIImage.init(named: "Ellipse") + sliderCell.isPercentage = true + sliderCell.maximumValue = Float(CutoutSettings.maxCornerRadius) + sliderCell.value = Float(cornerRadius) + sliderCell.title = "Corner radius" + sliderCell.sliderValueDidChange = { sliderCell in + self.cornerRadius = lroundf(sliderCell.value) + self.settingsDidChange() + } + cell = sliderCell + } + } + return cell ?? UITableViewCell() + case .verticalAlignment: + let cell = tableView.dequeueReusableCell(withIdentifier: Self.cellReuseIdentifier, for: indexPath) + let alignmentSetting = VerticalAlignment.getRow(indexPath.row) + switch alignmentSetting { + case .top: + cell.textLabel?.text = "Top" + case .center: + cell.textLabel?.text = "Center" + case .bottom: + cell.textLabel?.text = "Bottom" + } + setChecked(for: cell, to: (alignmentSetting == selectedVerticalAlignment)) + cell.selectionStyle = .none + return cell + case .reset: + let cell = tableView.dequeueReusableCell(withIdentifier: Self.cellReuseIdentifier, for: indexPath) + cell.textLabel?.text = "Reset scan area settings to default" + setUpResetCell(cell) + return cell + } + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + switch ScanAreaSection.getSection(indexPath.section) { + case .sizes: + break //nothing to do here + case .verticalAlignment: + //todo: share this code with the basic settings view controller + let newSetting = VerticalAlignment.getRow(indexPath.row) + if newSetting != selectedVerticalAlignment { + let oldSelectedCell = tableView.cellForRow(at: IndexPath(row: selectedVerticalAlignment.rawValue, section: indexPath.section)) + setChecked(for: oldSelectedCell, to: false) + selectedVerticalAlignment = newSetting + setChecked(for: tableView.cellForRow(at: indexPath), to:true) + self.settingsDidChange() + } + case .reset: + resetSettings() + } + } + + override func reset() { + CutoutSettings.shared.reset() + selectedVerticalAlignment = CutoutSettings.shared.alignment + cornerRadius = CutoutSettings.shared.cornerRadius + width = CutoutSettings.shared.maxWidthPercent + ratio = CutoutSettings.shared.ratioFromSize + tableView.reloadData() + } + + //this is called when they use the 'Save' button. We don't save the settings before that, in case they want to go back to the previous screen and and revert + override func saveSettings() { + CutoutSettings.shared.alignment = selectedVerticalAlignment + CutoutSettings.shared.cornerRadius = cornerRadius + CutoutSettings.shared.ratioFromSize = ratio + CutoutSettings.shared.maxWidthPercent = width + self.view.endEditing(true) + super.saveSettings() + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/SerialNumberSettings.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/SerialNumberSettings.swift new file mode 100644 index 000000000..fc5756c20 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/SerialNumberSettings.swift @@ -0,0 +1,165 @@ +import Foundation +import Anyline + +//this needs to be removed from BasicSettingsViewController +enum IncludeSetting : Int, CaseIterable { + case numbersAndCapitals,numbersOnly,capitalsOnly + static func getSetting(_ section: Int) -> IncludeSetting { + return self.allCases[section] + } +} + +@objc class SerialNumberSettings : NSObject { + static let isUsingAdvancedCharacterSettingsKey = "isUsingAdvancedCharacterSettings" + static let advancedCharacterSettingsRegexKey = "AdvancedCharacterSettingsRegex" + static let advancedCharacterSettingsAllowlistKey = "AdvancedCharacterSettingsAllowlist" + static let basicCharacterSettingsMinimumCharactersKey = "basicCharacterSettingsMinimumCharacters" + static let basicCharacterSettingsMaximumCharactersKey = "basicCharacterSettingsMaximumCharacters" + static let basicCharacterSettingsIncludeSettingsKey = "basicCharacterSettingsIncludeSettings" + static let basicCharacterSettingsExcludedCharactersKey = "basicCharacterSettingsExcludedCharacters" + @objc static let shared = SerialNumberSettings() + + public enum CharacterSetting { + case basic(minCharacters:UInt,maxCharacters:UInt,includeSetting:IncludeSetting, excludedCharacters:String?) + case advanced(regularExpression:String?, allowlist:String?) + } + + override init() { + super.init() + UserDefaults.standard.register(defaults: [ + Self.isUsingAdvancedCharacterSettingsKey : false, + Self.advancedCharacterSettingsRegexKey : "[A-Z0-9]{4,}", + Self.basicCharacterSettingsMinimumCharactersKey : 4, + Self.basicCharacterSettingsMaximumCharactersKey : 20, + Self.basicCharacterSettingsIncludeSettingsKey : IncludeSetting.numbersAndCapitals.rawValue + ]) + } + + public var characterSetting:CharacterSetting { + set { + //set in userdefaults, unless it's an invalid advanced setting + //we don't touch the defaults stored for the setting they're not using, as they might want to switch between them. + let defaults = UserDefaults.standard + switch (newValue) { + case .basic(minCharacters: let minCharacters, maxCharacters: let maxCharacters, includeSetting: let includeSetting, excludedCharacters: let excludedCharacters): + defaults.set(false, forKey: Self.isUsingAdvancedCharacterSettingsKey) + defaults.set(minCharacters, forKey: Self.basicCharacterSettingsMinimumCharactersKey) + defaults.set(maxCharacters, forKey: Self.basicCharacterSettingsMaximumCharactersKey) + defaults.set(includeSetting.rawValue, forKey: Self.basicCharacterSettingsIncludeSettingsKey) + defaults.set(excludedCharacters, forKey: Self.basicCharacterSettingsExcludedCharactersKey) + case .advanced(regularExpression: let regularExpression, allowlist: let allowlist): + defaults.set(true, forKey: Self.isUsingAdvancedCharacterSettingsKey) + defaults.set(regularExpression, forKey: Self.advancedCharacterSettingsRegexKey) + defaults.set(allowlist, forKey: Self.advancedCharacterSettingsAllowlistKey) + } + + } + get { + //get from user defaults + if (self.isUsingAdvancedCharacterSettings) { + return CharacterSetting.advanced( + regularExpression:self.regex, + allowlist: self.allowlist + ) + } else { + return CharacterSetting.basic( + minCharacters: self.minCharacters, + maxCharacters: self.maxCharacters, + includeSetting: self.includeSetting, + excludedCharacters: self.excludedCharacters + ) + } + } + } + + /* We still save any basic and advanced settings that the user has set, even if they are only using one of them, so they can switch between them and not lose anything. So here you can directly access those settings. You should only use characterSetting to get the actual setting, but use these to populate the edit screens. */ + public var minCharacters:UInt { + get { + return UInt(UserDefaults.standard.integer(forKey: Self.basicCharacterSettingsMinimumCharactersKey)) + } + } + + public var maxCharacters:UInt { + get { + return UInt(UserDefaults.standard.integer(forKey: Self.basicCharacterSettingsMaximumCharactersKey)) + } + } + + public var includeSetting:IncludeSetting { + get { + return IncludeSetting(rawValue: UserDefaults.standard.integer(forKey:Self.basicCharacterSettingsIncludeSettingsKey)) ?? .numbersAndCapitals + } + } + + public var excludedCharacters:String? { + get { + return UserDefaults.standard.string(forKey: Self.basicCharacterSettingsExcludedCharactersKey) + } + } + + public var regex:String? { + get { + return UserDefaults.standard.string(forKey: Self.advancedCharacterSettingsRegexKey) + } + } + + public var allowlist:String? { + get { + return UserDefaults.standard.string(forKey: Self.advancedCharacterSettingsAllowlistKey) + } + } + + public var isUsingAdvancedCharacterSettings:Bool { + get { + return UserDefaults.standard.bool(forKey: Self.isUsingAdvancedCharacterSettingsKey) + } + set { + //this will use whatever the previously-saved (or default) settings are for the advanced or basic settings. Usually you would set characterSetting with the full configuration instead; this is for when the user switches between basic and advanced settings without editing them. + UserDefaults.standard.set(newValue, forKey: Self.isUsingAdvancedCharacterSettingsKey) + } + } + + func resetBasicSettings() { + let defaults = UserDefaults.standard + defaults.removeObject(forKey: Self.basicCharacterSettingsMinimumCharactersKey) + defaults.removeObject(forKey: Self.basicCharacterSettingsMaximumCharactersKey) + defaults.removeObject(forKey: Self.basicCharacterSettingsIncludeSettingsKey) + defaults.removeObject(forKey: Self.basicCharacterSettingsExcludedCharactersKey) + } + + func resetAdvancedSettings() { + UserDefaults.standard.removeObject(forKey: Self.advancedCharacterSettingsRegexKey) + UserDefaults.standard.removeObject(forKey: Self.advancedCharacterSettingsAllowlistKey) + } + + func reset() { + //reset to default settings by removing any values we've set + UserDefaults.standard.removeObject(forKey: Self.isUsingAdvancedCharacterSettingsKey) + resetAdvancedSettings() + resetBasicSettings() + } + + @objc public func toOCRConfig() -> ALOcrConfig { + let ocrConfig = ALOcrConfig() + ocrConfig.scanMode = .scanModeAuto() + switch characterSetting { + case .basic(minCharacters: let minCharacters, maxCharacters: let maxCharacters, includeSetting: let includeSetting, excludedCharacters: let excludedCharacters): + switch includeSetting { + case .numbersAndCapitals: + ocrConfig.charWhitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + ocrConfig.validationRegex = "[A-Z0-9]{\(minCharacters),\(maxCharacters)}" + case .numbersOnly: + ocrConfig.charWhitelist = "0123456789" + ocrConfig.validationRegex = "[0-9]{\(minCharacters),\(maxCharacters)}" + case .capitalsOnly: + ocrConfig.charWhitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + ocrConfig.validationRegex = "[A-Z]{\(minCharacters),\(maxCharacters)}" + } + ocrConfig.charWhitelist = ocrConfig.charWhitelist?.filter( { !(excludedCharacters?.contains($0) ?? false) }) + case .advanced(regularExpression: let regularExpression, allowlist: let allowlist): + ocrConfig.charWhitelist = allowlist + ocrConfig.validationRegex = regularExpression + } + return ocrConfig + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/SerialNumberSettingsViewController.swift b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/SerialNumberSettingsViewController.swift new file mode 100644 index 000000000..bc3832cc3 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/Settings/SerialNumberSettingsViewController.swift @@ -0,0 +1,125 @@ +// +// SerialNumberSettingsViewController.swift +// AnylineExamples +// +// Created by Angela Brett on 15.07.20. +// + +import UIKit + +class SerialNumberSettingsViewController: BaseSettingsViewController { + static let cellReuseIdentifier = "SerialNumberSettingsCellIdentifier" + static let checkmarkCellReuseIdentifier = "checkmarkCellReuseIdentifier" + enum Section : CaseIterable { + case scanAreaSettings,characterSettings,reset //it's not clear yet whether we want this separate reset button at the bottom, or the one in the navbar (which we can add with addResetButton()) + static func getSection(_ section: Int) -> Section { + return self.allCases[section] + } + } + + enum CharacterSetting : CaseIterable { + case basicSettings,advancedSettings + static func getRow(_ section: Int) -> CharacterSetting { + return self.allCases[section] + } + } + + override func viewDidLoad() { + super.viewDidLoad() + self.title = "Serial Number Settings" + tableView.register(UITableViewCell.self, forCellReuseIdentifier: Self.cellReuseIdentifier) + } + + func refreshCheckmarks() { + //we just need to reload the character settings section so the checkmark is shown in the right place, so if the table gets larger it might be quicker to just load specific rows here. + tableView.reloadData() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + refreshCheckmarks() + } + + override func numberOfSections(in tableView: UITableView) -> Int { + return Section.allCases.count + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch Section.getSection(section) { + case .scanAreaSettings: + return 1 + case .characterSettings: + return CharacterSetting.allCases.count + case .reset: + return 1 + } + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch Section.getSection(section) { + case .scanAreaSettings: + return "Scan area settings" + case .characterSettings: + return "Character settings" + case .reset: + return resetSectionHeading + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + var cell = tableView.dequeueReusableCell(withIdentifier: Self.cellReuseIdentifier, for: indexPath) + switch Section.getSection(indexPath.section) { + case .scanAreaSettings: + cell.accessoryType = .disclosureIndicator + cell.textLabel?.text = "Scan area editor" + case .characterSettings: + let checkmarkCell = ALLeftCheckmarkCell(style: .subtitle, reuseIdentifier: Self.checkmarkCellReuseIdentifier) + cell = checkmarkCell + cell.accessoryType = .disclosureIndicator + switch CharacterSetting.getRow(indexPath.row) { + case .basicSettings: + checkmarkCell.isChecked = !SerialNumberSettings.shared.isUsingAdvancedCharacterSettings + checkmarkCell.rowWasChecked = { _ in + SerialNumberSettings.shared.isUsingAdvancedCharacterSettings = false + self.refreshCheckmarks() + } + cell.textLabel?.text = "Basic character settings" + case .advancedSettings: + checkmarkCell.isChecked = SerialNumberSettings.shared.isUsingAdvancedCharacterSettings + checkmarkCell.rowWasChecked = { _ in + SerialNumberSettings.shared.isUsingAdvancedCharacterSettings = true + self.refreshCheckmarks() + } + cell.textLabel?.text = "Advanced character settings" + //cell.detailTextLabel?.text = "Regex & allow list" //we might put this back if we bring back the allow list + } + case .reset: + cell.textLabel?.text = "Reset all settings to default" + setUpResetCell(cell) + } + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + switch Section.getSection(indexPath.section) { + case .scanAreaSettings: + self.navigationController?.pushViewController(ScanAreaEditorViewController.init(style: .grouped), animated: true) + case .characterSettings: + switch CharacterSetting.getRow(indexPath.row) { + case .basicSettings: + self.navigationController?.pushViewController(BasicSettingsViewController.init(style: .grouped), animated: true) + case .advancedSettings: + self.navigationController?.pushViewController(AdvancedSettingsViewController.init(style: .grouped), animated: true) + } + case .reset: + resetSettings() + break + } + } + + override func reset () { + SerialNumberSettings.shared.reset() + CutoutSettings.shared.reset() + refreshCheckmarks() + } +} diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/ViewController/ALUniversalSerialNumberScanViewController.h b/AnylineExamples/Anyline Examples Source/SerialNumber/ViewController/ALUniversalSerialNumberScanViewController.h index 40eff409a..e993d3cd3 100644 --- a/AnylineExamples/Anyline Examples Source/SerialNumber/ViewController/ALUniversalSerialNumberScanViewController.h +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/ViewController/ALUniversalSerialNumberScanViewController.h @@ -7,9 +7,13 @@ // #import - +#import #import "ALBaseScanViewController.h" @interface ALUniversalSerialNumberScanViewController : ALBaseScanViewController +// The Anyline plugin used for OCR +@property (nonatomic, strong, nullable) ALScanViewPlugin *scanViewPlugin; +// @property (nullable, nonatomic, strong) ALScanView *scanView; + @end diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/ViewController/ALUniversalSerialNumberScanViewController.m b/AnylineExamples/Anyline Examples Source/SerialNumber/ViewController/ALUniversalSerialNumberScanViewController.m index e1b0aaad6..10ff955d9 100644 --- a/AnylineExamples/Anyline Examples Source/SerialNumber/ViewController/ALUniversalSerialNumberScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/ViewController/ALUniversalSerialNumberScanViewController.m @@ -1,25 +1,11 @@ -// -// ALUniversalSerialNumberScanViewController.m -// AnylineExamples -// -// Created by Philipp Mueller on 24/11/16. -// Copyright © 2016 Anyline GmbH. All rights reserved. -// - - #import "ALUniversalSerialNumberScanViewController.h" #import #import "ALBaseViewController.h" #import "NSUserDefaults+ALExamplesAdditions.h" #import "AnylineExamples-Swift.h" -// The controller has to conform to to be able to receive results -@interface ALUniversalSerialNumberScanViewController () - -// The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *serialNumberScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *serialNumberScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +NSString * const kUniversalSerailNumberScanVC_configJSONFilename = @"serial_number_view_config"; +@interface ALUniversalSerialNumberScanViewController () @end @@ -30,139 +16,102 @@ @implementation ALUniversalSerialNumberScanViewController */ - (void)viewDidLoad { [super viewDidLoad]; - - self.title = @"Universal Serial Number"; - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - ALOCRConfig *config = [self ocrConfig]; - - NSError *error = nil; - self.serialNumberScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.serialNumberScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.serialNumberScanPlugin addInfoDelegate:self]; - - ALScanViewPluginConfig *scanViewPluginConfig = [self scanViewPluginConfig]; - - self.serialNumberScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.serialNumberScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - NSAssert(self.serialNumberScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.serialNumberScanViewPlugin addScanViewPluginDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.serialNumberScanViewPlugin]; - - //Enable Zoom Gesture - [self.scanView enableZoomPinchGesture:YES]; + self.title = @"Universal Serial Number"; + self.controllerType = ALScanHistoryBarcode; - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Settings"] style:UIBarButtonItemStylePlain target:self action:@selector(showSettings:)]; + [self setColors]; + self.controllerType = ALScanHistorySerial; } -- (ALOCRConfig *)ocrConfig { - ALOCRConfig *config = [[ALOCRConfig alloc] init]; - - config.scanMode = ALAuto; - - config.validationRegex = @"[A-Z0-9]{4,}"; - return config; +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self reloadScanView]; + [self.scanViewPlugin startWithError:nil]; } -- (ALScanViewPluginConfig *)scanViewPluginConfig { - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"serial_number_view_config" ofType:@"json"]; - return [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [self.scanViewPlugin stop]; } -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; +- (void)reloadScanView { + ALScanViewPlugin *scanViewPlugin = [self.class scanViewPluginWithUpdatedSettings]; + scanViewPlugin.scanPlugin.delegate = self; + + self.scanViewPlugin = scanViewPlugin; + + if (!self.scanView) { + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:scanViewPlugin + error:nil]; + [self installScanView:self.scanView]; + + + } else { + [self.scanView setScanViewPlugin:scanViewPlugin error:nil]; + } + [self.scanView startCamera]; + [self.view bringSubviewToFront:self.scanView]; } -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.serialNumberScanViewPlugin stopAndReturnError:nil]; +// MARK: - Serial Settings + ++ (ALScanViewPluginConfig *)defaultScanViewPluginConfig { + NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:kUniversalSerailNumberScanVC_configJSONFilename + ofType:@"json"]; + NSString *configStr = [NSString stringWithContentsOfFile:jsonFilePath + encoding:NSUTF8StringEncoding + error:NULL]; + return [[ALScanViewPluginConfig alloc] initWithJSONDictionary:[configStr asJSONObject] error:nil]; } -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.serialNumberScanViewPlugin]; - self.startTime = CACurrentMediaTime(); ++ (ALScanViewPlugin *)scanViewPluginWithUpdatedSettings { + ALScanViewPluginConfig *scanViewPluginConfig = [self.class defaultScanViewPluginConfig]; + + ALPluginConfig *newPluginConfig = scanViewPluginConfig.scanPluginConfig.pluginConfig; + newPluginConfig.ocrConfig = [self.class ocrConfig]; + + ALScanPluginConfig *newScanPluginConfig = [[ALScanPluginConfig alloc] initWithPluginConfig:newPluginConfig]; + + NSDictionary *newCutoutConfigDictionary = [CutoutSettings.shared customizedCutoutConfigFrom:scanViewPluginConfig.cutoutConfig]; + ALCutoutConfig *newCutoutConfig = [[ALCutoutConfig alloc] initWithJSONDictionary:newCutoutConfigDictionary error:nil]; + + ALScanViewPluginConfig *newScanViewPluginConfig = [[ALScanViewPluginConfig alloc] initWithScanPluginConfig:newScanPluginConfig cutoutConfig:newCutoutConfig scanFeedbackConfig:scanViewPluginConfig.scanFeedbackConfig error:nil]; + + return [[ALScanViewPlugin alloc] initWithConfig:newScanViewPluginConfig error:nil]; +} + ++ (ALOcrConfig *)ocrConfig { + return [[SerialNumberSettings shared] toOCRConfig]; } -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; +- (IBAction)showSettings:(id)sender { + SerialNumberSettingsViewController *controller = [[SerialNumberSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped]; + [self.navigationController pushViewController:controller animated:YES]; } -#pragma mark -- AnylineOCRModuleDelegate +// MARK: - ALScanPluginDelegate -/* - This is the main delegate method Anyline uses to report its results - */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin - didFindResult:(ALOCRResult *)result { - // We are done. Cancel scanning - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Universal Serial Number" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + NSArray *resultData = scanResult.pluginResult.ocrResult.resultEntryList; + NSString *resultDataJSONStr = [ALResultEntry JSONStringFromList:resultData]; + __weak ALUniversalSerialNumberScanViewController *weakSelf = self; + [self anylineDidFindResult:resultDataJSONStr barcodeResult:@"" - image:result.image - scanPlugin:anylineOCRScanPlugin - viewPlugin:self.serialNumberScanViewPlugin + image:scanResult.croppedImage + scanPlugin:scanPlugin + viewPlugin:self.scanViewPlugin completion:^{ ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - + vc.imagePrimary = scanResult.croppedImage; + [weakSelf.navigationController pushViewController:vc animated:YES]; }]; } -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.serialNumberScanViewPlugin]; - } - -} - - @end diff --git a/AnylineExamples/Anyline Examples Source/SerialNumber/serial_number_view_config.json b/AnylineExamples/Anyline Examples Source/SerialNumber/serial_number_view_config.json index dffe8fdef..c05c9aa4a 100644 --- a/AnylineExamples/Anyline Examples Source/SerialNumber/serial_number_view_config.json +++ b/AnylineExamples/Anyline Examples Source/SerialNumber/serial_number_view_config.json @@ -1,33 +1,58 @@ { - "viewPlugin" : { - "cutoutConfig" : { - "style": "animated_rect", - "maxWidthPercent": "67%", - "width": 1080, + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_right" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.universal-serial-number", + "ocrConfig": { + "scanMode": "AUTO", + "model": "USNr.any" + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "80%", "alignment": "top_half", - "ratioFromSize" : { - "width": 720, - "height": 144 + "ratioFromSize": { + "width": 5, + "height": 1 + }, + "offset": { + "x": 0, + "y": 0 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "cropPadding": { + "x": 0, + "y": 0 }, - "strokeWidth": 3, - "strokeColor": "FFFFFF", "cornerRadius": 4, + "strokeColor": "0099ff", + "strokeWidth": 2, "outerColor": "000000", - "outerAlpha": 0.5, "feedbackStrokeColor": "0099FF", - "offset": { - "x": 0, - "y": -15 - } + "outerAlpha": 0.3 }, - "scanFeedback" : { - "style": "CONTOUR_RECT", - "strokeColor": "0099FF", + "scanFeedbackConfig": { + "style": "rect", + "strokeWidth": 2, "cornerRadius": 2, + "strokeColor": "0099FF", + "fillColor": "330099FF", "beepOnResult": true, "vibrateOnResult": true, - "blinkAnimationOnResult": true - }, - "cancelOnResult" : true + "blinkAnimationOnResult": false + } } } diff --git a/AnylineExamples/Anyline Examples Source/TIN/ViewController/ALTINScanViewController.m b/AnylineExamples/Anyline Examples Source/TIN/ViewController/ALTINScanViewController.m index 04cb38155..b5650a1a5 100644 --- a/AnylineExamples/Anyline Examples Source/TIN/ViewController/ALTINScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/TIN/ViewController/ALTINScanViewController.m @@ -1,26 +1,29 @@ -// -// ALTINScanViewController.m -// AnylineExamples -// -// Created by Angela Brett on 26.08.19. -// - #import "ALTINScanViewController.h" #import -#import "AnylineExamples-Swift.h" -#import "ALUmbrella.h" -#import "UIColor+ALExamplesAdditions.h" -#import "UIFont+ALExamplesAdditions.h" #import "ALConfigurationDialogViewController.h" +#import "AnylineExamples-Swift.h" // for ALResultEntry +#import "ALPluginResultHelper.h" + #if __has_include("ALContactUsViewController.h") -#import "ALContactUsViewController.h" + #import "ALContactUsViewController.h" #endif -@interface ALTINScanViewController () +typedef enum { + ALTINScanModeUniversal = 0, + ALTINScanModeDOT +} ALTINScanMode; + +NSString * const kALTINScanVC_configFilename = @"tire_config_tin"; + -@property (nonatomic, strong) ALTireScanViewPlugin *tinScanViewPlugin; -@property (nonatomic, strong) ALTireScanPlugin *tinScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +@interface ALTINScanViewController () + +// TODO: most of these can go to a superclass. +@property (nonatomic, strong) ALScanViewPlugin *scanViewPlugin; + +@property (nonatomic, strong) ALScanViewConfig *scanViewConfig; + +@property (nonatomic, readonly) NSDictionary *scanViewConfigDict; @property () NSUInteger dialogIndexSelected; @@ -29,145 +32,116 @@ @interface ALTINScanViewController () *resultData = scanResult.pluginResult.tinResult.resultEntryList; + ALResultViewController *vc = [[ALResultViewController alloc] + initWithResults:resultData]; + vc.imagePrimary = scanResult.croppedImage; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]; } +// MARK: - Allow changing the scan mode + - (void)showOptionsSelectionDialog { - NSArray *choices = @[ @"Universal TIN/DOT", @"TIN/DOT (North America only)", @"Other tire sidewall information" ]; + NSArray *choices = @[ + @"Universal TIN/DOT", + @"TIN/DOT (North America only)", + @"Other tire sidewall information" + ]; NSArray *selections = @[@(self.dialogIndexSelected)]; ALConfigurationDialogViewController *vc = [[ALConfigurationDialogViewController alloc] initWithChoices:choices @@ -178,89 +152,54 @@ - (void)showOptionsSelectionDialog { vc.delegate = self; [vc setSelectionDialogFontSize:16.0]; [self presentViewController:vc animated:YES completion:nil]; - [self dialogStarted]; -} - -- (void)dialogStarted { - [self startCamera:NO]; -} - -- (void)dialogCancelled { - [self startCamera:YES]; + [self.scanView stopCamera]; } -- (void)startCamera:(BOOL)start { - if (start) { - [self.scanView startCamera]; - } else { - [self.scanView stopCamera]; - } -} - -- (void)presentContactUsDialog { - ALTINScanViewController __weak *weakself = self; -#if __has_include("ALContactUsViewController.h") - [self dismissViewControllerAnimated:YES completion:^{ - ALContactUsViewController *contactVC = [[ALContactUsViewController alloc] init]; - [weakself presentViewController:contactVC animated:YES completion:nil]; - [contactVC setPresentationBlock:^{ - [weakself dialogCancelled]; - }]; - }]; -#endif -} - -// MARK: - ALTireScanPluginDelegate - -- (void)anylineTireScanPlugin:(ALTireScanPlugin * _Nonnull)anylineTireScanPlugin - didFindResult:(ALTireResult * _Nonnull)result { - - [self enableLandscapeOrientation:NO]; - - NSMutableArray *resultData = [NSMutableArray array]; - - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Tire Identification Number" - value:result.result - shouldSpellOutValue:YES]]; - - NSString *jsonString = [self jsonStringFromResultData:resultData]; - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" - image:result.image - scanPlugin:anylineTireScanPlugin - viewPlugin:self.tinScanViewPlugin - completion:^{ - ALResultViewController *vc = [[ALResultViewController alloc] - initWithResults:resultData]; - vc.imagePrimary = result.image; +// MARK: - ALConfigurationDialogViewControllerDelegate - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} +- (void)configDialogCommitted:(BOOL)commited dialog:(ALConfigurationDialogViewController *)dialog {} -// MARK: - ALConfigurationDialogViewControllerDelegate +- (void)configDialogCancelled:(ALConfigurationDialogViewController *)dialog {} - (void)configDialog:(ALConfigurationDialogViewController *)dialog selectedIndex:(NSUInteger)index { switch (index) { - case 0: //universal + case 0: self.dialogIndexSelected = index; - [self changeScanViewMode:ALTINUniversal]; + [self changeScanViewMode:ALTINScanModeUniversal]; [self dismissViewControllerAnimated:YES completion:nil]; break; - case 1: //standart + case 1: self.dialogIndexSelected = index; - [self changeScanViewMode:ALTINDot]; + [self changeScanViewMode:ALTINScanModeDOT]; [self dismissViewControllerAnimated:YES completion:nil]; break; - case 2: // popup + case 2: [self presentContactUsDialog]; break; } } -- (void)configDialogCommitted:(BOOL)commited dialog:(ALConfigurationDialogViewController *)dialog {} +// MARK: - Miscellaneous -- (void)configDialogCancelled:(ALConfigurationDialogViewController *)dialog {} +- (void)setupNavigationBar { + UIBarButtonItem *scanModeButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Settings"] + style:UIBarButtonItemStylePlain + target:self + action:@selector(showOptionsSelectionDialog)]; + self.navigationItem.rightBarButtonItem = scanModeButton; +} +- (void)presentContactUsDialog { + ALTINScanViewController __weak *weakSelf = self; +#if __has_include("ALContactUsViewController.h") + [self dismissViewControllerAnimated:YES completion:^{ + ALContactUsViewController *contactVC = [[ALContactUsViewController alloc] init]; + [weakSelf presentViewController:contactVC animated:YES completion:nil]; + [contactVC setPresentationBlock:^{ + [weakSelf.scanView startCamera]; + }]; + }]; +#endif +} @end diff --git a/AnylineExamples/Anyline Examples Source/TIN/tire_config_tin.json b/AnylineExamples/Anyline Examples Source/TIN/tire_config_tin.json new file mode 100644 index 000000000..9c5c7dd8f --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/TIN/tire_config_tin.json @@ -0,0 +1,46 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "TIRE", + "cancelOnResult": true, + "tinConfig": { + + } + }, + "cutoutConfig": { + "style": "animated_rect", + "maxWidthPercent": "80%", + "maxHeightPercent": "80%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3, + "width": 720, + "ratioFromSize": { + "width": 720, + "height": 144 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig": { + "animation": "traverse_multi", + "animationDuration": 250, + "style": "rect", + "strokeColor": "0099FF", + "beepOnResult": true, + "vibrateOnResult": false, + "strokeWidth": 2 + } + } +} + diff --git a/AnylineExamples/Anyline Examples Source/Tire/TireViewController.swift b/AnylineExamples/Anyline Examples Source/Tire/TireViewController.swift index 33578c50a..3ccc2b463 100644 --- a/AnylineExamples/Anyline Examples Source/Tire/TireViewController.swift +++ b/AnylineExamples/Anyline Examples Source/Tire/TireViewController.swift @@ -1,25 +1,20 @@ -// -// TireViewController.swift -// AnylineExamples -// -// Created by Renato Neves Ribeiro on 31.01.22. -// - import Foundation import Anyline @objc(TireViewController) -class TireViewController: ALBaseScanViewController, ALTireScanPluginDelegate { - - var tireScanViewPlugin : ALTireScanViewPlugin? - +class TireViewController: ALBaseScanViewController { + @objc public enum TireConfigType: NSInteger { case tinConfig case tireSizeConfig case commercialTireConfig } - + @objc public var configType: TireConfigType = .tinConfig + + var scanViewPlugin: ALScanViewPluginBase? + var scanViewConfig: ALScanViewConfig? + var configJSONString: NSString? override func viewDidLoad() { super.viewDidLoad() @@ -29,114 +24,137 @@ class TireViewController: ALBaseScanViewController, ALTireScanPluginDelegate { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - startScanner() - } - - func startScanner() { + do { - try tireScanViewPlugin?.start() - } catch let error { - print("Start error: \(error.localizedDescription)") + try scanViewPlugin?.start() + } catch { + print("error: \(error.localizedDescription)") } } - func stopScanner() { - do { - try tireScanViewPlugin?.stop() - } catch let error { - print("Stop error: \(error.localizedDescription)") - } - } - override func viewWillDisappear(_ animated: Bool) { + scanViewPlugin?.stop() super.viewWillDisappear(animated) - do { - try tireScanViewPlugin?.stop() - } catch let error { - print("Stop error: \(error.localizedDescription)") - } } func setupTirePlugin() { - do { - var tireConfig: ALBaseTireConfig = .init() - - let scanViewPluginConfig = ALScanViewPluginConfig.defaultTIN() - scanViewPluginConfig.cutoutConfig.backgroundColor = .clear - - switch configType { - case .tinConfig: - tireConfig = ALTINConfig() - case .tireSizeConfig: - tireConfig = ALTireSizeConfig() - scanViewPluginConfig.scanFeedbackConfig.style = .rect - case .commercialTireConfig: - tireConfig = ALCommercialTireIdConfig() - } - - let tireScanPlugin = try ALTireScanPlugin.init(pluginID: "TIRE", delegate: self, tireConfig: tireConfig) - tireScanViewPlugin = ALTireScanViewPlugin.init(scanPlugin: tireScanPlugin, scanViewPluginConfig: scanViewPluginConfig) - - if let scanView = ALScanView(frame: view.bounds, scanViewPlugin: tireScanViewPlugin) { - scanView.flashButtonConfig = ALFlashButtonConfig(flashMode: .manualOff, - flashAlignment: .topLeft, - flashOffset: .zero) - view.addSubview(scanView) - scanView.translatesAutoresizingMaskIntoConstraints = false - if #available(iOS 11.0, *) { - scanView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true - } else { - scanView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true - } - scanView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true - scanView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true - scanView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true - scanView.startCamera() + var JSONFileName: String? + var titleString: String? + switch configType { + case .tinConfig: + JSONFileName = "tire_config_tin" + titleString = "TIN" + self.controllerType = ALScanHistoryTIN + case .tireSizeConfig: + JSONFileName = "tire_config_tire_size" + titleString = "Tire Size" + self.controllerType = ALScanHistoryTireSizeConfiguration + case .commercialTireConfig: + JSONFileName = "tire_config_commercial_tire_id" + titleString = "Commercial Tire" + self.controllerType = ALScanHistoryCommercialTireID + } + + self.title = titleString; + + guard let filename = JSONFileName else { + print("Initialization error: unable to load scan plugin from config") + return; + } + let JSONStr = self.configJSONStr(withFilename: filename) + + configJSONString = JSONStr as NSString? + + if let configJSONDict = configJSONString?.asJSONObject() as? [String: Any], + let scanViewPlugin = ALScanViewPluginFactory.withJSONDictionary(configJSONDict) as? ALScanViewPlugin { + + self.scanViewPlugin = scanViewPlugin + + if let scanViewConfig = try? ALScanViewConfig(jsonDictionary: configJSONDict), + let scanView = try? ALScanView(frame: .zero, + scanViewPlugin: scanViewPlugin, + scanViewConfig: scanViewConfig) { + self.scanView = scanView + } else { + print("error: ScanView was not created. Please check the error.") } - } catch let error { - print("Initialization error: \(error.localizedDescription)") - showAlert(withTitle: "Initialization error", message: error.localizedDescription) - self.stopScanner() + + self.installScanView(self.scanView!) + + let scanPlugin: ALScanPlugin = (self.scanViewPlugin as! ALScanViewPlugin).scanPlugin + scanPlugin.delegate = self + + self.scanView?.startCamera() + + } else { + let msg = "Initialization error: tireConfig couldn't be converted in json object" + assertionFailure(msg) } } - - func showAlert(title: String) { - let alert = UIAlertController(title: title, message: "Please try scanning again", preferredStyle: .alert) - let action = UIAlertAction(title: "OK", style: .default, handler: { action in - self.startScanner() - }) - alert.addAction(action) - present(alert, animated: true, completion: nil) - } - - // MARK: - ALTireScanPluginDelegate - func anylineTireScanPlugin(_ anylineTireScanPlugin: ALTireScanPlugin, didFind result: ALTireResult) { - var resultData = [ALResultEntry]() - resultData.append(ALResultEntry(title: title, - value: String(result.result), - shouldSpellOutValue: true)) - let jsonString = self.jsonString(fromResultData: resultData) +} + +extension TireViewController: ALScanPluginDelegate { + + func scanPlugin(_ scanPlugin: ALScanPlugin, resultReceived scanResult: ALScanResult) { + enableLandscapeOrientation(false) - self.anylineDidFindResult(jsonString, barcodeResult: "", image: result.image!, scanPlugin: anylineTireScanPlugin, viewPlugin: self.tireScanViewPlugin) { + + var resultData: Array! + var resultString: String? + let result = scanResult.pluginResult + switch configType { + case .commercialTireConfig: + if let commercialTireIDResult = result.commercialTireIDResult { + resultData = commercialTireIDResult.resultEntryList + resultString = resultData.JSONStringFromResultData + } + case .tinConfig: + if let tinResult = result.tinResult { + resultData = tinResult.resultEntryList + resultString = resultData.JSONStringFromResultData + } + case .tireSizeConfig: + if let tireSizeResult = result.tireSizeResult { + resultData = tireSizeResult.resultEntryList + resultString = resultData.JSONStringFromResultData + } + } + + guard let resultData = resultData, let resultString = resultString else { + assertionFailure("no value to scan (not possible)!") + return + } + + self.anylineDidFindResult(resultString, + barcodeResult: nil, + image: scanResult.croppedImage, + scanPlugin: scanPlugin, + viewPlugin: self.scanViewPlugin!) { [weak self] in + let vc = ALResultViewController(results: resultData) - vc.imagePrimary = result.image - self.navigationController?.pushViewController(vc, animated: true) + vc.imagePrimary = scanResult.croppedImage + self?.navigationController?.pushViewController(vc, animated: true) } } } @objc class TireSizeViewController: TireViewController { - override func viewDidLoad() { - configType = TireConfigType.tireSizeConfig + configType = .tireSizeConfig super.viewDidLoad() } } @objc class CommercialTireIdViewController: TireViewController { - override func viewDidLoad() { - configType = TireConfigType.commercialTireConfig + configType = .commercialTireConfig + super.viewDidLoad() + } +} + +@objc class TINDotViewController: TireViewController { + override func viewDidLoad() { + configType = .tinConfig super.viewDidLoad() } } diff --git a/AnylineExamples/Anyline Examples Source/Tire/tire_config_commercial_tire_id.json b/AnylineExamples/Anyline Examples Source/Tire/tire_config_commercial_tire_id.json new file mode 100644 index 000000000..ff1a22462 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Tire/tire_config_commercial_tire_id.json @@ -0,0 +1,46 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "TIRE", + "cancelOnResult": true, + "commercialTireIdConfig": { + + } + }, + "cutoutConfig": { + "style": "animated_rect", + "maxWidthPercent": "80%", + "maxHeightPercent": "80%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3, + "width": 720, + "ratioFromSize": { + "width": 720, + "height": 144 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig": { + "animation": "traverse_multi", + "animationDuration": 250, + "style": "rect", + "strokeColor": "0099FF", + "beepOnResult": true, + "vibrateOnResult": false, + "strokeWidth": 2 + } + } +} + diff --git a/AnylineExamples/Anyline Examples Source/Tire/tire_config_tire_size.json b/AnylineExamples/Anyline Examples Source/Tire/tire_config_tire_size.json new file mode 100644 index 000000000..9c0512304 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Tire/tire_config_tire_size.json @@ -0,0 +1,46 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "TIRE", + "cancelOnResult": true, + "tireSizeConfig": { + "upsideDownMode": "AUTO" + } + }, + "cutoutConfig": { + "style": "animated_rect", + "maxWidthPercent": "80%", + "maxHeightPercent": "80%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3, + "width": 720, + "ratioFromSize": { + "width": 720, + "height": 144 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig": { + "animation": "traverse_multi", + "animationDuration": 250, + "style": "rect", + "strokeColor": "0099FF", + "beepOnResult": true, + "vibrateOnResult": false, + "strokeWidth": 2 + } + } +} + diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Configs/driver_license_composite_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/driver_license_composite_config.json new file mode 100644 index 000000000..1585bd36a --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/driver_license_composite_config.json @@ -0,0 +1,103 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + "offset": { "x": 0, "y": 0 } + }, + "viewPluginCompositeConfig": { + "id": "com.anyline.configs.plugin.parallel-id-barcode", + "processingMode": "parallel", + "viewPlugins": [ + { + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.id", + "universalIdConfig": { + "allowedLayouts": { + "drivingLicense": [], + "mrz": [] + }, + "drivingLicense": { + "lastName": {"scanOption": 0, "minConfidence": 40}, + "firstName": {"scanOption": 0, "minConfidence": 40}, + "fullName": {"scanOption": 0, "minConfidence": 40}, + "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, + "placeOfBirth": {"scanOption": 1, "minConfidence": 50}, + "dateOfIssue": {"scanOption": 0, "minConfidence": 50}, + "dateOfExpiry": {"scanOption": 1, "minConfidence": 50}, + "authority": {"scanOption": 1, "minConfidence": 30}, + "documentNumber": {"scanOption": 0, "minConfidence": 40}, + "licenseClass": {"scanOption": 1, "minConfidence": 30}, + "address": {"scanOption": 0}, + "sex": {"scanOption": 1,"minConfidence": 60}, + "personalNumber": {"scanOption": 1,"minConfidence": 60} + }, + "alphabet": "latin" + }, + "cancelOnResult": true + }, + "cutoutConfig" : { + "style": "rect", + "maxWidthPercent": "90%", + "maxHeightPercent": "90%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0, + "ratioFromSize" : { + "width": 50, + "height": 31 + }, + "cropPadding": { + "x": 25, + "y": 25 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig" : { + "style": "CONTOUR_RECT", + "visualFeedbackRedrawTimeout": 100, + "strokeColor": "0099FF", + "fillColor" : "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "strokeWidth": 2 + } + } + }, + { + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.barcode", + "barcodeConfig": { + "barcodeFormats": [ "PDF_417" ], + "parseAAMVA": true + }, + "cancelOnResult": true + }, + "scanFeedbackConfig" : { + "style": "none", + "animation": "none", + "strokeWidth": 0, + "strokeColor": "000000", + "fillColor": "00000000", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": false, + } + } + } + ] + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Configs/driver_license_front_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/driver_license_front_config.json new file mode 100644 index 000000000..e52254d5e --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/driver_license_front_config.json @@ -0,0 +1,56 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p" + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + "offset": { "x": 0, "y": 0 } + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.id", + "universalIdConfig": { + "allowedLayouts": { + "drivingLicense": [] + }, + "alphabet": "latin" + }, + "cancelOnResult": true + }, + "cutoutConfig" : { + "style": "animated_rect", + "maxWidthPercent": "90%", + "maxHeightPercent": "90%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3, + "ratioFromSize" : { + "width": 50, + "height": 31 + }, + "cropPadding": { + "x": 25, + "y": 25 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig" : { + "style": "CONTOUR_RECT", + "visualFeedbackRedrawTimeout": 100, + "strokeColor": "0099FF", + "fillColor" : "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "strokeWidth": 2 + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Configs/id_composite_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/id_composite_config.json new file mode 100644 index 000000000..a6e34fd57 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/id_composite_config.json @@ -0,0 +1,112 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + "offset": { "x": 0, "y": 0 } + }, + "viewPluginCompositeConfig": { + "id": "com.anyline.configs.plugin.parallel-id-barcode", + "processingMode": "parallel", + "viewPlugins": [ + { + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.id", + "universalIdConfig": { + "allowedLayouts": { + "insuranceCard": [], + "idFront": [], + "mrz": [] + }, + "insuranceCard": { + "lastName": {"scanOption": 0, "minConfidence": 50}, + "firstName": {"scanOption": 0, "minConfidence": 50}, + "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, + "personalNumber": {"scanOption": 0, "minConfidence": 50}, + "authority": {"scanOption": 0, "minConfidence": 50}, + "documentNumber": {"scanOption": 0, "minConfidence": 50}, + "dateOfExpiry": {"scanOption": 0, "minConfidence": 50}, + "nationality": {"scanOption": 0, "minConfidence": 50} + }, + "idFront": { + "lastName": {"scanOption": 0, "minConfidence": 60}, + "firstName": {"scanOption": 0, "minConfidence": 60}, + "fullName": {"scanOption": 0, "minConfidence": 60}, + "dateOfBirth": {"scanOption": 0,"minConfidence": 60}, + "placeOfBirth": {"scanOption": 1,"minConfidence": 60}, + "dateOfIssue": {"scanOption": 0, "minConfidence": 60}, + "dateOfExpiry": {"scanOption": 1,"minConfidence": 60}, + "cardAccessNumber": {"scanOption": 1,"minConfidence": 60}, + "documentNumber": {"scanOption": 0,"minConfidence": 60}, + "nationality": {"scanOption": 1,"minConfidence": 60}, + "sex": {"scanOption": 1,"minConfidence": 60}, + "personalNumber": {"scanOption": 1,"minConfidence": 60} + }, + "alphabet": "latin" + }, + "cancelOnResult": true + }, + "cutoutConfig" : { + "style": "animated_rect", + "maxWidthPercent": "90%", + "maxHeightPercent": "90%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3, + "ratioFromSize" : { + "width": 50, + "height": 31 + }, + "cropPadding": { + "x": 25, + "y": 25 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig" : { + "style": "CONTOUR_RECT", + "visualFeedbackRedrawTimeout": 100, + "strokeColor": "0099FF", + "fillColor" : "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "strokeWidth": 2 + } + } + }, + { + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.barcode", + "barcodeConfig": { + "barcodeFormats": [ "PDF_417" ] + }, + "cancelOnResult": true + }, + "scanFeedbackConfig" : { + "style": "none", + "animation": "none", + "strokeWidth": 0, + "strokeColor": "000000", + "fillColor": "00000000", + "beepOnResult": false, + "vibrateOnResult": false, + "blinkAnimationOnResult": false, + } + } + } + ] + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Configs/id_front_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/id_front_config.json new file mode 100644 index 000000000..8c1f56acf --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/id_front_config.json @@ -0,0 +1,81 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p" + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + "offset": { "x": 0, "y": 0 } + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.id", + "universalIdConfig": { + "allowedLayouts": { + "insuranceCard": [], + "idFront": [] + }, + "alphabet": "latin", + "insuranceCard": { + "lastName": {"scanOption": 0, "minConfidence": 50}, + "firstName": {"scanOption": 0, "minConfidence": 50}, + "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, + "personalNumber": {"scanOption": 0, "minConfidence": 50}, + "authority": {"scanOption": 0, "minConfidence": 50}, + "documentNumber": {"scanOption": 0, "minConfidence": 50}, + "dateOfExpiry": {"scanOption": 0, "minConfidence": 50}, + "nationality": {"scanOption": 0, "minConfidence": 50} + }, + "idFront": { + "lastName": {"scanOption": 0, "minConfidence": 60}, + "firstName": {"scanOption": 0, "minConfidence": 60}, + "fullName": {"scanOption": 0, "minConfidence": 60}, + "dateOfBirth": {"scanOption": 0,"minConfidence": 60}, + "placeOfBirth": {"scanOption": 1,"minConfidence": 60}, + "dateOfIssue": {"scanOption": 0, "minConfidence": 60}, + "dateOfExpiry": {"scanOption": 1,"minConfidence": 60}, + "cardAccessNumber": {"scanOption": 1,"minConfidence": 60}, + "documentNumber": {"scanOption": 0,"minConfidence": 60}, + "nationality": {"scanOption": 1,"minConfidence": 60}, + "sex": {"scanOption": 1,"minConfidence": 60}, + "personalNumber": {"scanOption": 1,"minConfidence": 60} + } + }, + "cancelOnResult": true + }, + "cutoutConfig" : { + "style": "animated_rect", + "maxWidthPercent": "90%", + "maxHeightPercent": "90%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3, + "ratioFromSize" : { + "width": 50, + "height": 31 + }, + "cropPadding": { + "x": 25, + "y": 25 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig" : { + "style": "CONTOUR_RECT", + "visualFeedbackRedrawTimeout": 100, + "strokeColor": "0099FF", + "fillColor" : "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "strokeWidth": 2 + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Configs/universal_id_composite_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/universal_id_composite_config.json new file mode 100644 index 000000000..1215855f5 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/universal_id_composite_config.json @@ -0,0 +1,114 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + "offset": { "x": 0, "y": 0 } + }, + "viewPluginCompositeConfig": { + "id": "com.anyline.configs.plugin.parallel-id-barcode", + "processingMode": "parallel", + "viewPlugins": [ + { + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.id", + "universalIdConfig": { + "allowedLayouts": { + "mrz": [], + "insuranceCard": [], + "drivingLicense": [], + "idFront": [] + }, + "insuranceCard": { + "lastName": {"scanOption": 0, "minConfidence": 50}, + "firstName": {"scanOption": 0, "minConfidence": 50}, + "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, + "personalNumber": {"scanOption": 0, "minConfidence": 50}, + "authority": {"scanOption": 0, "minConfidence": 50}, + "documentNumber": {"scanOption": 0, "minConfidence": 50}, + "dateOfExpiry": {"scanOption": 0, "minConfidence": 50}, + "nationality": {"scanOption": 0, "minConfidence": 50} + }, + "idFront": { + "lastName": {"scanOption": 0, "minConfidence": 60}, + "firstName": {"scanOption": 0, "minConfidence": 60}, + "fullName": {"scanOption": 0, "minConfidence": 60}, + "dateOfBirth": {"scanOption": 0,"minConfidence": 60}, + "placeOfBirth": {"scanOption": 1,"minConfidence": 60}, + "dateOfIssue": {"scanOption": 0, "minConfidence": 60}, + "dateOfExpiry": {"scanOption": 1,"minConfidence": 60}, + "cardAccessNumber": {"scanOption": 1,"minConfidence": 60}, + "documentNumber": {"scanOption": 0,"minConfidence": 60}, + "nationality": {"scanOption": 1,"minConfidence": 60}, + "sex": {"scanOption": 1,"minConfidence": 60}, + "personalNumber": {"scanOption": 1,"minConfidence": 60} + }, + "alphabet": "latin" + }, + "cancelOnResult": true + }, + "cutoutConfig" : { + "style": "animated_rect", + "maxWidthPercent": "90%", + "maxHeightPercent": "90%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3, + "ratioFromSize" : { + "width": 50, + "height": 31 + }, + "cropPadding": { + "x": 25, + "y": 25 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig" : { + "style": "CONTOUR_RECT", + "visualFeedbackRedrawTimeout": 100, + "strokeColor": "0099FF", + "fillColor" : "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "strokeWidth": 2 + } + } + }, + { + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.barcode", + "barcodeConfig": { + "barcodeFormats": [ "PDF_417" ], + "parseAAMVA": true + }, + "cancelOnResult": true + }, + "scanFeedbackConfig" : { + "style": "none", + "animation": "none", + "strokeWidth": 0, + "strokeColor": "000000", + "fillColor": "00000000", + "beepOnResult": false, + "vibrateOnResult": false, + "blinkAnimationOnResult": false, + } + } + } + ] + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Configs/universal_id_front_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/universal_id_front_config.json new file mode 100644 index 000000000..c6c216215 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Configs/universal_id_front_config.json @@ -0,0 +1,83 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "pictureResolution": "1080p" + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + "offset": { "x": 0, "y": 0 } + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.id", + "universalIdConfig": { + "allowedLayouts": { + "mrz": [], + "insuranceCard": [], + "drivingLicense": [], + "idFront": [] + }, + "alphabet": "latin", + "insuranceCard": { + "lastName": {"scanOption": 0, "minConfidence": 50}, + "firstName": {"scanOption": 0, "minConfidence": 50}, + "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, + "personalNumber": {"scanOption": 0, "minConfidence": 50}, + "authority": {"scanOption": 0, "minConfidence": 50}, + "documentNumber": {"scanOption": 0, "minConfidence": 50}, + "dateOfExpiry": {"scanOption": 0, "minConfidence": 50}, + "nationality": {"scanOption": 0, "minConfidence": 50} + }, + "idFront": { + "lastName": {"scanOption": 0, "minConfidence": 60}, + "firstName": {"scanOption": 0, "minConfidence": 60}, + "fullName": {"scanOption": 0, "minConfidence": 60}, + "dateOfBirth": {"scanOption": 0,"minConfidence": 60}, + "placeOfBirth": {"scanOption": 1,"minConfidence": 60}, + "dateOfIssue": {"scanOption": 0, "minConfidence": 60}, + "dateOfExpiry": {"scanOption": 1,"minConfidence": 60}, + "cardAccessNumber": {"scanOption": 1,"minConfidence": 60}, + "documentNumber": {"scanOption": 0,"minConfidence": 60}, + "nationality": {"scanOption": 1,"minConfidence": 60}, + "sex": {"scanOption": 1,"minConfidence": 60}, + "personalNumber": {"scanOption": 1,"minConfidence": 60} + }, + }, + "cancelOnResult": true + }, + "cutoutConfig" : { + "style": "animated_rect", + "maxWidthPercent": "90%", + "maxHeightPercent": "90%", + "alignment": "center", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", + "outerColor": "000000", + "outerAlpha": 0.3, + "ratioFromSize" : { + "width": 50, + "height": 31 + }, + "cropPadding": { + "x": 25, + "y": 25 + }, + "cropOffset": { + "x": 0, + "y": 0 + }, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig" : { + "style": "CONTOUR_RECT", + "visualFeedbackRedrawTimeout": 100, + "strokeColor": "0099FF", + "fillColor" : "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "strokeWidth": 2 + } + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping.json b/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping.json new file mode 100644 index 000000000..e45b139b2 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping.json @@ -0,0 +1,299 @@ +{ + "All States/Countries": { + "All States/Countries": [] + }, + "USA": { + "Alabama": [ + "USA-FO-AL19" + ], + "Alaska": [ + "USA-FO-AK19" + ], + "Arizona": [ + "USA-FO-AZ19" + ], + "Arkansas": [ + "USA-FO-AR19" + ], + "California": [ + "USA-FO-CA19" + ], + "Colorado": [ + "USA-FO-CO19" + ], + "Connecticut": [ + "USA-FO-CT19", + "USA-FO-CT19_v2" + ], + "Delaware": [ + "USA-FO-DE19" + ], + "District of Columbia": [ + "USA-FO-DC19" + ], + "Florida": [ + "USA-FO-FL19", + "USA-FO-FL19_v2" + ], + "Georgia": [ + "USA-FO-GA20" + ], + "Idaho": [ + "USA-FO-ID19" + ], + "Illinois": [ + "USA-FO-IL19" + ], + "Indiana": [ + "USA-FO-IN19" + ], + "Iowa": [ + "USA-FO-IA19", + "USA-FO-IA19_v2" + ], + "Kansas": [ + "USA-FO-KS19" + ], + "Kentucky": [ + "USA-FO-KY19" + ], + "Louisiana": [ + "USA-FO-LA19" + ], + "Maine": [ + "USA-FO-ME19" + ], + "Maryland": [ + "USA-FO-MD19" + ], + "Massachusetts": [ + "USA-FO-MA19" + ], + "Michigan": [ + "USA-FO-MI19", + "USA-FO-MI19_v2" + ], + "Minnesota": [ + "USA-FO-MN19" + ], + "Mississippi": [ + "USA-FO-MS19" + ], + "Missouri": [ + "USA-FO-MO19", + "USA-FO-MO19_v2" + ], + "Montana": [ + "USA-FO-MT19" + ], + "Nebraska": [ + "USA-FO-NE19" + ], + "Nevada": [ + "USA-FO-NV19", + "USA-FO-NV19_v2" + ], + "New Hampshire": [ + "USA-FO-NH19" + ], + "New Jersey": [ + "USA-FO-NJ19" + ], + "New Mexico": [ + "USA-FO-NM19" + ], + "New York": [ + "USA-FO-NY19" + ], + "North Carolina": [ + "USA-FO-NC19" + ], + "North Dakota": [ + "USA-FO-ND19" + ], + "Ohio": [ + "USA-FO-OH19" + ], + "Oklahoma": [ + "USA-FO-OK19" + ], + "Oregon": [ + "USA-FO-OR19" + ], + "Pennsylvania": [ + "USA-FO-PA19", + "USA-FO-PA19_v2" + ], + "Rhode Island": [ + "USA-FO-RI19", + "USA-FO-RI19_v2" + ], + "South Carolina": [ + "USA-FO-SC19" + ], + "South Dakota": [ + "USA-FO-SD19" + ], + "Tennessee": [ + "USA-FO-TN19", + "USA-FO-TN19_v2" + ], + "Texas": [ + "USA-FO-TX19" + ], + "Utah": [ + "USA-FO-UT19", + "USA-FO-UT19_v2" + ], + "Vermont": [ + "USA-FO-VT19" + ], + "Virginia": [ + "USA-FO-VA19" + ], + "Washington": [ + "USA-FO-WA19" + ], + "West Virginia": [ + "USA-FO-WV19" + ], + "Wisconsin": [ + "USA-FO-WI19" + ], + "Wyoming": [ + "USA-FO-WY19" + ] + }, + "Canada": { + "Alberta": [ + "CAN-FO-AB19" + ], + "British Columbia": [ + "CAN-FO-BC19" + ], + "Ontario": [ + "CAN-FO-ON19" + ], + "Quebec": [ + "CAN-FO-QC19" + ] + }, + "Europe": { + "Austria": [ + "AUT-FO-04001", + "AUT-FO-05002" + ], + "Belgium": [ + "BEL-FO-02003", + "BEL-FO-05001" + ], + "Croatia": [ + "HRV-FO-02001" + ], + "Czechia": [ + "CZE-FO-02003" + ], + "Denmark": [ + "DNK-FO-03001", + "DNK-FO-04001" + ], + "Germany": [ + "DEU-FO-02006", + "DEU-FO-02007" + ], + "Estonia": [ + "EST-FO-02004", + "EE_DVL_O_R311_F" + ], + "Finland": [ + "FIN-FO-04001" + ], + "France": [ + "FRA-FO-07001" + ], + "Hungary": [ + "HUN-FO-02001" + ], + "Ireland": [ + "IRL-FO-04001" + ], + "Italy": [ + "ITA-FO-06001" + ], + "Latvia": [ + "LVA-FO-01003" + ], + "Lithuania": [ + "LTU-FO-04001" + ], + "Luxembourg": [ + "LUX-FO-01010" + ], + "Netherlands": [ + "NLD-FO-04001", + "NLD-FO-05001", + "NLD-FO-06001" + ], + "Norway": [ + "NOR-FO-07001" + ], + "Poland": [ + "POL-FO-04001" + ], + "Portugal": [ + "PRT-FO-06001" + ], + "Romania": [ + "ROU-FO-06001" + ], + "Slovakia": [ + "SVK-FO-04001" + ], + "Slovenia": [ + "SVN-FO-04001" + ], + "Spain": [ + "ESP-FO-04002" + ], + "Sweden": [ + "SWE-FO-05001", + "SWE-FO-06001", + "SWE-FO-07001" + ], + "Switzerland": [ + "CHE-FO-02001" + ], + "United Kingdom": [ + "GBR-FO-07001", + "GBR-FO-09002" + ] + }, + "Australia": { + "Australian Capital Territory": [ + "AUS-FO-ACT11" + ], + "New South Wales": [ + "AUS-FO-NSW12" + ], + "Northern Territory": [ + "AUS-FO-NT06" + ], + "Queensland": [ + "AUS-FO-QLD19" + ], + "South Australia": [ + "AUS-FO-SA13" + ], + "Victoria": [ + "AUS-FO-VIC09" + ], + "Western Australia": [ + "AUS-FO-WAXX" + ] + }, + "Rest of World": { + "New Zealand": [ + "NZL-FO-14" + ] + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping_arabic.json b/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping_arabic.json new file mode 100644 index 000000000..6afa60b21 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping_arabic.json @@ -0,0 +1,16 @@ +{ + "GCC": { + "United Arab Emirates: Dubai": [ + "AE_DVL_O_R332_F" + ], + "Saudi Arabia": [ + "SA_DVL_O_R331_F" + ], + "Qatar": [ + "QA_DVL_O_R331_F" + ], + "Oman": [ + "OM_DVL_O_R331_F" + ] + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping_cyrillic.json b/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping_cyrillic.json new file mode 100644 index 000000000..c00424111 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/Templates/template_type_and_region_mapping_cyrillic.json @@ -0,0 +1,4 @@ +{ + "GCC": { + } +} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDFieldnameUtil.h b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDFieldnameUtil.h deleted file mode 100644 index d3c093af7..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDFieldnameUtil.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// UniversalIDFieldnameMap.h -// AnylineExamples -// -// Created by Philipp Müller on 19.09.20. -// - -#import -#import "Anyline/Anyline.h" -#import "AnylineExamples-Swift.h" - -@interface ALUniversalIDFieldnameUtil : NSObject - -+ (NSArray *)fieldNamesOrderArray; -+ (NSArray *)sortResultData:(NSArray *)resultData; - -+ (NSArray *)sortResultDataUsingFieldNamesWithSpace:(NSArray *)resultData; - -+ (NSMutableArray *)addIDSubResult:(ALUniversalIDIdentification*)identification titleSuffix:(NSString *)titleSuffix resultHistoryString:(NSMutableString *)resultHistoryString; -+ (NSString *)camelCaseToTitleCaseModified:(NSString *)inputString; -+ (NSString *)camelCaseToTitleCase:(NSString *)inputString; -+ (BOOL)isPassportForUniversalIDIdentification:(ALUniversalIDIdentification *)identification; -@end diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDFieldnameUtil.m b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDFieldnameUtil.m deleted file mode 100644 index ceb69417e..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDFieldnameUtil.m +++ /dev/null @@ -1,200 +0,0 @@ -// -// UniversalIDFieldnameMap.m -// AnylineExamples -// -// Created by Philipp Müller on 19.09.20. -// - -#import "ALUniversalIDFieldnameUtil.h" - -@interface ALUniversalIDFieldnameUtil () - -@end - - -@implementation ALUniversalIDFieldnameUtil - -+ (NSArray *)sortResultData:(NSArray *)resultData { - NSArray *priorityFieldsArray = [ALUniversalIDFieldnameUtil fieldNamesOrderArray]; - NSArray *sortedArray = [resultData sortedArrayUsingComparator:^NSComparisonResult(ALResultEntry *entry1, ALResultEntry *entry2) { - NSUInteger index1 = [priorityFieldsArray indexOfObjectPassingTest:^BOOL(NSString *title, NSUInteger idx, BOOL * _Nonnull stop) { - return [entry1.title localizedCaseInsensitiveContainsString:title]; - }]; - NSUInteger index2 = [priorityFieldsArray indexOfObjectPassingTest:^BOOL(NSString *title, NSUInteger idx, BOOL * _Nonnull stop) { - return [entry2.title localizedCaseInsensitiveContainsString:title]; - }]; - if (index2 == index1) { - return (NSComparisonResult)NSOrderedSame; - } else if (index1 == NSNotFound && index2 != NSNotFound) { - return (NSComparisonResult)NSOrderedDescending; - } else if (index2 == NSNotFound && index1 != NSNotFound) { - return (NSComparisonResult)NSOrderedAscending; - } else if (index2 > index1) { - return (NSComparisonResult)NSOrderedAscending; - } else if (index1 > index2) { - return (NSComparisonResult)NSOrderedDescending; - } - return (NSComparisonResult)NSOrderedSame; - }]; - - return sortedArray; -} - -+ (NSArray *)fieldNamesOrderArray { - NSArray *array = @[ - @"Face Match Level", - @"name", - @"surname", - @"lastName", - @"givenNames", - @"firstName", - @"dateOfBirth", - @"placeOfBirth", - @"dateOfIssue", - @"dateOfExpiry", - @"documentNumber", - @"layoutDefinition.country", - @"formattedDateOfBirth", - @"formattedDateOfIssue", - @"formattedDateOfExpiry", - ]; - return [array copy]; -} - -+ (NSArray *)fieldNamesWithSpaceOrderArray { - NSArray *array = @[ - @"Face Match Level", - @"name", - @"surname", - @"lastName", - @"given Names", - @"first Name", - @"date Of Birth", - @"place Of Birth", - @"date Of Issue", - @"date Of Expiry", - @"document Number", - @"country", - ]; - return [array copy]; -} - -+ (NSArray *)sortResultDataUsingFieldNamesWithSpace:(NSArray *)resultData { - NSArray *priorityFieldsArray = [ALUniversalIDFieldnameUtil fieldNamesWithSpaceOrderArray]; - NSArray *sortedArray = [resultData sortedArrayUsingComparator:^NSComparisonResult(ALResultEntry *entry1, ALResultEntry *entry2) { - NSUInteger index1 = [priorityFieldsArray indexOfObjectPassingTest:^BOOL(NSString *title, NSUInteger idx, BOOL * _Nonnull stop) { - return [entry1.title localizedCaseInsensitiveContainsString:title]; - }]; - NSUInteger index2 = [priorityFieldsArray indexOfObjectPassingTest:^BOOL(NSString *title, NSUInteger idx, BOOL * _Nonnull stop) { - return [entry2.title localizedCaseInsensitiveContainsString:title]; - }]; - if (index2 == index1) { - return (NSComparisonResult)NSOrderedSame; - } else if (index1 == NSNotFound && index2 != NSNotFound) { - return (NSComparisonResult)NSOrderedDescending; - } else if (index2 == NSNotFound && index1 != NSNotFound) { - return (NSComparisonResult)NSOrderedAscending; - } else if (index2 > index1) { - return (NSComparisonResult)NSOrderedAscending; - } else if (index1 > index2) { - return (NSComparisonResult)NSOrderedDescending; - } - return (NSComparisonResult)NSOrderedSame; - }]; - - return sortedArray; -} - -+ (NSMutableArray *)addIDSubResult:(ALUniversalIDIdentification*)identification titleSuffix:(NSString *)titleSuffix resultHistoryString:(NSMutableString *)resultHistoryString { - - NSCharacterSet *set = [NSCharacterSet whitespaceCharacterSet]; - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - - NSMutableOrderedSet *baseSet = [NSMutableOrderedSet orderedSetWithArray:[ALUniversalIDFieldnameUtil fieldNamesOrderArray]]; - NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:[identification fieldNames]]; - - [baseSet unionOrderedSet:orderedSet]; - - NSArray *fieldNames = [baseSet array]; - NSArray *fieldsNamesWithSpace = [self fieldNamesWithSpaceOrderArray]; - - [fieldNames enumerateObjectsUsingBlock:^(NSString *fieldName, NSUInteger idx, BOOL *stop) { - NSString *fieldNameTitle = [NSString stringWithFormat:@"%@%@", [ALUniversalIDFieldnameUtil camelCaseToTitleCaseModified:fieldName], titleSuffix]; - if (![fieldName localizedCaseInsensitiveContainsString:@"String"] && - ![fieldName localizedCaseInsensitiveContainsString:@"checkdigit"] && - ![fieldName localizedCaseInsensitiveContainsString:@"confidence"] && - [identification valueForField:fieldName] && - [[[identification valueForField:fieldName] stringByTrimmingCharactersInSet: set] length] > 0) { - - if (![fieldName localizedCaseInsensitiveContainsString:@"formatted"]) { - __block ALResultEntry *newEntry = [[ALResultEntry alloc] initWithTitle:fieldNameTitle value:[identification valueForField:fieldName]]; - [fieldsNamesWithSpace enumerateObjectsUsingBlock:^(NSString * _Nonnull fieldname, NSUInteger idx, BOOL * _Nonnull stop) { - BOOL isMandatory = [newEntry.title localizedCaseInsensitiveContainsString:fieldname]; - [newEntry setIsMandatory:isMandatory]; - *stop = isMandatory; - }]; - [resultData addObject:newEntry]; - } else { - [resultData enumerateObjectsUsingBlock:^(ALResultEntry * _Nonnull entry, NSUInteger idx, BOOL * _Nonnull stop) { - if ([[entry title] localizedCaseInsensitiveContainsString:[fieldNameTitle stringByReplacingOccurrencesOfString:@"Formatted " withString:@""]]) { - [entry setValue:[identification valueForField:fieldName]]; - } - }]; - } - - [resultHistoryString appendString:[NSString stringWithFormat:@"%@:%@\n", fieldNameTitle, [identification valueForField:fieldName]]]; - } - }]; - - return resultData; -} - -+ (NSString *)camelCaseToTitleCaseModified:(NSString *)inputString { - NSString *strModified = [inputString stringByReplacingOccurrencesOfString:@"([a-z])([A-Z])" - withString:@"$1 $2" - options:NSRegularExpressionSearch - range:NSMakeRange(0, inputString.length)]; - - strModified = strModified.capitalizedString; - - strModified = [strModified stringByReplacingOccurrencesOfString:@"Of" - withString:@"of" - options:NSLiteralSearch - range:NSMakeRange(0, inputString.length)]; - - return strModified; -} - -+ (NSString *)camelCaseToTitleCase:(NSString *)inputString { - NSString *str = [inputString copy]; - NSMutableString *str2 = [NSMutableString string]; - - for (NSInteger i=0; i +#import +#import "ALIDCountryHelper.h" +#import "ALConfigurationDialogViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol ALUniversalIDScanConfigControllerDelegate; + +@interface ALUniversalIDScanConfig : NSObject + +@property (nonatomic, strong) NSArray *regions; + +@property (nonatomic, assign) ALScriptType scriptType; + +- (instancetype)initWithRegions:(NSArray *)regions scriptType:(ALScriptType)scriptType; + +@end + + +@interface ALUniversalIDScanConfigController : NSObject + +@property (nonatomic, strong) ALUniversalIDScanConfig *config; + +// used to stand in place of the usual caller ALUniversal...FrontAndBack +// to abstract away the dialog management from it +@property (nonatomic, weak) UIViewController *presentingViewController; + +@property (nonatomic, weak) id delegate; + +- (instancetype)initWithPresentingVC:(UIViewController *)presentingVC + countryHelper:(ALIDCountryHelper *)idCountryHelper + selectMode:(ALConfigDialogType)selectMode + delegate:(nonnull id)delegate; + +- (void)start; + +@end + + +@protocol ALUniversalIDScanConfigControllerDelegate + +// report when a change is registered, so that the scan view would get its configs reloaded. +// if nil, then no change was detected. +- (void)idScanConfigController:(ALUniversalIDScanConfigController *)controller + finishedWithUpdatedConfig:(BOOL)hasUpdates; + +- (void)idScanConfigController:(ALUniversalIDScanConfigController *)controller + isChangingScript:(ALScriptType)newScript; + +- (void)dialogStarted; + +- (void)dialogCancelled; + +@end + +NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanConfigController.m b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanConfigController.m new file mode 100644 index 000000000..18b0da4b7 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanConfigController.m @@ -0,0 +1,284 @@ +#import "ALUniversalIDScanConfigController.h" +#import "ALIDCountryHelper.h" +#import "ALSelectionTable.h" + +NSString * const kSelectRegionText = @"Select Region"; +NSString * const kSelectScriptText = @"Select Script"; +NSString * const kAllRegionsText = @"All Regions"; +NSString * const kAllRegionsFormat = @"%u Regions"; + +@implementation ALUniversalIDScanConfig + +- (nonnull id)copyWithZone:(nullable NSZone *)zone { + id copy = [[[self class] alloc] init]; + if (copy) { + [copy setRegions:[self.regions copyWithZone:zone]]; + [copy setScriptType:self.scriptType]; + } + return copy; +} + +- (instancetype)initWithRegions:(NSArray *)regions scriptType:(ALScriptType)scriptType { + if (self = [self init]) { + _regions = regions; + _scriptType = scriptType; + } + return self; +} + +@end + +@interface ALUniversalIDScanConfigController () + +@property (nonatomic, strong) ALUniversalIDScanConfig *savedConfig; + +@property (nonatomic, assign) ALConfigDialogType selectMode; + +@property (nonatomic, weak) ALIDCountryHelper *idCountryHelper; + +@end + +@implementation ALUniversalIDScanConfigController + +- (instancetype)initWithPresentingVC:(UIViewController *)presentingVC + countryHelper:(ALIDCountryHelper *)idCountryHelper + selectMode:(ALConfigDialogType)selectMode + delegate:(nonnull id)delegate { + if (self = [super init]) { + _presentingViewController = presentingVC; + _delegate = delegate; + _selectMode = selectMode; + _idCountryHelper = idCountryHelper; + } + return self; +} + +- (void)setConfig:(ALUniversalIDScanConfig *)config { + _config = config; + self.savedConfig = [config copy]; +} + +- (void)start { + switch (self.selectMode) { + case ALConfigDialogTypeOverview: + [self showOptionsSelectionDialog]; + break; + case ALConfigDialogTypeScriptSelection: + [self showSelectScriptDialog]; + break; + default: + break; + } +} + +- (void)showOptionsSelectionDialog { + UIViewController *pvc = self.presentingViewController; + NSArray *choices = @[ kSelectScriptText, kSelectRegionText ]; + NSArray *subTexts = [self getSubTextsFromRegions:self.config.regions scriptType:self.config.scriptType]; + NSArray *selections = nil; + BOOL hasChanges = [self configHasChanged]; + ALConfigurationDialogViewController *vc = [[ALConfigurationDialogViewController alloc] + initWithChoices:choices + selections:selections + secondaryTexts:subTexts + showApplyBtn:hasChanges + dialogType:ALConfigDialogTypeOverview]; + vc.delegate = self; + [pvc presentViewController:vc animated:YES completion:nil]; + [self.delegate dialogStarted]; +} + +- (void)showSelectRegionDialog { + NSDictionary *> *regionTemplateMap = [_idCountryHelper idTemplateList]; + NSArray *headers = [self sortedHeadersForRegionTemplateMap:regionTemplateMap]; + + NSString *title = kSelectRegionText; + NSArray *countryList = [_idCountryHelper defaultTemplates]; + ALSelectionTable *selectionTable = [[ALSelectionTable alloc] initWithSelectedItems:self.config.regions + allItems:regionTemplateMap + headerTitles:headers + defaultItems:countryList + title:title + singleSelect:YES]; + selectionTable.delegate = self; + + + UINavigationController *navC = [[UINavigationController alloc] initWithRootViewController:selectionTable]; + [self.presentingViewController presentViewController:navC animated:YES completion:NULL]; + navC.presentationController.delegate = self; +} + +- (void)showSelectScriptDialog { + [self showSelectScriptDialogWithApplyButton:NO]; +} + +- (void)showSelectScriptDialogWithApplyButton:(BOOL)showApplyBtn { + NSArray *choices = [[self class] scripts]; + NSArray *selections = [self scriptsSelected]; + ALConfigurationDialogViewController *vc = [[ALConfigurationDialogViewController alloc] + initWithChoices:choices + selections:selections + secondaryTexts:@[] + showApplyBtn:showApplyBtn + dialogType:ALConfigDialogTypeScriptSelection]; + vc.delegate = self; + [self.presentingViewController presentViewController:vc animated:YES completion:nil]; +} + +// MARK: - ALConfigurationDialogViewControllerDelegate + +- (void)concludeWithMode:(ALConfigDialogType)mode { + switch (mode) { + case ALConfigDialogTypeOverview: + [self showOptionsSelectionDialog]; + break; + case ALConfigDialogTypeScriptSelection: + [self.delegate idScanConfigController:self + finishedWithUpdatedConfig:[self configHasChanged]]; + break; + } +} + +- (void)configDialog:(nonnull ALConfigurationDialogViewController *)dialog selectedIndex:(NSUInteger)index { + __weak __block typeof(self) weakSelf = self; + switch (dialog.type) { + case ALConfigDialogTypeScriptSelection: + [self updateConfigForCommittedScriptIndex:index]; + [self dismissDialog:dialog afterDelay:0.5 completion:^{ + [weakSelf concludeWithMode:weakSelf.selectMode]; + }]; + break; + case ALConfigDialogTypeOverview: + [dialog dismissViewControllerAnimated:YES completion:^{ + switch (index) { + case 0: [weakSelf showSelectScriptDialog]; break; + case 1: [weakSelf showSelectRegionDialog]; break; + default: break; + } + }]; + break; + } +} + +- (void)configDialogCommitted:(BOOL)commited dialog:(nonnull ALConfigurationDialogViewController *)dialog { + if (dialog.type == ALConfigDialogTypeOverview) { + BOOL hasUpdates = [self configHasChanged]; + __weak __block typeof(self) weakSelf = self; + [dialog dismissViewControllerAnimated:YES completion:^{ + [weakSelf.delegate idScanConfigController:self finishedWithUpdatedConfig:hasUpdates]; + }]; + } else if (dialog.type == ALConfigDialogTypeScriptSelection) { + [self updateConfigForCommittedScriptIndex:dialog.selectedIndex.unsignedIntValue]; + __weak __block typeof(self) weakSelf = self; + [dialog dismissViewControllerAnimated:YES completion:^{ + if (dialog.showApplyButton) { + [weakSelf.delegate idScanConfigController:self finishedWithUpdatedConfig:YES]; + } else { + [weakSelf showOptionsSelectionDialog]; + } + }]; + } +} + +- (void)configDialogCancelled:(ALConfigurationDialogViewController *)dialog { + [self.delegate dialogCancelled]; +} + +// MARK: - ALSelectionTableDelegate + +- (void)selectionTable:(ALSelectionTable *)selectionTable selectedItems:(NSArray *)selectedItems { + self.config.regions = selectedItems; + [self showOptionsSelectionDialog]; +} + +- (void)selectionTableCancelled:(ALSelectionTable *)selectionTable { + [self showOptionsSelectionDialog]; +} + +// when pulling down the region selection dialog to dismiss it... +- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController { + UIViewController *presented = presentationController.presentedViewController; + if ([presented isKindOfClass:[UINavigationController class]]) { + UIViewController *topVC = [((UINavigationController *)presented) topViewController]; + if ([topVC isKindOfClass:[ALSelectionTable class]]) { + [self showOptionsSelectionDialog]; + } + } +} + +// MARK: - Miscellaneous + +- (void)dismissDialog:(ALConfigurationDialogViewController *)dialog afterDelay:(NSTimeInterval)delay completion:(void (^ __nullable)(void))completion { + __weak __block ALConfigurationDialogViewController *weakDialog = dialog; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + [weakDialog dismissViewControllerAnimated:YES completion:completion]; + }); +} + +- (NSArray *)sortedHeadersForRegionTemplateMap:(NSDictionary *> *)regionTemplateMap { + + // NOTE: this sort will put shorter header names first (prioritizing "USA"). It only works as intended + // with the default template region map. I kept it here because it is found on the original code, + // before non-Latin scripts configurations had been introduced. + NSComparisonResult (^sortByDecreasingHeaderLength)(NSString * _Nonnull obj1, NSString * _Nonnull obj2) = ^NSComparisonResult(NSString * _Nonnull obj1, NSString * _Nonnull obj2) { + if (obj1.length < obj2.length) { + return NSOrderedAscending; + } + return NSOrderedDescending; + }; + + // the sensible default would be a case insensitive sort of the headers + NSComparisonResult (^sortCaseInsensitive)(NSString * _Nonnull obj1, NSString * _Nonnull obj2) = ^NSComparisonResult(NSString * _Nonnull obj1, NSString * _Nonnull obj2) { + return [obj1 compare:obj2 options:NSCaseInsensitiveSearch]; + }; + + if (self.idCountryHelper.scriptType == ALScriptTypeLatin) { + return [regionTemplateMap.allKeys sortedArrayUsingComparator:sortByDecreasingHeaderLength]; + } + return [regionTemplateMap.allKeys sortedArrayUsingComparator:sortCaseInsensitive]; +} + +- (void)updateConfigForCommittedScriptIndex:(NSUInteger)index { + ALScriptType selectedScriptType = [self scriptTypeForIndex:index]; + BOOL scriptIsChanging = _config.scriptType != selectedScriptType; + if (scriptIsChanging) { + [self.delegate idScanConfigController:self isChangingScript:selectedScriptType]; + self.config.regions = [_idCountryHelper defaultTemplates]; + } + self.config.scriptType = selectedScriptType; +} + +// when config (region / script) is already different from one originally loaded +- (BOOL)configHasChanged { + BOOL scriptChanged = self.config.scriptType != self.savedConfig.scriptType; + BOOL newRegionConfigHasChanged = ![[NSSet setWithArray:self.config.regions] isEqualToSet:[NSSet setWithArray:self.savedConfig.regions]]; + return scriptChanged || newRegionConfigHasChanged; +} + +- (NSArray *)scriptsSelected { + // result is an array with a single int -- the index of the enum value. + return @[@(self.config.scriptType)]; +} + +- (ALScriptType)scriptTypeForIndex:(NSUInteger)index { + return (ALScriptType)index; +} + +- (NSArray *)getSubTextsFromRegions:(NSArray *)regions scriptType:(ALScriptType)scriptType { + NSString *script = [[self class] scripts][scriptType]; + NSString *region = [NSString stringWithFormat:kAllRegionsText]; + if (regions.count == 1) { + region = regions[0]; + } else if (regions.count != [self.idCountryHelper defaultTemplates].count) { + region = [NSString stringWithFormat:kAllRegionsFormat, (unsigned)regions.count]; + } + return @[script, region]; +} + +// NOTE: the array MUST correspond to the values of enum ALScriptType ++ (NSArray *)scripts { + return @[ @"Latin", @"Arabic", @"Cyrillic" ]; +} + +@end diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewController.h b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewController.h index b8ff75481..e4b822a72 100644 --- a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewController.h +++ b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewController.h @@ -1,16 +1,19 @@ -// -// ALUniversalIDViewController.h -// AnylineExamples -// -// Created by Angela Brett on 25.06.20. -// - #import "ALBaseScanViewController.h" +#import "ALIDCountryHelper.h" +#import + +extern NSString * const kArabicIDTitleString; + +extern NSString * const kCyrillicIDTitleString; + +extern NSString * const kDriversLicenseTitleString; -NS_ASSUME_NONNULL_BEGIN +extern NSString * const kPassportVisaTitleString; + +extern NSString * const kIDCardTitleString; @interface ALUniversalIDScanViewController : ALBaseScanViewController -@end +@property (nonatomic, assign) ALScriptType scriptType; -NS_ASSUME_NONNULL_END +@end diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewController.m b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewController.m index 3561ad50b..704ae4e04 100644 --- a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewController.m @@ -1,140 +1,912 @@ -// -// ALUniversalIDViewController.m -// AnylineExamples -// -// Created by Angela Brett on 25.06.20. -// +#import +#import +#import +#import "AnylineExamples-Swift.h" +#import "ALScriptSelectionViewController.h" +#import "ALTutorialViewController.h" +#import "ALUniversalIDScanConfigController.h" #import "ALUniversalIDScanViewController.h" -#import "AnylineExamples-Swift.h" -#import "ALUniversalIDFieldnameUtil.h" -@interface ALUniversalIDScanViewController () +NSString * const kDriversLicenseTitleString = @"Driver's License"; +NSString * const kIDCardTitleString = @"ID Card"; +NSString * const kPassportVisaTitleString = @"Passport / Visa"; + +NSString * const kArabicIDTitleString = @"Arabic"; +NSString * const kCyrillicIDTitleString = @"Cyrillic"; +NSString * const kDefaultIDTitleString = @"ID"; + +NSString * const kDocumentationSupportedIdsURL = @"https://documentation.anyline.com/toc/products/id/universal_id/index.html#supported-document-types-and-countries"; +NSString * const kRequestSupportMsgBodyFmt = @"Dear Anyline Support,

I have recurrently faced an error updating the content.

This is related to the deployment \"%@\".

The error I received is: \"%@\".

Kind regards"; + +NSString * const kScanIDFrontLabelText = @"Scan your ID"; +NSString * const kScanIDBackLabelText = @"Turn ID over"; +NSString * const kScanViewPluginFrontID = @"IDPluginFront"; +NSString * const kScanViewPluginBackID = @"IDPluginBack"; + +NSString * const kFileNameUniversalIdFront = @"universal_id_front_config"; +NSString * const kFileNameUniversalIdCompositeBack = @"universal_id_composite_config"; +NSString * const kFileNameIdFront = @"id_front_config"; +NSString * const kFileNameIdCompositeBack = @"id_composite_config"; +NSString * const kFileNameDriverLicenseFront = @"driver_license_front_config"; +NSString * const kFileNameDriverLicenseCompositeBack = @"driver_license_composite_config"; + +NSString * const kTroubleScanningAlertDefaultTitleText = @"Having trouble scanning?"; +NSString * const kTroubleScanningAlertDefaultMessageText = @"This ID is either not supported yet or the scan was not captured correctly."; +NSString * const kTroubleScanningAlertDefaultActionText = @"Try again"; + +NSString * const kTroubleScanningAlertBadConditionTitleText = @"This ID was not captured correctly."; +NSString * const kTroubleScanningAlertBadConditionMessageText = @"Please ensure a good scanning environment. \ +Try again later or read through the documentation for more information."; + +NSString * const kTroubleScanningAlertUnknownIDTitleText = @"ID not supported"; +NSString * const kTroubleScanningAlertUnknownIDMessageText = @"Unfortunately, it seems like this ID is not supported yet."; + +NSString * const kActionTitleMoreInfo = @"More info"; +NSString * const kActionTitleOK = @"OK"; +NSString * const kActionTitleStartOver = @"Start over"; + +NSUInteger const kUniversalIDTroubleScanningCounter = 3; + +// Timeout applied to each side of ID scan before a prompt is shown +NSInteger const kUniversalIDTroubleScanningTimeoutTime = 30; + +NSTimeInterval const kUniversalIDBacksideScanTimeout = 0.5; + +// applies to the second part of the serial scan (backside parallel scan +// of barcode:PDF417+ID). This is the total time before serial gives up and +// results are gathered and presented, regardless of whether or not an ID +// backside is successfully scanned. +// NSInteger const kUniversalIDSerialScanTimeout = 5; + +// as PDF417 is an optional child of the parallel plugin (together with ID +// backside), this is the amount of additional seconds barcode scanning is +// given to add to the back side ID scan after the latter has already been +// successfully scanned. +// NSInteger const kBarcodePDF417Timeout = 1; + + +typedef NS_ENUM(NSUInteger, ALUniversalIDScanType) { + ALUniversalIDScanTypeGeneric = 0, + ALUniversalIDScanTypeDriverLicense, + ALUniversalIDScanTypeIDCard +}; + + +@interface ALUniversalIDScanViewController () + +@property (nonatomic, strong) id scanViewPlugin; + +@property (nonatomic, strong) ALScanViewConfig *scanViewConfig; + +@property (nonatomic, readonly) NSString *configJSONStr; + +@property (nullable, nonatomic, strong) NSMutableArray *resultData; + +@property (nullable, nonatomic, strong) UIImage *frontScanImage; + +@property (nullable, nonatomic, strong) UIImage *backScanImage; + +@property (nullable, nonatomic, strong) UIImage *faceImage; + +@property (nullable, nonatomic, strong) NSTimer *troubleScanningTimeout; + +// how long to wait before wrapping backside scan (must have at least 1 out of 2 results) +@property (nullable, nonatomic, strong) NSTimer *backsideScanTimeout; + +@property (nonatomic) NSUInteger troubleScanningCounter; + +@property (nonatomic, strong) NSMutableString *resultHistoryString; + +@property (nullable, nonatomic, strong) UIView *hintView; -@property (nonatomic, strong) ALIDScanViewPlugin *scanViewPlugin; -@property (nonatomic, strong) ALIDScanPlugin *scanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +@property (nullable, nonatomic, strong) UILabel *hintViewLabel; + +@property (nonatomic, strong) UIImageView *flipIDAnimationView; + +@property (nonatomic, strong) ALIDCountryHelper *countryIDHelper; + +@property (nonatomic, strong) ALUniversalIDScanConfigController *configController; + +@property (nonatomic, assign) BOOL isTwoSided; + +@property (nonatomic, assign) BOOL hasScannedSecondSide; + +@property (nonatomic, readonly) ALUniversalIDScanType scanType; + +@property (nonatomic, strong, nullable) ALBarcodeResult *barcodeResult; + +@property (nonatomic, strong, nullable) ALUniversalIDResult *backsideIDResult; @end @implementation ALUniversalIDScanViewController +- (void)dealloc { + [NSNotificationCenter.defaultCenter removeObserver:self]; +} + - (void)viewDidLoad { [super viewDidLoad]; + _isTwoSided = NO; + self.resultData = [[NSMutableArray alloc] init]; + [self subscribeToAppLifecycleEvents]; - self.title = @"ID"; - - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - NSError *error = nil; - NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:@"universal_id_config" ofType:@"json"]; - NSData *jsonFile = [NSData dataWithContentsOfFile:jsonFilePath]; - NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData: jsonFile options: NSJSONReadingMutableContainers error: &error]; - self.scanViewPlugin = (ALIDScanViewPlugin *)[ALAbstractScanViewPlugin scanViewPluginForConfigDict:configDict delegate:self error:&error]; - - [self.scanViewPlugin addScanViewPluginDelegate:self]; - - NSAssert(self.scanViewPlugin, @"Setup Error: %@", error.debugDescription); - self.scanPlugin = self.scanViewPlugin.idScanPlugin; - - [self.scanPlugin addInfoDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.scanViewPlugin]; - - self.controllerType = ALScanHistoryUniversalID; - - // After setup is complete we add the scanView to the view of this view controller - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; + if (!_countryIDHelper) { + _countryIDHelper = [[ALIDCountryHelper alloc] init]; + } + + self.title = (self.title && self.title.length > 0) ? self.title : kDefaultIDTitleString; + + // assume a script type based on VC title + self.scriptType = ALScriptTypeLatin; + if ([self.title localizedCaseInsensitiveCompare:kArabicIDTitleString] == NSOrderedSame) { + self.scriptType = ALScriptTypeArabic; + } else if ([self.title localizedCaseInsensitiveCompare:kCyrillicIDTitleString] == NSOrderedSame) { + self.scriptType = ALScriptTypeCyrillic; + } + + CGFloat hintMargin = 7; + + // Add scan hint label + self.hintView = [self createScanHintView:hintMargin]; + [self.view addSubview:self.hintView]; + + [self setupNavigationBar]; + + [self configureSelectNoOfSidesButton]; } -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { +- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; + [self resumeScanning]; + [self.navigationController setNavigationBarHidden:NO]; } -/* - Cancel scanning to allow the module to clean up - */ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - [self.scanViewPlugin stopAndReturnError:nil]; + [self stopTroubleScanningTimeout]; + [self stopBacksideScanTimeout]; +} + +- (void)resetResultData { + self.resultData = [NSMutableArray array]; + self.frontScanImage = nil; + self.backScanImage = nil; + self.barcodeResult = nil; + self.backsideIDResult = nil; + self.hasScannedSecondSide = NO; + self.faceImage = nil; } -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.scanViewPlugin]; +- (void)removeScanView { + if (self.scanView) { + [self.scanView stopCamera]; + [self.scanView removeFromSuperview]; + } } +- (void)createFrontScanViewPlugin { + [self resetResultData]; -#pragma mark -- AnylineOCRModuleDelegate + NSDictionary *frontIDScanViewConfig = [self getConfigDictForFrontIDScanner]; -/* - This is the main delegate method Anyline uses to report its results - */ -- (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin - didFindResult:(ALIDResult *)scanResult { - [self.scanViewPlugin stopAndReturnError:nil]; + NSError *error; // each time it's used, you should really check the error. + self.scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:frontIDScanViewConfig error:&error]; + + // Handle it properly: you most likely couldn't proceed to the next stage when an error occurs. + ALScanViewPluginConfig *scanViewPluginConfig = [[ALScanViewPluginConfig alloc] initWithJSONDictionary:frontIDScanViewConfig + error:&error]; + [scanViewPluginConfig.scanPluginConfig.pluginConfig.universalIDConfig setAlphabet:[self getAlphabet]]; + self.scanViewPlugin = [[ALScanViewPlugin alloc] initWithConfig:scanViewPluginConfig error:&error]; + + if (self.scanView) { + BOOL success = [self.scanView setScanViewPlugin:self.scanViewPlugin error:&error]; + if (!success) { + NSLog(@"Unable to update scan view plugin. Reason: %@", error.localizedDescription); + } + } else { + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.scanViewPlugin + scanViewConfig:self.scanViewConfig + error:&error]; + [self installScanView:self.scanView]; + } + + // this is just a cast + ALScanViewPlugin *scanViewPlugin = self.scanViewPlugin; + scanViewPlugin.scanPlugin.delegate = self; + + [self.scanViewPlugin startWithError:&error]; + + [self.scanView startCamera]; + [self.view sendSubviewToBack:self.scanView]; +} + +- (void)createBackScanViewPlugin { + NSDictionary *backIDScanViewConfig = [self getConfigDictForBackIDScanner]; + + // going to recreate the scan plugin configs and all with the currently-selected alphabet + ALAlphabet *alphabet = [self getAlphabet]; + + id backScanViewPlugin = [ALScanViewPluginFactory withJSONDictionary:backIDScanViewConfig]; + + // (The ScanViewPlugin needs to be recreated) + // create a new scan plugin (with the config changes) and pass it to scan view + // plugin obj / constructor. + ALScanViewPluginConfig *scanViewPluginConfig; + if ([backScanViewPlugin isKindOfClass:ALScanViewPlugin.class]) { + ALScanViewPlugin *scanViewPlugin = backScanViewPlugin; + scanViewPluginConfig = scanViewPlugin.scanViewPluginConfig; + scanViewPluginConfig.scanPluginConfig.pluginConfig.universalIDConfig.alphabet = alphabet; + + backScanViewPlugin = [ALScanViewPluginFactory withJSONDictionary:scanViewPluginConfig.asJSONString.asJSONObject]; + ((ALScanViewPlugin *)backScanViewPlugin).scanPlugin.delegate = self; + + } else if ([backScanViewPlugin isKindOfClass:ALViewPluginComposite.class]) { + ALViewPluginComposite *composite = backScanViewPlugin; + // modify the alphabet of the ID plugin child + for (id child in composite.children) { + if ([child isKindOfClass:ALScanViewPlugin.class] && [[(ALScanViewPlugin *)child scanPlugin] scanPluginConfig].pluginConfig.universalIDConfig != nil) { + ALScanViewPlugin *scanViewPlugin = child; + scanViewPluginConfig = scanViewPlugin.scanViewPluginConfig; + scanViewPluginConfig.scanPluginConfig.pluginConfig.universalIDConfig.alphabet = alphabet; + break; + } + } + composite = [[ALViewPluginComposite alloc] initWithJSONDictionary:composite.JSONDictionary[@"viewPluginCompositeConfig"] error:nil]; + backScanViewPlugin = composite; + for (id child in composite.children) { + if ([child isKindOfClass:ALScanViewPlugin.class]) { + ((ALScanViewPlugin *)child).scanPlugin.delegate = self; + } + } + } + + NSAssert(backScanViewPlugin, @"backScanViewPlugin should not be null!"); + + scanViewPluginConfig.scanPluginConfig.pluginConfig.universalIDConfig.alphabet = [self getAlphabet]; + + NSError *error; + self.scanViewPlugin = backScanViewPlugin; + + // the way it works, unfortunately for the back scan view, is that it will keep using + // any scan view config used for the front scan because then we wouldn't have to recreate the + // scan view. + self.scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:backIDScanViewConfig error:&error]; + + if (self.scanView) { + BOOL success = [self.scanView setScanViewPlugin:self.scanViewPlugin error:&error]; + if (!success) { + NSLog(@"Unable to update scan view plugin. Reason: %@", error.localizedDescription); + } + } else { + + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.scanViewPlugin + scanViewConfig:self.scanViewConfig + error:&error]; + + [self installScanView:self.scanView]; + } + + [self.scanViewPlugin startWithError:&error]; + + [self.scanView startCamera]; + [self.view sendSubviewToBack:self.scanView]; +} + +- (ALAlphabet *)getAlphabet { + switch (self.scriptType) { + case ALScriptTypeLatin: + return [ALAlphabet withValue:@"latin"]; + case ALScriptTypeArabic: + return [ALAlphabet withValue:@"arabic"]; + case ALScriptTypeCyrillic: + return [ALAlphabet withValue:@"cyrillic"]; + } + return [ALAlphabet withValue:@"latin"]; +} + +- (ALUniversalIDScanType)scanType { + if ([self.title isEqualToString:kIDCardTitleString]) { + return ALUniversalIDScanTypeIDCard; + } else if ([self.title isEqualToString:kDriversLicenseTitleString]) { + return ALUniversalIDScanTypeDriverLicense; + } + return ALUniversalIDScanTypeGeneric; +} + +- (NSDictionary *)getConfigDictForFrontIDScanner { + NSError *error = nil; + NSString *path = [[NSBundle mainBundle] pathForResource: + [self fileNameForCurrentScanModeIsFront:YES] ofType:@"json"]; + NSData *jsonFile = [NSData dataWithContentsOfFile:path]; + NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData:jsonFile + options:NSJSONReadingMutableContainers + error:&error]; + return configDict; +} + +- (NSDictionary *)getConfigDictForBackIDScanner { + NSError *error = nil; + NSString *path = [[NSBundle mainBundle] pathForResource: + [self fileNameForCurrentScanModeIsFront:NO] ofType:@"json"]; + NSData *jsonFile = [NSData dataWithContentsOfFile:path]; + NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData:jsonFile + options:NSJSONReadingMutableContainers + error:&error]; + return configDict; +} + +- (NSString *)fileNameForCurrentScanModeIsFront:(BOOL)isFront { + switch (self.scanType) { + case ALUniversalIDScanTypeIDCard: + return isFront ? kFileNameIdFront : kFileNameIdCompositeBack; + case ALUniversalIDScanTypeDriverLicense: + return isFront ? kFileNameDriverLicenseFront : kFileNameDriverLicenseCompositeBack; + case ALUniversalIDScanTypeGeneric: + return isFront ? kFileNameUniversalIdFront : kFileNameUniversalIdCompositeBack; + } +} + +- (void)setupNavigationBar { + UIBarButtonItem *infoBarItem; + UIBarButtonItem *scriptSelectionBarItem; + + NSMutableArray *barButtonItems = [NSMutableArray array]; + + if (![[[NSBundle mainBundle] bundleIdentifier] localizedCaseInsensitiveContainsString:@"bundle"]) { + UIButton *infoButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 40)]; + [infoButton setTintColor:[UIColor AL_BackButton]]; + [infoButton setImage:[UIImage imageNamed:@"info"] forState:UIControlStateNormal]; + [infoButton addTarget:self action:@selector(infoPressed:) forControlEvents:UIControlEventTouchUpInside]; + infoBarItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton]; + } + + if (self.scriptType == ALScriptTypeLatin) { + scriptSelectionBarItem = [ALScriptSelectionViewController createBarButtonForScriptSelection:self]; + } + + if (scriptSelectionBarItem) { + [barButtonItems addObject:scriptSelectionBarItem]; + } + + if (infoBarItem) { + [barButtonItems addObject:infoBarItem]; + } + + UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; + [barButtonItems addObject:flexibleSpace]; + + self.navigationItem.rightBarButtonItems = barButtonItems; +} + +- (void)showScanOptionsDialog { + ALScriptType scriptType = self.scriptType; + ALUniversalIDScanConfig *config = [[ALUniversalIDScanConfig alloc] initWithRegions:@[] // regions is no longer used here + scriptType:scriptType]; + [self startScanConfigurator:config]; +} + +- (void)startScanConfigurator:(ALUniversalIDScanConfig *)config { + if (!_configController) { + _configController = [[ALUniversalIDScanConfigController alloc] initWithPresentingVC:self + countryHelper:_countryIDHelper + selectMode:ALConfigDialogTypeScriptSelection + delegate:self]; + } + self.configController.config = config; + [self.configController start]; +} + +- (IBAction)infoPressed:(id)sender { + [self presentViewController:[[ALTutorialViewController alloc] init] animated:YES completion:nil]; +} + +- (IBAction)selectScriptPressed:(id)sender { + [self showScanOptionsDialog]; +} + +- (IBAction)settingsPressed:(id)sender { + [self showScanOptionsDialog]; +} - // Handle a UniversalID result - ALUniversalIDIdentification *identification = (ALUniversalIDIdentification *)scanResult.result; - NSMutableString *resultHistoryString = [NSMutableString string]; - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - - [resultData addObjectsFromArray:[ALUniversalIDFieldnameUtil addIDSubResult:identification titleSuffix:@"" resultHistoryString:resultHistoryString]]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Detected Country" value:identification.layoutDefinition.country]]; - resultData = [ALUniversalIDFieldnameUtil sortResultDataUsingFieldNamesWithSpace:resultData].mutableCopy; - NSString *jsonString = [self jsonStringFromResultData:resultData]; +// MARK: - Configure UI + +- (void)openContactEmailWithDeployment:(NSString *)deployment error:(NSString *)error { + if (![MFMailComposeViewController canSendMail]) { + [self showAlertWithTitle:@"Mail Settings" + message:@"Please set up an email account in the Settings App"]; + return; + } + MFMailComposeViewController* composeVC = [[MFMailComposeViewController alloc] init]; + composeVC.mailComposeDelegate = self; + + // Configure the fields of the interface + [composeVC setToRecipients:@[@"support@anyline.com"]]; + [composeVC setSubject:[NSString stringWithFormat:@"%@ Support", + [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleDisplayName"]]]; + NSString *msgBody = [NSString stringWithFormat:kRequestSupportMsgBodyFmt, deployment, error]; + [composeVC setMessageBody:msgBody isHTML:YES]; + + [self presentViewController:composeVC animated:YES completion:nil]; +} + +- (void)configureSelectNoOfSidesButton { + UIButton *selectSides = [[UIButton alloc] init]; + CGFloat margin = 20; + CGFloat buttonWidth = 98; + CGFloat buttonHeight = 36; + selectSides.layer.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.75].CGColor; + selectSides.layer.cornerRadius = round(buttonHeight / 2.0f); + selectSides.layer.borderWidth = 0.6; + selectSides.layer.borderColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor; + [selectSides setTitle:@"One Sided" forState:UIControlStateNormal]; + [selectSides setTitle:@"Two Sided" forState:UIControlStateSelected]; + [selectSides setSelected:NO]; + [[selectSides titleLabel] setFont:[UIFont AL_proximaRegularWithSize:14]]; + [self.view addSubview:selectSides]; + selectSides.translatesAutoresizingMaskIntoConstraints = NO; + + [selectSides.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:-margin].active = YES; + [selectSides.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:margin].active = YES; + [selectSides.widthAnchor constraintEqualToConstant:buttonWidth].active= YES; + [selectSides.heightAnchor constraintEqualToConstant:buttonHeight].active = YES; + + [selectSides addTarget:self action:@selector(changeSelectedSides:) forControlEvents:UIControlEventTouchUpInside]; +} + +- (IBAction)changeSelectedSides:(UIButton *)sender { + _isTwoSided = !sender.isSelected; + [sender setSelected:_isTwoSided]; + [self startTroubleScanningTimeout]; +} + +- (UIView *)createScanHintView:(CGFloat)hintMargin { + UILabel * hintViewLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + UIView * hintView = [[UILabel alloc] initWithFrame:CGRectZero]; + hintView.alpha = 0; + hintViewLabel.text = kScanIDFrontLabelText; + [hintViewLabel sizeToFit]; + [hintView addSubview:hintViewLabel]; + hintView.frame = UIEdgeInsetsInsetRect(hintViewLabel.frame, UIEdgeInsetsMake(-hintMargin, -hintMargin, -hintMargin, -hintMargin)); + hintView.center = CGPointMake(self.view.center.x, 0); + hintViewLabel.translatesAutoresizingMaskIntoConstraints = NO; + [hintViewLabel.centerYAnchor constraintEqualToAnchor:hintView.centerYAnchor constant:0].active = YES; + [hintViewLabel.centerXAnchor constraintEqualToAnchor:hintView.centerXAnchor constant:0].active = YES; + hintView.layer.cornerRadius = 8; + hintView.layer.masksToBounds = YES; + hintView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; + hintViewLabel.textColor = [UIColor whiteColor]; + + // We shouldn't do this here: + self.hintViewLabel = hintViewLabel; + + return hintView; +} + +- (void)updateHintPosition:(CGFloat)newPosition { + self.hintView.center = CGPointMake(self.hintView.center.x, newPosition); + self.hintView.alpha = 1.0; +} + +- (void)showPrepareForBacksideScanningHintWithDuration:(NSTimeInterval)secondsToDisplay complete:(void (^ __nullable)(void))complete { + [self updateScanLabelWithStringWithAnimation:kScanIDBackLabelText]; + self.flipIDAnimationView.hidden = NO; + [self.flipIDAnimationView startAnimating]; __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:scanResult.image scanPlugin:anylineIDScanPlugin viewPlugin:self.scanViewPlugin completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = scanResult.image; - vc.imageFace = [scanResult.result faceImage]; + dispatch_time_t gifTimeout = dispatch_time(DISPATCH_TIME_NOW, secondsToDisplay * NSEC_PER_SEC); + dispatch_after(gifTimeout, dispatch_get_main_queue(), ^(void){ + weakSelf.flipIDAnimationView.hidden = YES; + complete(); + }); +} + +// MARK: - ALScanPluginDelegate + +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + + __weak ALUniversalIDScanViewController *weakSelf = self; + + // if barcode result is found, store it + if (scanResult.pluginResult.barcodeResult) { + self.barcodeResult = scanResult.pluginResult.barcodeResult; + } + + ALUniversalIDResult *IDResult = scanResult.pluginResult.universalIDResult; + + [self addResultsAtIndex:IDResult.resultEntryList.mutableCopy]; + + NSArray *pdf417ResultsList = self.barcodeResult.resultEntryList; + if (pdf417ResultsList.count > 0) { + [self addResultsAtIndex:pdf417ResultsList.mutableCopy]; + } + + if (scanResult.faceImage && !self.faceImage) { // save only the first face image that is scanned + // front side will have a first chance to do so, then the back side. + // so if both sides have photos, the front pic will be used. + self.faceImage = scanResult.faceImage; + } + + if (_isTwoSided && !_hasScannedSecondSide) { // front scan + turn over + + self.frontScanImage = scanResult.croppedImage; + [self stopTroubleScanningTimeout]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self showPrepareForBacksideScanningHintWithDuration:2.0 complete:^{ + [weakSelf createBackScanViewPlugin]; + weakSelf.hasScannedSecondSide = YES; + [weakSelf startTroubleScanningTimeout]; + }]; + }); + } else { + + // if it was barcode, wait for ID before returning + [self stopTroubleScanningTimeout]; + + if (IDResult) { + self.backsideIDResult = IDResult; + self.backScanImage = scanResult.croppedImage; + } + + if (!_isTwoSided) { + // one sided + [self finishBacksideScanning]; + } else { + // two sided + if ([self scanViewPluginIsComposite]) { + // backside is composite (ID + Barcode) + if (self.backsideIDResult && !self.barcodeResult) { + [self startBacksideScanTimeout]; + } else if (self.barcodeResult && !self.backsideIDResult) { + [self startBacksideScanTimeout]; + } else { + [self finishBacksideScanning]; + } + } else { + // backside is plain / not composite + [self finishBacksideScanning]; + } + } + } +} + +- (BOOL)scanViewPluginIsComposite { + // it's talking about the current one, whether it be front side (single-sided) or + // backside (when in double-side scanning) + return ![self.scanViewPlugin isKindOfClass:ALScanViewPlugin.class]; +} + +- (void)finishBacksideScanning { + [self stopBacksideScanTimeout]; + // show the results assuming one of two + // its a composite, you want the first child + + ALScanPlugin *scanPlugin; + if ([self.scanViewPlugin isKindOfClass:ALScanViewPlugin.class]) { + scanPlugin = [(ALScanViewPlugin *)self.scanViewPlugin scanPlugin]; + } else { + scanPlugin = [(ALScanViewPlugin *)[self.scanViewPlugin children][0] scanPlugin]; + } + + NSMutableArray *images = [NSMutableArray array]; + if (self.frontScanImage) { + [images addObject:self.frontScanImage]; + } + if (self.backScanImage) { + [images addObject:self.backScanImage]; + } + + __weak __block typeof(self) weakSelf = self; + + NSString *resultJSONStr = [ALResultEntry JSONStringFromList:self.resultData]; + [self anylineDidFindResult:resultJSONStr + barcodeResult:@"" + faceImage:self.faceImage + images:images + scanPlugin:scanPlugin + viewPlugin:self.scanViewPlugin completion:^{ + dispatch_time_t gifTimeout = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC); + dispatch_after(gifTimeout, dispatch_get_main_queue(), ^(void){ + ALResultViewController *vc = [[ALResultViewController alloc] + initWithResults:weakSelf.resultData]; + vc.imageFace = weakSelf.faceImage; + vc.imagePrimary = weakSelf.frontScanImage; + vc.imageSecondary = weakSelf.backScanImage; + vc.showDisclaimer = YES; + vc.isRightToLeft = weakSelf.scriptType == ALScriptTypeArabic; + UIViewController *topVC = [weakSelf.navigationController topViewController]; + if ([topVC isKindOfClass:[ALUniversalIDScanViewController class]]) { + [weakSelf.navigationController pushViewController:vc animated:YES]; + } + }); + }]; +} + + +// MARK: - GIF Animation for Backside + +- (UIImageView *)flipIDAnimationView { + if (!_flipIDAnimationView) { + UIImage *flipAnimation = [UIImage animatedImageNamed:@"flip-id-" duration:1.0f]; + UIImageView *imgView = [[UIImageView alloc] init]; + imgView.image = flipAnimation; + + NSMutableArray *animatedImagesArray = [NSMutableArray array]; + for (int i = 0; i <= 150; i++) { + [animatedImagesArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"flip-id-%d%@", i, @".png"]]]; + } + + imgView.animationImages = animatedImagesArray; + imgView.animationDuration = 3.0f; + imgView.animationRepeatCount = 1; + imgView.hidden = YES; + + imgView.image = [imgView.animationImages lastObject]; // maybe we won't need this... + [imgView startAnimating]; + + imgView.translatesAutoresizingMaskIntoConstraints = NO; + _flipIDAnimationView = imgView; + } + // original GIF size: 500 x 310 + + [self.view addSubview:_flipIDAnimationView]; + [_flipIDAnimationView.centerXAnchor constraintEqualToAnchor:self.scanView.centerXAnchor constant:0].active = YES; // -90 + [_flipIDAnimationView.centerYAnchor constraintEqualToAnchor:self.scanView.centerYAnchor constant:0].active = YES; // -160 + [_flipIDAnimationView.widthAnchor constraintEqualToConstant:320].active = YES; // 250 + [_flipIDAnimationView.heightAnchor constraintEqualToConstant:180].active = YES; // 155 + + return _flipIDAnimationView; +} - [weakSelf.navigationController pushViewController:vc animated:YES]; +- (void)setupBackScanningGuideAnimation { + + if (!_flipIDAnimationView) { // create it the very first time + UIImage *flipAnimation = [UIImage animatedImageNamed:@"flip-id-" duration:1.0f]; + UIImageView *imgView = [[UIImageView alloc] init]; + imgView.image = flipAnimation; + + NSMutableArray *animatedImagesArray = [NSMutableArray array]; + for (int i = 0; i <= 150; i++) { + [animatedImagesArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"flip-id-%d%@", i, @".png"]]]; + } + + imgView.animationImages = animatedImagesArray; + imgView.animationDuration = 3.0f; + imgView.animationRepeatCount = 1; + imgView.hidden = YES; + + imgView.image = [imgView.animationImages lastObject]; // maybe we won't need this... + [imgView startAnimating]; + + imgView.translatesAutoresizingMaskIntoConstraints = NO; + _flipIDAnimationView = imgView; + } + // original GIF size: 500 x 310 + + [self.view addSubview:_flipIDAnimationView]; + [_flipIDAnimationView.centerXAnchor constraintEqualToAnchor:self.scanView.centerXAnchor constant:0].active = YES; // -90 + [_flipIDAnimationView.centerYAnchor constraintEqualToAnchor:self.scanView.centerYAnchor constant:0].active = YES; // -160 + [_flipIDAnimationView.widthAnchor constraintEqualToConstant:320].active = YES; // 250 + [_flipIDAnimationView.heightAnchor constraintEqualToConstant:180].active = YES; // 155 +} + +// MARK: - Handle Scanning Issues + +- (void)startTroubleScanningTimeout { + [self.troubleScanningTimeout invalidate]; + self.troubleScanningTimeout = [NSTimer scheduledTimerWithTimeInterval:kUniversalIDTroubleScanningTimeoutTime + target:self + selector:@selector(showTroubleScanningDialog) + userInfo:nil + repeats:NO]; +} + +- (void)startBacksideScanTimeout { + [self.backsideScanTimeout invalidate]; + self.backsideScanTimeout = [NSTimer scheduledTimerWithTimeInterval:kUniversalIDBacksideScanTimeout + target:self + selector:@selector(finishBacksideScanning) + userInfo:nil + repeats:NO]; +} + +- (void)stopTroubleScanningTimeout { + [self.troubleScanningTimeout invalidate]; + self.troubleScanningTimeout = nil; + self.troubleScanningCounter = 0; +} + +- (void)stopBacksideScanTimeout { + [self.backsideScanTimeout invalidate]; + self.backsideScanTimeout = nil; +} + +- (void)showTroubleScanningDialog { + [self.scanView stopCamera]; + // Note: because sometimes a race condition can cause the timeout invalidation to happen + // after the ResultsVC has been pushed and is onscreen (we don't want to see the alert there) + if ([self.navigationController topViewController] != self) { + return; + } + + // if you couldn't show the alert because there's a different dialog + // (e.g. the scan config dialog) presented + if (self.presentedViewController != nil) { return; } + + NSMutableArray *actions = [[NSMutableArray alloc] init]; + + NSString *titleText = kTroubleScanningAlertDefaultTitleText; + NSString *messageText = kTroubleScanningAlertDefaultMessageText; + NSString *actionText = kTroubleScanningAlertDefaultActionText; + + self.troubleScanningCounter++; + if (self.troubleScanningCounter < kUniversalIDTroubleScanningCounter) { + // a few more chances given to try again, still using the same plugin + + __weak __block typeof(self) weakSelf = self; + UIAlertAction *tryAgain = [UIAlertAction actionWithTitle:actionText + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + [weakSelf resumeScanning]; + }]; + [actions addObject:tryAgain]; + + [self showAlertControllerWithTitle:titleText message:messageText actions:actions]; + } else { + // no more tries remaining. On OK, start all over if still on frontside, or proceed to the + // results if on backside. + BOOL isDriverLicenseMode = self.scanType == ALUniversalIDScanTypeDriverLicense; + [self showScanFailureAlertIsDriverLicenseMode:isDriverLicenseMode + showMoreInfoOption:YES actionTitle:kActionTitleOK complete:^{ + }]; + } +} + +- (void)returnFromBackground { + [self resumeScanning]; +} + +- (void)resumeScanning { + [self createFrontScanViewPlugin]; + [self startTroubleScanningTimeout]; +} + +// MARK: - Handle Scan Issues + +- (void)showScanFailureAlertIsDriverLicenseMode:(BOOL)isDriverLicenseMode + showMoreInfoOption:(BOOL)showMoreInfoOption + actionTitle:(NSString *)actionTitle + complete:(void (^ __nullable)(void))complete { + + NSString *titleText = kTroubleScanningAlertDefaultTitleText; + NSString *messageText = kTroubleScanningAlertDefaultMessageText; + + NSMutableArray *actions = [[NSMutableArray alloc] init]; + + if (isDriverLicenseMode) { + titleText = kTroubleScanningAlertBadConditionTitleText; + messageText = kTroubleScanningAlertBadConditionMessageText; + } else { + titleText = kTroubleScanningAlertUnknownIDTitleText; + messageText = kTroubleScanningAlertUnknownIDMessageText; + } + + if (showMoreInfoOption) { + UIAlertAction *moreInfo = [UIAlertAction actionWithTitle:kActionTitleMoreInfo + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + [[self class] loadDocumentationWebPage]; + // Since you'll be leaving the app into a browser, make sure `resumeScanning` gets + // called when returning to it + }]; + [actions addObject:moreInfo]; + } + + UIAlertAction *ok = [UIAlertAction actionWithTitle:actionTitle + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + complete(); }]; + [actions addObject:ok]; + + [self showAlertControllerWithTitle:titleText message:messageText actions:actions]; +} + +- (void)updateScanLabelWithStringWithAnimation:(NSString *)labelText { + self.hintViewLabel.transform = CGAffineTransformScale(self.hintViewLabel.transform, .25, .25); + self.hintViewLabel.text = labelText; + [UIView animateWithDuration:0.4 animations:^{ + self.hintViewLabel.transform = CGAffineTransformScale(self.hintViewLabel.transform, 4.5, 4.5); + } completion:^(BOOL finished) { + [UIView animateWithDuration:0.15 animations:^{ + self.hintViewLabel.transform = CGAffineTransformScale(self.hintViewLabel.transform, 0.875, 0.875); + } completion:^(BOOL finished) { + self.hintViewLabel.transform = CGAffineTransformScale(self.hintViewLabel.transform, 1.0, 1.0); + [self.hintViewLabel sizeToFit]; + }]; + }]; +} + + +// MARK: - ALUniversalIDScanConfigControllerDelegate + +- (void)idScanConfigController:(ALUniversalIDScanConfigController *)controller finishedWithUpdatedConfig:(BOOL)hasUpdates { + if (!hasUpdates) { + [self.scanView startCamera]; + return; + } + ALUniversalIDScanConfig *config = controller.config; + self.scriptType = config.scriptType; + [self createFrontScanViewPlugin]; + [self startTroubleScanningTimeout]; +} + +- (void)idScanConfigController:(ALUniversalIDScanConfigController *)controller + isChangingScript:(ALScriptType)newScript { + [_countryIDHelper setScriptType:newScript]; } -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.scanPlugin]; +// MARK: - ResultData Processing + +- (void)addResultAtIndex:(ALResultEntry *)entry forFieldName:(NSString *)fieldName withOffset:(NSUInteger)offset { + for (ALResultEntry *entryTemp in self.resultData) { + if ([entryTemp.title localizedCaseInsensitiveCompare:entry.title] == NSOrderedSame) { + [entry setValue:entry.value]; + return; + } } - + [self.resultData addObject:entry]; } -- (void)anylineScanPlugin:(ALAbstractScanPlugin * _Nonnull)anylineScanPlugin - runSkipped:(ALRunSkippedReason * _Nonnull)runSkippedReason { - if (runSkippedReason.reason == ALRunFailureIDTypeNotSupported) { - [self updateScanWarnings:ALWarningStateIDNotSupported]; +- (void)addResultsAtIndex:(NSMutableArray *)entryArray { + if (self.resultData.count > 0) { + for (ALResultEntry *entryTemp in entryArray) { + NSUInteger index = [self.resultData indexOfObjectPassingTest:^BOOL(ALResultEntry * _Nonnull entry, NSUInteger idx, BOOL * _Nonnull stop) { + return ([entryTemp.title localizedCaseInsensitiveCompare:entry.title] == NSOrderedSame); + }]; + if (index != NSNotFound) { + [[self.resultData objectAtIndex:index] setValue:entryTemp.value]; + } else { + [self.resultData addObject:entryTemp]; + } + } + } else { + [self.resultData addObjectsFromArray:entryArray]; } } -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; +// MARK: - Miscellaneous + +- (void)dialogStarted { + [self.scanView stopCamera]; + [self stopTroubleScanningTimeout]; +} + +- (void)dialogCancelled { + [self.scanView startCamera]; + [self startTroubleScanningTimeout]; +} + ++ (void)loadDocumentationWebPage { + NSURL *url = [NSURL URLWithString:kDocumentationSupportedIdsURL]; + [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil]; +} + +- (void)subscribeToAppLifecycleEvents { + if (@available(iOS 13, *)) { + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(returnFromBackground) + name:UISceneWillEnterForegroundNotification + object:nil]; + } else { + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(returnFromBackground) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + } } @end diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewControllerFrontAndBack.h b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewControllerFrontAndBack.h deleted file mode 100644 index 3ed17f1b2..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewControllerFrontAndBack.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// ALUniversalIDScanViewControllerFrontAndBack.h -// AnylineExamples -// -// Created by Philipp on 16.09.20. -// - -#import "ALBaseScanViewController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface ALUniversalIDScanViewControllerFrontAndBack : ALBaseScanViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewControllerFrontAndBack.m b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewControllerFrontAndBack.m deleted file mode 100644 index 5a4b0e791..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/ALUniversalIDScanViewControllerFrontAndBack.m +++ /dev/null @@ -1,497 +0,0 @@ -// -// ALUniversalIDScanViewControllerFrontAndBack.h -// AnylineExamples -// -// Created by Philipp on 16.09.20. -// - -#import "ALUniversalIDScanViewControllerFrontAndBack.h" -#import "AnylineExamples-Swift.h" -#import "ALUniversalIDFieldnameUtil.h" -#import "ALBarcodeResultUtil.h" - -NSString * const kScanIDFrontLabelText = @"Scan your ID"; -NSString * const kScanIDBackLabelText = @"Turn ID over"; - -NSString * const kScanViewPluginFrontID = @"IDPluginFront"; -NSString * const kScanViewPluginBackID = @"IDPluginBack"; - -NSString * const kScanViewPluginBarcodeID = @"BarcodePlugin"; - -NSString * const kScanViewPluginSerialID = @"SerialPlugin"; -NSString * const kScanViewPluginParallelID = @"ParallelPlugin"; - -NSString * const kCameraConfigJSON = @"universal_id_camera_config"; -NSString * const kFlashConfigJSON = @"universal_id_flash_config"; - -NSInteger const kUniversalIDSerialScanTimeout = 10; -NSInteger const kUniversalIDBacksideScanTimeout = 5; -NSInteger const kBarcodeBacksideScanTimeout = 0.7; - -@interface ALUniversalIDScanViewControllerFrontAndBack () - -@property (nonatomic, strong) ALIDScanPlugin *scanPluginFront; -@property (nonatomic, strong) ALIDScanViewPlugin *scanViewPluginFront; - -@property (nonatomic, strong) ALIDScanPlugin *scanPluginBack; -@property (nonatomic, strong) ALIDScanViewPlugin *scanViewPluginBack; - -@property (nonatomic, strong) ALBarcodeScanPlugin *barcodeScanPlugin; -@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin; - -@property (nonatomic, strong) ALSerialScanViewPluginComposite *serialScanViewPlugin; -@property (nonatomic, strong) ALParallelScanViewPluginComposite *parallelScanViewPlugin; - -@property (nullable, nonatomic, strong) ALScanView *scanView; - -@property (nonatomic, strong) NSLayoutConstraint *cutoutGuideYOffsetConstraint; - -@property (nullable, nonatomic, strong) NSMutableArray *resultData; - -@property (nullable, nonatomic, strong) UIImage *frontScanImage; -@property (nullable, nonatomic, strong) UIImage *backScanImage; -@property (nullable, nonatomic, strong) UIImage *faceScanImage; - -@property (nullable, nonatomic, strong) NSTimer *scanTimeoutFront; -@property (nullable, nonatomic, strong) NSTimer *scanTimeoutBack; - -@property (nullable, nonatomic, strong) GifuWrapper *gifImageView; - -@property (nonatomic, strong) ALBarcodeResult *detectedBarcode; -@property (nonatomic, strong) NSMutableString *resultHistoryString; - -@property (nullable, nonatomic, strong) UIView *hintView; -@property (nullable, nonatomic, strong) UILabel *hintViewLabel; - -@end - - -@implementation ALUniversalIDScanViewControllerFrontAndBack - -// MARK: - UIViewController Lifecycle - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = (self.title && self.title.length > 0) ? self.title : @"Universal ID"; - - NSError *error = nil; - - // Front ID scan plugin and scan view plugin - NSDictionary *idScanConfigDict = [[self class] configDictForIDScanPlugin]; - self.scanViewPluginFront = (ALIDScanViewPlugin *)[ALAbstractScanViewPlugin - scanViewPluginForConfigDict:idScanConfigDict - delegate:self - error:&error]; - NSAssert(self.scanViewPluginFront, @"Setup Error: %@", error.debugDescription); - - [self.scanViewPluginFront addScanViewPluginDelegate:self]; - - ALScanViewPluginConfig *configFront = self.scanViewPluginFront.scanViewPluginConfig; - configFront.cutoutConfig.animation = ALCutoutAnimationFade; - [self.scanViewPluginFront setScanViewPluginConfig:configFront]; - - self.scanPluginFront = self.scanViewPluginFront.idScanPlugin; - [self.scanPluginFront setPluginID:kScanViewPluginFrontID]; - [self.scanPluginFront addInfoDelegate:self]; - - // Back ID scan and scan view plugin (config is almost identical with that of the front ID) - self.scanViewPluginBack = (ALIDScanViewPlugin *)[ALAbstractScanViewPlugin - scanViewPluginForConfigDict:idScanConfigDict - delegate:self - error:&error]; - NSAssert(self.scanViewPluginBack, @"Setup Error: %@", error.debugDescription); - [self.scanViewPluginBack addScanViewPluginDelegate:self]; - ALScanViewPluginConfig *configBack = self.scanViewPluginFront.scanViewPluginConfig; - configBack.cutoutConfig.animation = ALCutoutAnimationFade; - [self.scanViewPluginFront setScanViewPluginConfig:configBack]; - - self.scanPluginBack = self.scanViewPluginBack.idScanPlugin; - [self.scanPluginBack setPluginID:kScanViewPluginBackID]; - [self.scanPluginBack addInfoDelegate:self]; - - // Barcode (to be paired with back id in a parallel scan) - ALBarcodeScanPlugin *barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] - initWithPluginID:kScanViewPluginBarcodeID - delegate:self - error:&error]; - - [barcodeScanPlugin setBarcodeFormatOptions:@[kCodeTypePDF417]]; - [barcodeScanPlugin setParsePDF417:YES]; - - self.barcodeScanPlugin = barcodeScanPlugin; - - ALBarcodeScanViewPlugin *barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] - initWithScanPlugin:barcodeScanPlugin]; - - self.barcodeScanViewPlugin = barcodeScanViewPlugin; - - ALScanViewPluginConfig *barcodeScanViewConfig = [ALScanViewPluginConfig defaultBarcodeConfig]; - barcodeScanViewConfig.cutoutConfig.strokeWidth = 0; - barcodeScanViewConfig.cutoutConfig.backgroundColor = [UIColor clearColor]; - barcodeScanViewConfig.scanFeedbackConfig.vibrateOnResult = NO; - barcodeScanViewConfig.scanFeedbackConfig.strokeWidth = 0; - - self.barcodeScanViewPlugin.scanViewPluginConfig = barcodeScanViewConfig; - - self.parallelScanViewPlugin = [[ALParallelScanViewPluginComposite alloc] initWithPluginID:kScanViewPluginParallelID]; - - self.parallelScanViewPlugin.optionalTimeoutDelay = @(kBarcodeBacksideScanTimeout); - [self.parallelScanViewPlugin addDelegate:self]; - - [self.parallelScanViewPlugin addPlugin:self.scanViewPluginBack]; - - self.barcodeScanViewPlugin.isOptional = YES; - [self.parallelScanViewPlugin addPlugin:self.barcodeScanViewPlugin]; - - // Combine front and back (which also includes barcode) in a SerialScanViewPlugin - ALSerialScanViewPluginComposite *serialScanViewPlugin = [[ALSerialScanViewPluginComposite alloc] - initWithPluginID:kScanViewPluginSerialID]; - - serialScanViewPlugin.timeout = @(kUniversalIDBacksideScanTimeout); - [serialScanViewPlugin addPlugin:self.scanViewPluginFront]; - [serialScanViewPlugin addPlugin:self.parallelScanViewPlugin]; - - self.serialScanViewPlugin = serialScanViewPlugin; - [serialScanViewPlugin addDelegate:self]; - - // Create ScanView and add our ScanViewPlugin Composite - CGRect frame = [self scanViewFrame]; - - NSString *configPath = [[NSBundle mainBundle] pathForResource:kCameraConfigJSON ofType:@"json"]; - ALCameraConfig *cameraConfig = [[ALCameraConfig alloc] initWithJsonFilePath:configPath]; - - configPath = [[NSBundle mainBundle] pathForResource:kFlashConfigJSON ofType:@"json"]; - ALFlashButtonConfig *flashConfig = [[ALFlashButtonConfig alloc] initWithJsonFilePath:configPath]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame - scanViewPlugin:self.serialScanViewPlugin - cameraConfig:cameraConfig - flashButtonConfig:flashConfig]; - - self.controllerType = ALScanHistoryUniversalID; - - // After setup is complete we add the scanView to the view of this view controller - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - - // Start Camera - [self.scanView startCamera]; - [self startListeningForMotion]; - - // Add scan hint label - self.hintView = [[self class] createScanHintViewCenteredInView:self.view]; - [self.view addSubview:self.hintView]; - - self.hintView.translatesAutoresizingMaskIntoConstraints = NO; - - [self.hintView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES; - self.cutoutGuideYOffsetConstraint = [self.hintView.topAnchor constraintEqualToAnchor:self.view.topAnchor]; - self.cutoutGuideYOffsetConstraint.active = YES; - - self.hintViewLabel = [[self class] createScanHintViewLabelWithText:kScanIDFrontLabelText inView:self.hintView margin:7.0f]; - - [self.hintView.heightAnchor constraintEqualToAnchor:self.hintViewLabel.heightAnchor constant:20].active = YES; - [self.hintView.widthAnchor constraintEqualToAnchor:self.hintViewLabel.widthAnchor constant:20].active = YES; - - self.gifImageView = [[GifuWrapper alloc] init]; - self.gifImageView.contentMode = UIViewContentModeScaleAspectFit; - [self.scanView addSubview:self.gifImageView]; - self.gifImageView.alpha = 0.80; - self.gifImageView.layer.cornerRadius = 5.0; - self.gifImageView.layer.masksToBounds = YES; - - CGRect gifFrame = CGRectMake(0, 0, 500, 310); - self.gifImageView.frame = gifFrame; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self startAnylineScanner]; -} - -- (void)viewWillDisappear:(BOOL)animated { - NSError *error; - [self.serialScanViewPlugin stopAndReturnError:&error]; - [self resetResultData]; - [super viewWillDisappear:animated]; -} - -// MARK: - Plugin Management - -- (void)startAnylineScanner { - NSError *error; - BOOL success = [self.serialScanViewPlugin startAndReturnError:&error]; - if (!success) { - - __weak __block typeof(self) weakSelf = self; - [self showAlertForScanningError:error completion:^{ - // Prevent the trouble scanning timeout timer from setting off - // - // NOTE: this won't help with the exceptional instance of user going to the - // the univ-id first thing on new install, and the user sitting on the - // request camera permission alert that comes out. But it will absolutely - // work when the user had already previously revoked / denied the camera - // access permission before entering the screen. - [weakSelf.scanTimeoutFront invalidate]; - [weakSelf.scanTimeoutBack invalidate]; - weakSelf.scanTimeoutFront = nil; - weakSelf.scanTimeoutBack = nil; - } dismissHandler:^{ - [weakSelf.navigationController popViewControllerAnimated:YES]; - }]; - } - [self resetResultData]; - - self.scanTimeoutFront = [self startTimeout:kUniversalIDSerialScanTimeout - scanViewPlugin:self.scanViewPluginFront]; - -} - -- (void)prepareForBacksideScanWithDelay:(NSTimeInterval)secondsToDisplay - completion:(void (^ __nullable)(void))completion { - [self updateScanLabelWithStringWithAnimation:kScanIDBackLabelText]; - self.gifImageView.hidden = false; - [self hideGIFView:false]; - [self.gifImageView startGIFWithGifName:@"flip_id" loopCount:1]; - if (completion == nil) { - return; - } - __weak __block typeof(self) weakSelf = self; - dispatch_time_t gifTimeout = dispatch_time(DISPATCH_TIME_NOW, secondsToDisplay * NSEC_PER_SEC); - dispatch_after(gifTimeout, dispatch_get_main_queue(), ^(void){ - [weakSelf.gifImageView stopGIF]; - [weakSelf hideGIFView:true]; - completion(); - }); -} - -- (NSTimer *)startTimeout:(NSTimeInterval)timeoutInterval scanViewPlugin:(ALAbstractScanViewPlugin *)scanViewPlugin { - return [NSTimer scheduledTimerWithTimeInterval:timeoutInterval - target:self - selector:@selector(scanningTimedOut:) - userInfo:@{ @"plugin": scanViewPlugin } - repeats:NO]; -} - - -- (void)scanningTimedOut:(NSTimer *)timer { - ALAbstractScanViewPlugin *scanViewPlugin = [[timer userInfo] valueForKey:@"plugin"]; - [self timer:timer timedOutWithPlugin:scanViewPlugin]; -} - -// MARK: - Scan View Plugin Delegate Methods - -- (void)timer:(NSTimer *)timer timedOutWithPlugin:(ALAbstractScanViewPlugin *)scanViewPlugin { - if (timer == self.scanTimeoutFront) { // front scan timed out, should move to back side - __weak __block typeof(self) weakSelf = self; - [self prepareForBacksideScanWithDelay:0.3 completion:^{ - NSError *error; - [weakSelf.serialScanViewPlugin startFromID:kScanViewPluginParallelID andReturnError:&error]; - weakSelf.scanTimeoutBack = [weakSelf startTimeout:kUniversalIDBacksideScanTimeout - scanViewPlugin:weakSelf.parallelScanViewPlugin]; - }]; - } else if (timer == self.scanTimeoutBack) { - [self presentResult]; - } -} - -- (void)anylineCompositeScanPlugin:(ALAbstractScanViewPluginComposite * _Nonnull)anylineCompositeScanPlugin - didFindResult:(ALCompositeResult * _Nonnull)scanResult { - if (anylineCompositeScanPlugin == self.serialScanViewPlugin) { - [self presentResult]; - } -} - -- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin * _Nonnull)anylineBarcodeScanPlugin - didFindResult:(ALBarcodeResult * _Nonnull)scanResult { - self.detectedBarcode = scanResult; -} - -- (void)anylineIDScanPlugin:(ALIDScanPlugin *)idScanPlugin didFindResult:(ALIDResult *)scanResult { - - ALUniversalIDIdentification *identification = (ALUniversalIDIdentification *)scanResult.result; - ALLayoutDefinition *layoutDefinition = identification.layoutDefinition; - - if (idScanPlugin == self.scanPluginFront) { - - [self.scanTimeoutFront invalidate]; - self.scanTimeoutFront = nil; - - [self.resultData addObjectsFromArray:[ALUniversalIDFieldnameUtil addIDSubResult:identification titleSuffix:@"" resultHistoryString:self.resultHistoryString]]; - [self.resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Detected Country" value:layoutDefinition.country]]; - [self.resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Detected Type" value:layoutDefinition.type]]; - - self.frontScanImage = scanResult.image; - self.faceScanImage = [scanResult.result faceImage]; - - __weak __block typeof(self) weakSelf = self; - [self prepareForBacksideScanWithDelay:0.3 completion:^{ - weakSelf.scanTimeoutBack = [weakSelf startTimeout:kUniversalIDBacksideScanTimeout - scanViewPlugin:weakSelf.parallelScanViewPlugin]; - }]; - - } else if (idScanPlugin == self.scanPluginBack) { - [self.resultData addObjectsFromArray:[ALUniversalIDFieldnameUtil - addIDSubResult:identification - titleSuffix:@" Back" - resultHistoryString:self.resultHistoryString]]; - [self.resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Detected Country" value:layoutDefinition.country]]; - [self.resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Detected Type" - value:layoutDefinition.type]]; - self.backScanImage = scanResult.image; - } -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info { - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.scanViewPluginFront]; - } -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - // Update Position of warning indicator - [self updateWarningPosition:cutoutRect.origin.y + cutoutRect.size.height + self.scanView.frame.origin.y + 80]; - [self updateHintPosition:cutoutRect.origin.y + self.scanView.frame.origin.y - 50]; - self.gifImageView.frame = CGRectMake(cutoutRect.origin.x, cutoutRect.origin.x, cutoutRect.size.width * 0.9, cutoutRect.size.height * 0.9); - self.gifImageView.center = CGPointMake(cutoutRect.origin.x + cutoutRect.size.width/2, cutoutRect.origin.y + cutoutRect.size.height/2); -} - -// MARK: - Handle Results - -- (void)presentResult { - - NSError *error; - - [self.serialScanViewPlugin stopAndReturnError:&error]; - - [self.scanTimeoutFront invalidate]; - [self.scanTimeoutBack invalidate]; - self.scanTimeoutFront = nil; - self.scanTimeoutBack = nil; - - NSString *barcodeString = @""; - if (self.detectedBarcode != nil) { - if (self.detectedBarcode.result.count > 0) { - barcodeString = [ALBarcodeResultUtil strValueFromBarcode:self.detectedBarcode.result[0]]; - } - [self.resultData addObjectsFromArray:[ALBarcodeResultUtil barcodeResultDataFromBarcodeResultArray:self.detectedBarcode.result]]; - } - - ALResultViewController *vc; - - if (self.resultData.count > 0) { - // Write result in history - [super anylineDidFindResult:self.resultHistoryString - barcodeResult:barcodeString - image:self.frontScanImage - scanPlugin:self.scanViewPluginFront.idScanPlugin - viewPlugin:self.serialScanViewPlugin completion:^{ - }]; - } else { - // We couldn't read the back side of the ID - ALResultEntry *barcodeResult = [[ALResultEntry alloc] initWithTitle:@"Result Data" value:@"This ID is either not supported yet or the scan wasn't captured properly.\n\nPlease try again." isAvailable:NO]; - [self.resultData addObject:barcodeResult]; - } - - vc = [[ALResultViewController alloc] initWithResults:self.resultData]; - vc.imagePrimary = self.frontScanImage; - vc.imageSecondary = self.backScanImage; - vc.imageFace = self.faceScanImage; - - [self resetResultData]; - [self.navigationController pushViewController:vc animated:YES]; -} - -- (void)resetResultData { - self.resultData = [NSMutableArray array]; - self.resultHistoryString = [NSMutableString string]; - self.detectedBarcode = nil; - self.backScanImage = nil; - self.frontScanImage = nil; - self.faceScanImage = nil; - self.scanTimeoutFront = nil; - self.scanTimeoutBack = nil; - self.hintViewLabel.text = kScanIDFrontLabelText; - [self.hintViewLabel sizeToFit]; - [self hideGIFView:true]; - [self.gifImageView stopGIF]; -} - -- (NSUInteger)getOrderedIndexForFieldName:(NSString *)fieldName withOffset:(NSUInteger)offset { - NSUInteger idx = [[ALUniversalIDFieldnameUtil fieldNamesOrderArray] indexOfObject:fieldName]; - if (idx == NSNotFound || idx >= ([self.resultData count]+offset)) { - return [self.resultData count]; - } - return idx+offset; -} - -- (void)addResultAtIndex:(ALResultEntry *)entry forFieldName:(NSString *)fieldName withOffset:(NSUInteger)offset { - [self.resultData insertObject:entry atIndex:[self getOrderedIndexForFieldName:fieldName withOffset:offset]]; -} - -// MARK: - Manage Onscreen Guides - -- (void)updateScanLabelWithStringWithAnimation:(NSString *)labelText { - self.hintViewLabel.text = labelText; - self.hintViewLabel.transform = CGAffineTransformScale(self.hintViewLabel.transform, .25, .25); - [UIView animateWithDuration:0.4 animations:^{ - self.hintViewLabel.transform = CGAffineTransformScale(self.hintViewLabel.transform, 4.5, 4.5); - } completion:^(BOOL finished) { - [UIView animateWithDuration:0.15 animations:^{ - self.hintViewLabel.transform = CGAffineTransformScale(self.hintViewLabel.transform, 0.875, 0.875); - } completion:^(BOOL finished) { - self.hintViewLabel.transform = CGAffineTransformScale(self.hintViewLabel.transform, 1.0, 1.0); - [self.hintViewLabel sizeToFit]; - }]; - }]; -} - -- (void)updateHintPosition:(CGFloat)newPosition { - self.cutoutGuideYOffsetConstraint.constant = newPosition; -} - -- (void)hideGIFView:(BOOL)willBeHidden { - [UIView transitionWithView:self.gifImageView duration:0.3 - options:UIViewAnimationOptionTransitionCrossDissolve animations:^(void) { - self.gifImageView.hidden = willBeHidden; - } completion:nil]; -} - - -// MARK: - Miscellaneous - -+ (NSDictionary *)configDictForIDScanPlugin { - NSError *error = nil; - NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:@"universal_id_config" ofType:@"json"]; - NSData *jsonFile = [NSData dataWithContentsOfFile:jsonFilePath]; - NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData:jsonFile - options:NSJSONReadingMutableContainers - error:&error]; - return configDict; -} - -+ (UIView *)createScanHintViewCenteredInView:(UIView * _Nonnull)view { - UIView *hintView = [[UILabel alloc] init]; - hintView.center = CGPointMake(view.center.x, 0); - hintView.layer.cornerRadius = 8; - hintView.layer.masksToBounds = true; - hintView.backgroundColor = [[UIColor darkTextColor] colorWithAlphaComponent:0.6]; - return hintView; -} - -+ (UILabel *)createScanHintViewLabelWithText:(NSString *)text inView:(UIView * _Nonnull)hintView margin:(CGFloat)margin { - UILabel *hintViewLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - hintViewLabel.text = text; - hintViewLabel.textColor = [UIColor lightTextColor]; - [hintViewLabel sizeToFit]; - - hintViewLabel.translatesAutoresizingMaskIntoConstraints = NO; - [hintView addSubview:hintViewLabel]; - [hintViewLabel.centerXAnchor constraintEqualToAnchor:hintView.centerXAnchor].active = YES; - [hintViewLabel.centerYAnchor constraintEqualToAnchor:hintView.centerYAnchor].active = YES; - - return hintViewLabel; -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/GifuWrapper.swift b/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/GifuWrapper.swift deleted file mode 100644 index cb519e915..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/ViewController/GifuWrapper.swift +++ /dev/null @@ -1,29 +0,0 @@ - // -// GifuWrapper.swift -// AnylineExamples -// -// Created by Philipp Müller on 18.09.20. -// -// This does nothing, but could be replaced with a wrapper for the Gifu library. -@objc -class GifuWrapper: UIImageView { - - override public func display(_ layer: CALayer) { - } - - @objc public func setGIF(gifName: String, loopCount: Int, frame: CGRect) { - self.frame = frame - } - - @objc public func startGIF(gifName: String, loopCount: Int) { - } - - @objc public func toggleAnimation() { - } - - @objc public func stopGIF() { - } - @objc public func startGIF() -> Double { - return 0.0 - } -} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_arabic_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_arabic_config.json deleted file mode 100644 index 07a0ca16f..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_arabic_config.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "viewPlugin" : { - "plugin":{ - "id":"ID", - "idPlugin": { - "universalIDConfig": { - "alphabet": "arabic", - "faceDetection": true, - "allowedLayouts": { - "mrz": [], - "idFront": [], - "drivingLicense": [] - }, - "idFront": { - "fullName": {"scanOption": 0, "minConfidence": 60}, - "dateOfBirth": {"scanOption": 0, "minConfidence": 60}, - "placeOfBirth": {"scanOption": 1, "minConfidence": 60}, - "dateOfExpiry": {"scanOption": 1, "minConfidence": 60}, - "documentNumber": {"scanOption": 0, "minConfidence": 60}, - "nationality": {"scanOption": 1, "minConfidence": 60} - }, - "drivingLicense": { - "fullName": {"scanOption": 0, "minConfidence": 60}, - "dateOfBirth": {"scanOption": 0, "minConfidence": 60}, - "placeOfBirth": {"scanOption": 1, "minConfidence": 60}, - "dateOfExpiry": {"scanOption": 1, "minConfidence": 60}, - "documentNumber": {"scanOption": 0, "minConfidence": 60}, - "nationality": {"scanOption": 0, "minConfidence": 60} - } - } - } - }, - "cutoutConfig" : { - "style": "animated_rect", - "maxWidthPercent": "90%", - "maxHeightPercent": "90%", - "alignment": "center", - "strokeWidth": 3, - "cornerRadius": 8, - "strokeColor": "FFFFFF", - "outerColor": "000000", - "outerAlpha": 0.3, - "ratioFromSize" : { - "width": 50, - "height": 31 - }, - "cropPadding": { - "x": -50, - "y": -50 - }, - "cropOffset": { - "x": 0, - "y": 0 - }, - "feedbackStrokeColor": "0099FF" - }, - "scanFeedback" : { - "style": "CONTOUR_RECT", - "visualFeedbackRedrawTimeout": 100, - "strokeColor": "0099FF", - "fillColor" : "220099FF", - "beepOnResult": true, - "vibrateOnResult": true, - "strokeWidth": 2 - }, - "cancelOnResult" : true - } -} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_camera_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_camera_config.json deleted file mode 100644 index b9caead8d..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_camera_config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "captureResolution" : "1080p", - "zoomGesture": true -} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_config.json deleted file mode 100644 index 17ac5bdfb..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_config.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "viewPlugin" : { - "plugin":{ - "id":"ID", - "idPlugin": { - "universalIdConfig": { - "faceDetection": true, - "allowedLayouts": { - "mrz": [], - "drivingLicense": [], - "idFront": [], - "insuranceCard" : [] - }, - "insuranceCard": { - "lastName": {"scanOption": 0, "minConfidence": 50}, - "firstName": {"scanOption": 0, "minConfidence": 50}, - "fullName": {"scanOption": 0, "minConfidence": 50}, - "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, - "personalNumber": {"scanOption": 0, "minConfidence": 50}, - "authority": {"scanOption": 0, "minConfidence": 50}, - "documentNumber": {"scanOption": 0, "minConfidence": 50}, - "dateOfExpiry": {"scanOption": 0, "minConfidence": 50}, - "nationality": {"scanOption": 0, "minConfidence": 50} - }, - "drivingLicense": { - "lastName": {"scanOption": 0, "minConfidence": 40}, - "firstName": {"scanOption": 0, "minConfidence": 40}, - "fullName": {"scanOption": 0, "minConfidence": 40}, - "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, - "placeOfBirth": {"scanOption": 1, "minConfidence": 50}, - "dateOfIssue": {"scanOption": 0, "minConfidence": 50}, - "dateOfExpiry": {"scanOption": 1, "minConfidence": 50}, - "authority": {"scanOption": 1, "minConfidence": 30}, - "documentNumber": {"scanOption": 0, "minConfidence": 40}, - "licenseClass": {"scanOption": 1, "minConfidence": 30}, - "address": {"scanOption": 0}, - "sex": {"scanOption": 1,"minConfidence": 60}, - "personalNumber": {"scanOption": 1,"minConfidence": 60} - }, - "idFront": { - "lastName": {"scanOption": 0, "minConfidence": 60}, - "firstName": {"scanOption": 0,"minConfidence": 60}, - "fullName": {"scanOption": 0, "minConfidence": 60}, - "dateOfBirth": {"scanOption": 0,"minConfidence": 60}, - "placeOfBirth": {"scanOption": 1,"minConfidence": 60}, - "dateOfIssue": {"scanOption": 0, "minConfidence": 60}, - "dateOfExpiry": {"scanOption": 1,"minConfidence": 60}, - "cardAccessNumber": {"scanOption": 1,"minConfidence": 60}, - "documentNumber": {"scanOption": 0,"minConfidence": 60}, - "nationality": {"scanOption": 1,"minConfidence": 60}, - "sex": {"scanOption": 1,"minConfidence": 60}, - "personalNumber": {"scanOption": 1,"minConfidence": 60} - }, - "miscellaneous": { - "dateOfIssue": {"scanOption": 0,"minConfidence": 35}, - "dateOfExpiry": {"scanOption": 0,"minConfidence": 35}, - "status": {"scanOption": 1,"minConfidence": 35}, - "duration": {"scanOption": 0,"minConfidence": 35}, - "airport": {"scanOption": 0,"minConfidence": 35} - } - } - } - }, - "cutoutConfig" : { - "style": "animated_rect", - "maxWidthPercent": "90%", - "maxHeightPercent": "90%", - "alignment": "center", - "strokeWidth": 3, - "cornerRadius": 8, - "strokeColor": "FFFFFF", - "outerColor": "000000", - "outerAlpha": 0.3, - "ratioFromSize" : { - "width": 50, - "height": 31 - }, - "cropPadding": { - "x": -50, - "y": -50 - }, - "cropOffset": { - "x": 0, - "y": 0 - }, - "feedbackStrokeColor": "0099FF" - }, - "scanFeedback" : { - "style": "CONTOUR_RECT", - "visualFeedbackRedrawTimeout": 100, - "strokeColor": "0099FF", - "fillColor" : "220099FF", - "beepOnResult": true, - "vibrateOnResult": true, - "strokeWidth": 2 - }, - "cancelOnResult" : true - } -} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_cyrillic_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_cyrillic_config.json deleted file mode 100644 index abc9d2111..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_cyrillic_config.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "viewPlugin" : { - "plugin":{ - "id":"ID", - "idPlugin": { - "universalIdConfig": { - "alphabet": "cyrillic", - "faceDetection": true, - "allowedLayouts": { - "mrz": [], - "drivingLicense": [], - "idFront": [] - }, - "drivingLicense": { - "lastName": {"scanOption": 0, "minConfidence": 40}, - "lastName@cyr": {"scanOption": 0, "minConfidence": 40}, - "firstName": {"scanOption": 0, "minConfidence": 40}, - "firstName@cyr": {"scanOption": 0, "minConfidence": 40}, - "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, - "placeOfBirth": {"scanOption": 1, "minConfidence": 50}, - "dateOfIssue": {"scanOption": 0, "minConfidence": 50}, - "dateOfExpiry": {"scanOption": 1, "minConfidence": 50}, - "authority": {"scanOption": 1, "minConfidence": 30}, - "documentNumber": {"scanOption": 0, "minConfidence": 40}, - "address": {"scanOption": 1}, - "address@cyr": {"scanOption": 1}, - "nationality": {"scanOption": 1}, - "nationality@cyr": {"scanOption": 1} - }, - "idFront": { - "lastName": {"scanOption": 0, "minConfidence": 40}, - "lastName@cyr": {"scanOption": 0, "minConfidence": 40}, - "firstName": {"scanOption": 0, "minConfidence": 40}, - "firstName@cyr": {"scanOption": 0, "minConfidence": 40}, - "dateOfBirth": {"scanOption": 0, "minConfidence": 50}, - "placeOfBirth": {"scanOption": 1, "minConfidence": 50}, - "dateOfIssue": {"scanOption": 0, "minConfidence": 50}, - "dateOfExpiry": {"scanOption": 1, "minConfidence": 50}, - "authority": {"scanOption": 1, "minConfidence": 30}, - "documentNumber": {"scanOption": 0, "minConfidence": 40}, - "address": {"scanOption": 1}, - "address@cyr": {"scanOption": 1}, - "nationality": {"scanOption": 1}, - "nationality@cyr": {"scanOption": 1} - } - } - } - }, - "cutoutConfig" : { - "style": "animated_rect", - "maxWidthPercent": "90%", - "maxHeightPercent": "90%", - "alignment": "center", - "strokeWidth": 3, - "cornerRadius": 8, - "strokeColor": "FFFFFF", - "outerColor": "000000", - "outerAlpha": 0.3, - "ratioFromSize" : { - "width": 50, - "height": 31 - }, - "cropPadding": { - "x": -50, - "y": -50 - }, - "cropOffset": { - "x": 0, - "y": 0 - }, - "feedbackStrokeColor": "0099FF" - }, - "scanFeedback" : { - "style": "CONTOUR_RECT", - "visualFeedbackRedrawTimeout": 100, - "strokeColor": "0099FF", - "fillColor" : "220099FF", - "beepOnResult": true, - "vibrateOnResult": true, - "strokeWidth": 2 - }, - "cancelOnResult" : true - } -} diff --git a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_flash_config.json b/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_flash_config.json deleted file mode 100644 index 040df0b20..000000000 --- a/AnylineExamples/Anyline Examples Source/UniversalID/universal_id_flash_config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "mode": "manual", - "alignment": "top_left", - "imageOn": "flash_on", - "imageOff": "flash_off" -} diff --git a/AnylineExamples/Anyline Examples Source/Utility/ALAppDemoLicenses.h b/AnylineExamples/Anyline Examples Source/Utility/ALAppDemoLicenses.h index 85c44b78a..d3128817f 100644 --- a/AnylineExamples/Anyline Examples Source/Utility/ALAppDemoLicenses.h +++ b/AnylineExamples/Anyline Examples Source/Utility/ALAppDemoLicenses.h @@ -10,8 +10,8 @@ #define Anyline_ALAppDemoLicenses_h -#define kDemoAppLicenseKey \ -@"ew0KICAibGljZW5zZUtleVZlcnNpb24iOiAiMy4wIiwNCiAgImRlYnVnUmVwb3J0aW5nIjogIm9uIiwNCiAgIm1ham9yVmVyc2lvbiI6ICIzNyIsDQogICJzY29wZSI6IFsNCiAgICAiQUxMIg0KICBdLA0KICAibWF4RGF5c05vdFJlcG9ydGVkIjogMzAsDQogICJhZHZhbmNlZEJhcmNvZGUiOiB0cnVlLA0KICAibXVsdGlCYXJjb2RlIjogdHJ1ZSwNCiAgInN1cHBvcnRlZEJhcmNvZGVGb3JtYXRzIjogWw0KICAgICJBTEwiDQogIF0sDQogICJwbGF0Zm9ybSI6IFsNCiAgICAiaU9TIiwNCiAgICAiQW5kcm9pZCINCiAgXSwNCiAgInNob3dXYXRlcm1hcmsiOiB0cnVlLA0KICAidG9sZXJhbmNlRGF5cyI6IDMwLA0KICAidmFsaWQiOiAiMjAyMy0wNi0zMCIsDQogICJpb3NJZGVudGlmaWVyIjogWw0KICAgICJpby5hbnlsaW5lLmV4YW1wbGVzIiwNCiAgICAiaW8uYW55bGluZS5leGFtcGxlcy5zdG9yZSIsDQogICAgImlvLmFueWxpbmUuZXhhbXBsZXMuYnVuZGxlIiwNCiAgICAiaW8uYW55bGluZS5BbnlsaW5lRXhhbXBsZXMiLA0KICAgICJpby5hbnlsaW5lLkFueWxpbmVFeGFtcGxlcy5iZXRhIiwNCiAgICAiaW8uYW55bGluZS5BbnlsaW5lRXhhbXBsZXMudGVzdCIsDQogICAgImlvLmFueWxpbmUuZXhhbXBsZXMudGVzdCINCiAgXSwNCiAgImFuZHJvaWRJZGVudGlmaWVyIjogWw0KICAgICJpby5hbnlsaW5lLmV4YW1wbGVzIiwNCiAgICAiaW8uYW55bGluZS5leGFtcGxlcy5zdG9yZSIsDQogICAgImlvLmFueWxpbmUuZXhhbXBsZXMuYnVuZGxlIiwNCiAgICAiaW8uYW55bGluZS5BbnlsaW5lRXhhbXBsZXMiLA0KICAgICJpby5hbnlsaW5lLkFueWxpbmVFeGFtcGxlcy5iZXRhIiwNCiAgICAiaW8uYW55bGluZS5leGFtcGxlcy50ZXN0Ig0KICBdDQp9ClltN2ltVjFYandGWjlqL3Y4T2ZGdU9TR0xsNUptYkJEOEhRZnlkU05XMSs4dkVHdXhDV0hHMXk4a3RHK1o4MGw4L0t5RWN1MXY5R1hKTU1lcG5hWmJuY25VQ241UFNObE9yUXNOVm56WUtKWkJjTkNEUTVXbkFnODV6RW55enVTYWJFb3JLbC9pL3FaTFlUaklNTlVNQlFBSi96aFBlU29DME1VaThqRDF1QTZzOTZsZXJHNlBoS2hFUG1pZFJLdXZZeVFuNWZlRCt1OEdUTnFuVXpkT3U4VzlJaGJ5cDIyaHpUVEhqQm9mQmRyRFJtNVRvcnFDL3RxSk1aSjIyam9iTGZudlFLOWtMRWRsRWhxNy91OE00TjNlSDlXZW00dXM5aG5TWEtEaTNoekJxeDRuSVg1U2luaUdJOVhIRDdoT3lqMUp3dzJuNUh4eEhIL1YzSzI1Zz09" +#define kDemoAppLicenseKey_Bundle \ +@"ew0KICAibGljZW5zZUtleVZlcnNpb24iOiAiMy4wIiwNCiAgImRlYnVnUmVwb3J0aW5nIjogInBpbmciLA0KICAibWFqb3JWZXJzaW9uIjogIjM3IiwNCiAgInNjb3BlIjogWw0KICAgICJBTEwiDQogIF0sDQogICJtYXhEYXlzTm90UmVwb3J0ZWQiOiAzMCwNCiAgImFkdmFuY2VkQmFyY29kZSI6IHRydWUsDQogICJtdWx0aUJhcmNvZGUiOiB0cnVlLA0KICAic3VwcG9ydGVkQmFyY29kZUZvcm1hdHMiOiBbDQogICAgIkFMTCINCiAgXSwNCiAgInBsYXRmb3JtIjogWw0KICAgICJpT1MiLA0KICAgICJBbmRyb2lkIg0KICBdLA0KICAic2hvd1dhdGVybWFyayI6IHRydWUsDQogICJ0b2xlcmFuY2VEYXlzIjogMzAsDQogICJ2YWxpZCI6ICIyMDIzLTA2LTMwIiwNCiAgImlvc0lkZW50aWZpZXIiOiBbDQogICAgImlvLmFueWxpbmUuZXhhbXBsZXMiLA0KICAgICJpby5hbnlsaW5lLmV4YW1wbGVzLnN0b3JlIiwNCiAgICAiaW8uYW55bGluZS5leGFtcGxlcy5idW5kbGUiLA0KICAgICJpby5hbnlsaW5lLkFueWxpbmVFeGFtcGxlcyIsDQogICAgImlvLmFueWxpbmUuQW55bGluZUV4YW1wbGVzLmJldGEiLA0KICAgICJpby5hbnlsaW5lLkFueWxpbmVFeGFtcGxlcy50ZXN0IiwNCiAgICAiaW8uYW55bGluZS5leGFtcGxlcy50ZXN0Ig0KICBdLA0KICAiYW5kcm9pZElkZW50aWZpZXIiOiBbDQogICAgImlvLmFueWxpbmUuZXhhbXBsZXMiLA0KICAgICJpby5hbnlsaW5lLmV4YW1wbGVzLnN0b3JlIiwNCiAgICAiaW8uYW55bGluZS5leGFtcGxlcy5idW5kbGUiLA0KICAgICJpby5hbnlsaW5lLkFueWxpbmVFeGFtcGxlcyIsDQogICAgImlvLmFueWxpbmUuQW55bGluZUV4YW1wbGVzLmJldGEiLA0KICAgICJpby5hbnlsaW5lLmV4YW1wbGVzLnRlc3QiDQogIF0NCn0KUkNsdndZRituM0c5am5YQnE5QVAwd0M0dVRubWNDMmhDT1R1Yys1ZmhDNVk3K3pqTzhUeWdCV0dsSnVBNmp1SVdpZ3ovb3pqUi95eE1TLzhoeHJ6R0EwdFpJRFhHU1laRmtYVTNnVm16TERtTTFNZkdEQk4wMVN5bjFUQ2RUQ3Zqc0VPVlozMW91UHJzNUtNTVVWTzVleWtMdDRBNXM0b0FnemdRM25XQ2Q5RHgyOU5yOWxOZmdraXFoNkxEbTdrMnF3ME9CMDJYWjFsS2phVENtRkpMUXB0em83UG1iaXRHWEtGUXVvZGpicEJDcDQ1NGJ2SHhuMWFXUGtsR1NSVUJ1NkxBZyt0cEp0eWFuWVlDQjVJTTN6QUV0TjlhSENSdEYwNWliaVhoaUQyYUFZRUlpZ1ZHK2pQTFdDa0syMHlEcTlRNkl6V1dGMmxpcFovZDVJQXZ3PT0=" #define kCommunityLicense_v1 \ @"eyJzY29wZSI6WyJBTEwiXSwicGxhdGZvcm0iOlsiaU9TIiwiQW5kcm9pZCIsIldpbmRvd3MiXSwidmFsaWQiOiIyMDE3LTA2LTA2IiwibWFqb3JWZXJzaW9uIjoiMyIsImlzQ29tbWVyY2lhbCI6ZmFsc2UsInRvbGVyYW5jZURheXMiOjYwLCJpb3NJZGVudGlmaWVyIjpbImlvLmFueWxpbmUuQW55bGluZUV4YW1wbGVzIl0sImFuZHJvaWRJZGVudGlmaWVyIjpbImlvLmFueWxpbmUuQW55bGluZUV4YW1wbGVzIl0sIndpbmRvd3NJZGVudGlmaWVyIjpbImlvLmFueWxpbmUuQW55bGluZUV4YW1wbGVzIl19CkkwL1VNUGEvSnVsKzFTVXdzMlJqRGorWlhJVXlYZTE5QnlVZ1J5K2ZkNUJSTExRLzNlUUFOVkNYQm9zZ2YxUFJUWWp2c05aakpqSWFYVTdLc2JkL25zdC9oZTV4Qjk5MnZMTDFqcDhSMXJIR2dmNUsxVFg2TXNaK2VKbmFvak9nMThUbjBBSWt3YkU3aHA5M0lnRXlPb25KanR5Mno0bVYrdVhPTXRIR0hpVXRMZExQaHE2aUZOTW5OTEFDT0FwM0N4NjNXblhNakJKVGUwRjlzOUtHbGsvZExCQWExdW1KUkk5bE1qVmQ1Q2ZLTDkxb0F0Yk1sdzcxOHdvcWpwaE1PUGE0c1o0a3ZYRzZnSm9iSkRQWXpqTlVBc2xNTUUwS0Q3Rjh1bVROZnJ1NGJXczRvK2NYZjFmQnNMeHpDNmJRbHRwT0dZd0xFSlhPQXdqR2p4SVBhZz09" diff --git a/AnylineExamples/Anyline Examples Source/Utility/ALBarcodeResultUtil.h b/AnylineExamples/Anyline Examples Source/Utility/ALBarcodeResultUtil.h index 60b02f792..a14f8a1de 100644 --- a/AnylineExamples/Anyline Examples Source/Utility/ALBarcodeResultUtil.h +++ b/AnylineExamples/Anyline Examples Source/Utility/ALBarcodeResultUtil.h @@ -1,21 +1,17 @@ -// -// ALBarcodeResultUtil.h -// AnylineExamples -// -// Created by Aldrich Co on 11/17/21. -// - #import -#import -#import "AnylineExamples-Swift.h" +#import NS_ASSUME_NONNULL_BEGIN +@class ALResultEntry; + @interface ALBarcodeResultUtil : NSObject + (NSString *)strValueFromBarcode:(ALBarcode *)barcode; -+ (NSArray *)barcodeResultDataFromBarcodeResultArray:(NSArray *)resultData; +//+ (NSArray *)barcodeResultDataFromBarcodeResult:(ALBarcodeResult *)barcodeResult; + ++ (NSArray *)resultDataFromBarcodeResults:(NSArray *)barcodes; @end diff --git a/AnylineExamples/Anyline Examples Source/Utility/ALBarcodeResultUtil.m b/AnylineExamples/Anyline Examples Source/Utility/ALBarcodeResultUtil.m index 7c87a231a..5b7170c7d 100644 --- a/AnylineExamples/Anyline Examples Source/Utility/ALBarcodeResultUtil.m +++ b/AnylineExamples/Anyline Examples Source/Utility/ALBarcodeResultUtil.m @@ -1,63 +1,101 @@ -// -// ALBarcodeResultUtil.m -// AnylineExamples -// -// Created by Aldrich Co on 11/17/21. -// - #import "ALBarcodeResultUtil.h" -#import "ALUniversalIDFieldnameUtil.h" +#import "AnylineExamples-Swift.h" @implementation ALBarcodeResultUtil -/// Returns an array of ALResultEntry for use with a results screen, given an -/// NSArray *. The results may also include PDF417-AAMVA parsed data, if -/// the barcode scan plugin's `parsePDF417` property had been set to YES. -/// -/// @param resultData An array of barcode scan result -/// -+ (NSArray *)barcodeResultDataFromBarcodeResultArray:(NSArray *)resultData { - NSMutableArray *resultMutableData = [NSMutableArray array]; - for (ALBarcode *barcode in resultData) { ++ (NSArray *)resultDataFromBarcodeResults:(NSArray *)barcodes { + NSMutableArray *resultData = [NSMutableArray arrayWithCapacity:barcodes.count]; + for (ALBarcode *barcode in barcodes) { NSString *barcodeString = [[self class] strValueFromBarcode:barcode]; // If we are have a parsed PDF417 result display it in a different way - NSMutableArray *pdf417Results = [NSMutableArray array]; - if (barcode.parsedPDF417 != nil) { - @try { - NSDictionary *body = barcode.parsedPDF417[kPDF417ParsedBody]; - for (NSString *key in body) { - NSString *value = [body[key] uppercaseString]; - NSString *title = [NSString stringWithFormat:@"%@ (Barcode)", [ALUniversalIDFieldnameUtil camelCaseToTitleCase:key]]; - [pdf417Results addObject:[[ALResultEntry alloc] initWithTitle:title value:value]]; - } - } @catch (id anException) { - // Something went wrong with converting the PDF417 code - } - } - - if (pdf417Results.count > 0) { - [resultMutableData addObjectsFromArray:pdf417Results]; - } else { - [resultMutableData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode Result" - value:barcodeString - shouldSpellOutValue:YES]]; - } - [resultMutableData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode Symbology" value:barcode.barcodeFormat shouldSpellOutValue:YES]]; +// NSMutableArray *pdf417Results = [NSMutableArray array]; +// if (barcode.parsedPDF417 != nil) { +// @try { +// NSDictionary *body = barcode.parsedPDF417[kPDF417ParsedBody]; +// for (NSString *key in body) { +// NSString *value = [body[key] uppercaseString]; +// NSString *title = [NSString stringWithFormat:@"%@ (Barcode)", [ALUniversalIDFieldnameUtil camelCaseToTitleCase:key]]; +// [pdf417Results addObject:[[ALResultEntry alloc] initWithTitle:title value:value]]; +// } +// } @catch (id anException) { +// // Something went wrong with converting the PDF417 code +// } +// } +// +// if (pdf417Results.count > 0) { +// [resultData addObjectsFromArray:pdf417Results]; +// } else { +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode Result" +// value:barcodeString +// shouldSpellOutValue:YES]]; +// } + + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode Result" + value:barcodeString + shouldSpellOutValue:YES]]; + [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode Symbology" + value:barcode.format + shouldSpellOutValue:YES]]; } - return resultMutableData; + return resultData; } -/// Returns a string value of a barcode, in base64 in case the raw -/// string value cannot be obtained. +/// Returns an array of ALResultEntry for use with a results screen, given an +/// ALBarcodeResult. The results may also include PDF417-AAMVA parsed data, if +/// the barcode scan plugin's `parsePDF417` property had been set to YES. +/// +/// @param barcodeResult A barcode scan result +/// +//+ (NSArray *)barcodeResultDataFromBarcodeResult:(ALBarcodeResult *)barcodeResult { +// NSMutableArray *resultData = [NSMutableArray array]; +// for (ALBarcode *barcode in barcodeResult.result) { +// NSString *barcodeString = [[self class] strValueFromBarcode:barcode]; +// // If we are have a parsed PDF417 result display it in a different way +// NSMutableArray *pdf417Results = [NSMutableArray array]; +// if (barcode.parsedPDF417 != nil) { +// @try { +// NSDictionary *body = barcode.parsedPDF417[kPDF417ParsedBody]; +// for (NSString *key in body) { +// NSString *value = [body[key] uppercaseString]; +// NSString *title = [NSString stringWithFormat:@"%@ (Barcode)", [ALUniversalIDFieldnameUtil camelCaseToTitleCase:key]]; +// [pdf417Results addObject:[[ALResultEntry alloc] initWithTitle:title value:value]]; +// } +// } @catch (id anException) { +// // Something went wrong with converting the PDF417 code +// } +// } +// +// if (pdf417Results.count > 0) { +// [resultData addObjectsFromArray:pdf417Results]; +// } else { +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode Result" +// value:barcodeString +// shouldSpellOutValue:YES]]; +// } +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode Symbology" value:barcode.barcodeFormat shouldSpellOutValue:YES]]; +// } +// return resultData; +//} + +/// Returns a string value of a barcode, even when initially in base64. /// /// @param barcode An ALBarcode /// + (NSString *)strValueFromBarcode:(ALBarcode *)barcode { - NSString *barcodeString = barcode.base64; - if (barcode.value.length > 0) { - barcodeString = barcode.value; + NSString *barcodeResultStr = barcode.value; + if (barcode.isBase64) { + barcodeResultStr = barcode.value; // set the fallback if this fails + NSData *data = [[NSData alloc] initWithBase64EncodedString:barcode.value + options:0]; + if (data) { + NSString *decodedStr = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + if (decodedStr.length > 0) { + barcodeResultStr = decodedStr; + } + } } - return barcodeString; + return barcodeResultStr; } @end diff --git a/AnylineExamples/Anyline Examples Source/Utility/ALBaseScanViewController.h b/AnylineExamples/Anyline Examples Source/Utility/ALBaseScanViewController.h index da6abb2e9..b9ed20897 100644 --- a/AnylineExamples/Anyline Examples Source/Utility/ALBaseScanViewController.h +++ b/AnylineExamples/Anyline Examples Source/Utility/ALBaseScanViewController.h @@ -1,17 +1,19 @@ -// -// ALBaseScanViewController.h -// AnylineExamples -// -// Created by Daniel Albertini on 24/05/16. -// Copyright © 2016 9yards GmbH. All rights reserved. -// - #import -#import #import "ScanHistory+CoreDataClass.h" #import "ALWarningView.h" +#import + +NS_ASSUME_NONNULL_BEGIN -@interface ALBaseScanViewController : UIViewController +@class ALScanView; +@class ALScanPlugin; +@class ALResultEntry; + +@protocol ALScanViewPluginBase; + +@interface ALBaseScanViewController : UIViewController + +@property (nonatomic, strong, nullable) ALScanView *scanView; @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; @@ -20,8 +22,13 @@ @property (nonatomic) ALScanHistoryType controllerType; @property (nullable, nonatomic, strong) UIButton *flipOrientationButton; + @property () BOOL isOrientationFlipped; +@property (nonatomic, readonly) BOOL isDarkMode; + +- (void)setColors; + - (void)updateScanWarnings:(ALWarningState)warningState; - (void)updateWarningPosition:(CGFloat)newPosition; @@ -32,39 +39,34 @@ - (NSString *)jsonStringFromResultData:(NSArray*)resultData; -- (void)anylineDidFindResult:(NSString*)result - barcodeResult:(NSString *)barcodeResult - image:(UIImage*)image - scanPlugin:(ALAbstractScanPlugin *)scanPlugin - viewPlugin:(ALAbstractScanViewPlugin *)viewPlugin +- (void)anylineDidFindResult:(NSString * _Nullable)result + barcodeResult:(NSString * _Nullable)barcodeResult + image:(UIImage * _Nullable)image + scanPlugin:(ALScanPlugin *)scanPlugin + viewPlugin:(id)viewPlugin completion:(void (^)(void))completion; -- (void)anylineDidFindResult:(NSString*)result - barcodeResult:(NSString *)barcodeResult - images:(NSArray*)images - scanPlugin:(ALAbstractScanPlugin *)scanPlugin - viewPlugin:(ALAbstractScanViewPlugin *)viewPlugin +- (void)anylineDidFindResult:(NSString * _Nullable)result + barcodeResult:(NSString * _Nullable)barcodeResult + images:(NSArray * _Nullable)images + scanPlugin:(ALScanPlugin *)scanPlugin + viewPlugin:(id)viewPlugin completion:(void (^)(void))completion; -- (void)anylineDidFindResult:(NSString*)result - barcodeResult:(NSString *)barcodeResult - faceImage:(UIImage*)faceImage - images:(NSArray*)images - scanPlugin:(ALAbstractScanPlugin *)scanPlugin - viewPlugin:(ALAbstractScanViewPlugin *)viewPlugin +- (void)anylineDidFindResult:(NSString * _Nullable)result + barcodeResult:(NSString * _Nullable)barcodeResult + faceImage:(UIImage * _Nullable)faceImage + images:(NSArray * _Nullable)images + scanPlugin:(ALScanPlugin *)scanPlugin + viewPlugin:(id)viewPlugin completion:(void (^)(void))completion; -- (void)anylineDidFindResult:(NSString*)result - barcodeResult:(NSString *)barcodeResult - image:(UIImage*)image - scanPlugin:(ALAbstractScanPlugin *)scanPlugin - viewPlugin:(ALAbstractScanViewPlugin *)viewPlugin - completion:(void (^)(void))completion; +// - (void)startListeningForMotion; +// - (void)startPlugin:(ALAbstractScanViewPlugin *)plugin; -- (void)startListeningForMotion; -- (void)startPlugin:(ALAbstractScanViewPlugin *)plugin; - (void)showAlertWithTitle:(NSString *)title message:(NSString *)message; - (void)showAlertWithTitle:(NSString *)title message:(NSString *)message completion:(void (^ _Nullable)(void))completion; +- (void)showAlertControllerWithTitle:(NSString *)title message:(NSString *)message actions:(NSArray *)actions; - (void)showAlertForScanningError:(NSError * _Nonnull)error completion:(void (^ _Nullable)(void))completion dismissHandler:(void (^ _Nullable)(void))dismissHandler; - (CGRect)scanViewFrame; @@ -73,6 +75,13 @@ // To add a flip orietation button to any scan mode that extends ALBasescanViewController // you need to call this method on view did load. - (void)setupFlipOrientationButton; + - (void)enableLandscapeOrientation:(BOOL)isLandscape; +- (void)installScanView:(ALScanView * _Nonnull)scanView; + +- (NSString * _Nullable)configJSONStrWithFilename:(NSString *)filename; + @end + +NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/Utility/ALBaseScanViewController.m b/AnylineExamples/Anyline Examples Source/Utility/ALBaseScanViewController.m index ce3dc432f..0cf3a72fd 100644 --- a/AnylineExamples/Anyline Examples Source/Utility/ALBaseScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/Utility/ALBaseScanViewController.m @@ -15,6 +15,8 @@ #import "UIFont+ALExamplesAdditions.h" #import "UIColor+ALExamplesAdditions.h" #import "AppDelegate.h" +#import +#import "AnylineExamples-Swift.h" @import CoreMotion; @@ -36,7 +38,7 @@ - (void)dealloc { [self.motionManager stopDeviceMotionUpdates]; @try { - [[ALErrorManager sharedInstance] removeObserver:self forKeyPath:@"error"]; +// [[ALErrorManager sharedInstance] removeObserver:self forKeyPath:@"error"]; } @catch (NSException * __unused exception) {} } @@ -45,9 +47,9 @@ - (instancetype)initWithTitle:(NSString *)title { if (self) { self.title = (title && title.length > 0) ? title : @""; - [[ALErrorManager sharedInstance] addObserver:self forKeyPath:@"error" - options:NSKeyValueObservingOptionNew - context:nil]; +// [[ALErrorManager sharedInstance] addObserver:self forKeyPath:@"error" +// options:NSKeyValueObservingOptionNew +// context:nil]; } return self; } @@ -78,6 +80,23 @@ - (void)viewWillDisappear:(BOOL)animated { [self enableLandscapeOrientation:NO]; } +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + [self setColors]; +} + +- (void)setColors { + // override +} + +- (BOOL)isDarkMode { + BOOL isDarkMode = NO; + if (@available(iOS 13.0, *)) { + isDarkMode = self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark; + } + return isDarkMode; +} + - (NSString *)jsonStringFromResultData:(NSArray*)resultData { return @""; } @@ -87,33 +106,31 @@ - (void)updateBrightness:(CGFloat)brightness forModule:(id)anylineModule; { } - (void)updateBrightness:(CGFloat)brightness forModule:(id)anylineModule ignoreTooDark:(BOOL)ignoreTooDark { - if([anylineModule isKindOfClass:[ALOCRScanViewPlugin class]]) { - if( brightness < 40 && !ignoreTooDark) { - [self updateScanWarnings:ALWarningStateTooDark]; - } else if (brightness > 200) { - [self updateScanWarnings:ALWarningStateTooBright]; - } - } +// if([anylineModule isKindOfClass:[ALOCRScanViewPlugin class]]) { +// if( brightness < 40 && !ignoreTooDark) { +// [self updateScanWarnings:ALWarningStateTooDark]; +// } else if (brightness > 200) { +// [self updateScanWarnings:ALWarningStateTooBright]; +// } +// } } - - -- (void)startListeningForMotion { - __weak __block typeof(self) welf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - CMMotionManager * motionManager = [[CMMotionManager alloc] init]; - motionManager.deviceMotionUpdateInterval = 1.0/60.0; - [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] - withHandler:^(CMDeviceMotion *motion, NSError *error) { - CGFloat threshold = 0.05; - if( fabs(motion.userAcceleration.x) > threshold || - fabs(motion.userAcceleration.y) > threshold) { - [welf updateScanWarnings:ALWarningStateHoldStill]; - } - }]; - welf.motionManager = motionManager; - }); -} +//- (void)startListeningForMotion { +// __weak __block typeof(self) welf = self; +// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ +// CMMotionManager * motionManager = [[CMMotionManager alloc] init]; +// motionManager.deviceMotionUpdateInterval = 1.0/60.0; +// [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] +// withHandler:^(CMDeviceMotion *motion, NSError *error) { +// CGFloat threshold = 0.05; +// if( fabs(motion.userAcceleration.x) > threshold || +// fabs(motion.userAcceleration.y) > threshold) { +// [welf updateScanWarnings:ALWarningStateHoldStill]; +// } +// }]; +// welf.motionManager = motionManager; +// }); +//} - (void)updateScanWarnings:(ALWarningState)warningState { [self.warningView showWarning:warningState]; @@ -126,12 +143,14 @@ - (void)updateWarningPosition:(CGFloat)newPosition { - (void)anylineDidFindResult:(NSString *)result barcodeResult:(NSString *)barcodeResult image:(UIImage *)image - scanPlugin:(ALAbstractScanPlugin *)scanPlugin - viewPlugin:(ALAbstractScanViewPlugin *)viewPlugin + scanPlugin:(ALScanPlugin *)scanPlugin + viewPlugin:(id)viewPlugin completion:(void (^)(void))completion { self.successfulScan = YES; - if (completion){ - completion(); + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(); + }); } } @@ -139,8 +158,8 @@ - (void)anylineDidFindResult:(NSString *)result - (void)anylineDidFindResult:(NSString*)result barcodeResult:(NSString *)barcodeResult images:(NSArray*)images - scanPlugin:(ALAbstractScanPlugin *)scanPlugin - viewPlugin:(ALAbstractScanViewPlugin *)viewPlugin + scanPlugin:(ALScanPlugin *)scanPlugin + viewPlugin:(id)viewPlugin completion:(void (^)(void))completion { [self anylineDidFindResult:result barcodeResult:barcodeResult faceImage:nil images:images scanPlugin:scanPlugin viewPlugin:viewPlugin completion:completion]; } @@ -149,8 +168,8 @@ - (void)anylineDidFindResult:(NSString*)result barcodeResult:(NSString *)barcodeResult faceImage:(UIImage*)faceImage images:(NSArray*)images - scanPlugin:(ALAbstractScanPlugin *)scanPlugin - viewPlugin:(ALAbstractScanViewPlugin *)viewPlugin + scanPlugin:(ALScanPlugin *)scanPlugin + viewPlugin:(id)viewPlugin completion:(void (^)(void))completion { self.successfulScan = YES; if (completion){ @@ -224,17 +243,41 @@ - (void)showAlertForScanningError:(NSError * _Nonnull)error }]; } -- (void)startPlugin:(ALAbstractScanViewPlugin *)plugin { - NSError *error; - BOOL success = [plugin startAndReturnError:&error]; - if (!success) { - __weak __block typeof(self) weakSelf = self; - [self showAlertForScanningError:error completion:nil dismissHandler:^{ - [weakSelf.navigationController popViewControllerAnimated:YES]; - }]; +- (void)showAlertControllerWithTitle:(NSString *)title message:(NSString *)message actions:(NSArray *)actions { + UIAlertController *sender = [UIAlertController alertControllerWithTitle:title + message:message + preferredStyle:UIAlertControllerStyleAlert]; + for (UIAlertAction *action in actions) { + if ([action isKindOfClass:[UIAlertAction class]]) { + [sender addAction:action]; + } } + [self presentViewController:sender animated:YES completion:nil]; } + +- (NSString *)configJSONStrWithFilename:(NSString *)filename { + NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:filename + ofType:@"json"]; + + NSString *configStr = [NSString stringWithContentsOfFile:jsonFilePath + encoding:NSUTF8StringEncoding + error:NULL]; + + return configStr; +} + +//- (void)startPlugin:(id)plugin { +// NSError *error; +// BOOL success = [plugin startAndReturnError:&error]; +// if (!success) { +// __weak __block typeof(self) weakSelf = self; +// [self showAlertForScanningError:error completion:nil dismissHandler:^{ +// [weakSelf.navigationController popViewControllerAnimated:YES]; +// }]; +// } +//} + - (CGRect)scanViewFrame { CGRect frame = [[UIScreen mainScreen] bounds]; CGFloat navbarHeight = CGRectGetMaxY(self.navigationController.navigationBar.frame); @@ -243,7 +286,7 @@ - (CGRect)scanViewFrame { frame.size.width, frame.size.height - navbarHeight); } -#pragma mark - FlipOrietation +#pragma mark - FlipOrientation - (void)flipOrientationPressed:(id)sender { self.isOrientationFlipped = !self.isOrientationFlipped; @@ -306,7 +349,17 @@ - (void)setupFlipOrientationButton { [NSLayoutConstraint activateConstraints:flipCosntraints]; } -#pragma mark - NSKeyValueObserving +- (void)installScanView:(ALScanView *)scanView { + [self.view addSubview:scanView]; + + scanView.translatesAutoresizingMaskIntoConstraints = false; + [scanView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES; + [scanView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES; + [scanView.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES; + [scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES; +} + +// MARK: - NSKeyValueObserving - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object @@ -327,17 +380,17 @@ - (void)observeValueForKeyPath:(NSString *)keyPath // // You shouldn't stop the running plugin here either, as the SDK will have taken // care of it already. - NSError *error = [[ALErrorManager sharedInstance] error]; - if (error && ![error.userInfo[@"cached"] isEqual:@(YES)]) { - // We only do this part here because we believe an SDK-based alert error is also - // being shown at this point; and that the SDK shouldn't provide this - // behavior, for obvious reasons. - __weak __block typeof(self) weakSelf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), - dispatch_get_main_queue(), ^{ - [weakSelf.navigationController popViewControllerAnimated:YES]; - }); - } +// NSError *error = [[ALErrorManager sharedInstance] error]; +// if (error && ![error.userInfo[@"cached"] isEqual:@(YES)]) { +// // We only do this part here because we believe an SDK-based alert error is also +// // being shown at this point; and that the SDK shouldn't provide this +// // behavior, for obvious reasons. +// __weak __block typeof(self) weakSelf = self; +// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), +// dispatch_get_main_queue(), ^{ +// [weakSelf.navigationController popViewControllerAnimated:YES]; +// }); +// } } } diff --git a/AnylineExamples/Anyline Examples Source/Utility/ALUtils.m b/AnylineExamples/Anyline Examples Source/Utility/ALUtils.m index 8d58b8426..796679d1c 100644 --- a/AnylineExamples/Anyline Examples Source/Utility/ALUtils.m +++ b/AnylineExamples/Anyline Examples Source/Utility/ALUtils.m @@ -64,20 +64,20 @@ + (BOOL)isScannerTypeImplemented:(ALScannerType)scannerType { #pragma mark - Private -+ (ALFlashMode)defaultFlashMode { - NSString *flashModeString = InfoPlist[@"NYDefaultFlashMode"]; - - if ([flashModeString isEqualToString:@"auto"]) { - return ALFlashModeAuto; - } else if ([flashModeString isEqualToString:@"manual"]) { - return ALFlashModeManual; - } else if ([flashModeString isEqualToString:@"none"]) { - return ALFlashModeNone; - } else { - @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"Unknown flash mode: %@. Supported are: auto, manual, none", flashModeString] userInfo:nil]; - } - return ALFlashModeAuto; -} +//+ (ALFlashMode)defaultFlashMode { +// NSString *flashModeString = InfoPlist[@"NYDefaultFlashMode"]; +// +// if ([flashModeString isEqualToString:@"auto"]) { +// return ALFlashModeAuto; +// } else if ([flashModeString isEqualToString:@"manual"]) { +// return ALFlashModeManual; +// } else if ([flashModeString isEqualToString:@"none"]) { +// return ALFlashModeNone; +// } else { +// @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"Unknown flash mode: %@. Supported are: auto, manual, none", flashModeString] userInfo:nil]; +// } +// return ALFlashModeAuto; +//} void _VerifyAnylineModuleSetup(BOOL success, NSError *error) { if (!success) { diff --git a/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALPluginResultHelper.h b/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALPluginResultHelper.h new file mode 100644 index 000000000..299905b0f --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALPluginResultHelper.h @@ -0,0 +1,64 @@ +#import +#import // needed? + +NS_ASSUME_NONNULL_BEGIN + +@class ALPluginResult; +@class ALResultEntry; + +@interface ALBarcode (ALExtras) + +- (NSString *)decoded; + +@end + + +@protocol ALResultListEnumerable + +@property (nonatomic, readonly) NSArray *resultEntryList; + +@end + + +@interface ALMrzResult (ALExtras) +@end + +@interface ALUniversalIDResult (ALExtras) +@end + +@interface ALTinResult (ALExtras) +@end + +@interface ALVehicleRegistrationCertificateResult (ALExtras) +@end + +@interface ALCommercialTireIDResult (ALExtras) +@end + +@interface ALTireSizeResult (ALExtras) +@end + +@interface ALVinResult (ALExtras) +@end + +@interface ALLicensePlateResult (ALExtras) +@end + +@interface ALMeterResult (ALExtras) +@end + +@interface ALBarcodeResult (ALExtras) +@end + +@interface ALContainerResult (ALExtras) +@end + +@interface ALOcrResult (ALExtras) +@end + +// TODO: need to support these + +//@interface ALJapaneseLandingPermissionResult (ALExtras) +//@end + +NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALPluginResultHelper.m b/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALPluginResultHelper.m new file mode 100644 index 000000000..c8901f2cc --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALPluginResultHelper.m @@ -0,0 +1,368 @@ +#import "ALPluginResultHelper.h" +#import +#import "AnylineExamples-Swift.h" +#import "ALUniveralIDResultHelper.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ALPluginResultHelper + ++ (NSString *)dateStringFromString:(NSString *)string; + +@end + + +@interface ALUniversalIDResultField (ALExtras) + +- (NSString * _Nullable)latinText; +- (NSString * _Nullable)arabicText; +- (NSString * _Nullable)cyrillicText; + +@end + + +@interface NSMutableArray (ALExtras) + +- (BOOL)appendValue:(NSString * _Nullable)value forKey:(NSString *)key; +- (BOOL)appendValue:(NSString * _Nullable)value forKey:(NSString *)key scriptCode:(NSString * _Nullable)scriptCode; +- (BOOL)appendValue:(NSString * _Nullable)value forKey:(NSString *)key scriptCode:(NSString * _Nullable)scriptCode spellOut:(BOOL)spellOut; + +@end + + +@interface NSString (ALExtras) + +- (NSString *)formattedDate; + +@end + + +@implementation ALResultEntry (ALExtras) + +- (NSString *)description { + return [NSString stringWithFormat:@"ALResultEntry: %@: %@", self.title, self.value]; +} + +@end + + +@implementation NSMutableArray (ALExtras) + +- (BOOL)appendValue:(NSString * _Nullable)value + forKey:(NSString *)key + scriptCode:(NSString * _Nullable)scriptCode + spellOut:(BOOL)spellOut { + if (!value.length) { + return NO; + } + value = [value stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; + if (scriptCode.length) { + key = [NSString stringWithFormat:@"%@-%@", key, scriptCode]; + } + [self addObject:[ALResultEntry withTitle:key value:value shouldSpellOutValue:spellOut]]; + return YES; +} + +- (BOOL)appendValue:(NSString * _Nullable)value forKey:(NSString *)key { + return [self appendValue:value forKey:key scriptCode:nil]; +} + +- (BOOL)appendValue:(NSString * _Nullable)value forKey:(NSString *)key scriptCode:(NSString * _Nullable)scriptCode { + return [self appendValue:value forKey:key scriptCode:scriptCode spellOut:NO]; +} + +@end + + +@implementation NSString (ALExtras) + +- (NSString *)formattedDate { + return [ALUniveralIDResultHelper dateStringFromString:self]; +} + +@end + + +@implementation ALTinResult (ALExtras) + +- (NSArray *)resultEntryList { + return @[ [ALResultEntry withTitle:@"Tire Identification Number" value:self.text] ]; +} + +@end + + +@implementation ALCommercialTireIDResult (ALExtras) + +- (NSArray *)resultEntryList { + return @[ [ALResultEntry withTitle:@"Commercial Tire ID" value:self.text] ]; +} + +@end + + +@implementation ALTireSizeResult (ALExtras) + +- (NSArray *)resultEntryList { + return @[ [ALResultEntry withTitle:@"Tire Size Configuration" value:self.text.text] ]; +} + +@end + + +@implementation ALVinResult (ALExtras) + +- (NSArray *)resultEntryList { + return @[ [ALResultEntry withTitle:@"Vehicle Identification Number" value:self.text] ]; +} + +@end + +@implementation ALContainerResult (ALExtras) + +- (NSArray *)resultEntryList { + return @[ [ALResultEntry withTitle:@"Shipping Container Number" value:self.text] ]; +} + +@end + +@implementation ALOcrResult (ALExtras) + +- (NSArray *)resultEntryList { + return @[ [ALResultEntry withTitle:@"OCR Result" value:self.text] ]; +} + +@end + +@implementation ALVehicleRegistrationCertificateResult (ALExtras) + +- (NSArray *)resultEntryList { + + NSMutableArray *ret = [NSMutableArray array]; + + [ret appendValue:self.result.firstName.text forKey:@"First Name"]; + [ret appendValue:self.result.lastName.text forKey:@"Last Name"]; + [ret appendValue:self.result.address.text forKey:@"Address"]; + [ret appendValue:self.result.brand.text forKey:@"Brand"]; + [ret appendValue:self.result.documentNumber.text forKey:@"Document Number"]; + [ret appendValue:self.result.firstIssued.text forKey:@"First Issued"]; + [ret appendValue:self.result.licensePlate.text forKey:@"License Plate"]; + [ret appendValue:self.result.vehicleIdentificationNumber.text forKey:@"Vehicle Identification Number"]; + + [ret appendValue:self.result.vehicleType.text forKey:@"Vehicle Type"]; + [ret appendValue:self.result.displacement.text forKey:@"Displacement"]; + [ret appendValue:self.result.tire.text forKey:@"Tire"]; + + [ret appendValue:self.result.manufacturerCode.text forKey:@"Manufacturer Code"]; + [ret appendValue:self.result.vehicleTypeCode.text forKey:@"Vehicle Type Code"]; + + // OTHER KNOWN FIELDS: + // documentCategoryDefinition; + // documentRegionDefinition; + // documentSideDefinition; + // documentTypeDefinition; + // documentVersionsDefinition; + // formattedFirstIssued; + return ret; +} + +@end + + +@implementation ALUniversalIDResult (ALExtras) + +- (NSArray *)resultEntryList { + + NSMutableArray *resultData = [NSMutableArray array]; + NSCharacterSet *underscores = [NSCharacterSet characterSetWithCharactersInString:@"_"]; + NSArray *fieldNames = [ALUniveralIDResultHelper fieldNames]; + [fieldNames enumerateObjectsUsingBlock:^(NSString *fieldNameWithUnderscore, + NSUInteger idx, + BOOL * _Nonnull stop) { + + // ACO: uninteresting fields (those that end with "Definition") + if ([fieldNameWithUnderscore hasSuffix:@"Definition"]) { + return; // skip + } + + NSString *fieldName = [fieldNameWithUnderscore stringByTrimmingCharactersInSet:underscores]; + + // must work because the field names were obtained via reflection + ALUniversalIDResultField *field = [self.result valueForKey:fieldName]; + if (![fieldName localizedCaseInsensitiveContainsString:@"formatted"]) { + ALResultEntry *entry; + entry = [ALUniveralIDResultHelper resultEntryFromFieldName:fieldName value:field.latinText]; + if (entry) { + [resultData addObject:entry]; + } + entry = [ALUniveralIDResultHelper resultEntryFromFieldName:fieldName value:field.arabicText scriptCode:@"ara"]; + if (entry) { + [resultData addObject:entry]; + } + entry = [ALUniveralIDResultHelper resultEntryFromFieldName:fieldName value:field.cyrillicText scriptCode:@"cyr"]; + if (entry) { + [resultData addObject:entry]; + } + } else { + NSString *fieldNameTitleCase = [ALUniveralIDResultHelper camelCaseToTitleCaseModified:fieldName]; + NSString *fieldNameDisplay = [NSString stringWithFormat:@"%@", fieldNameTitleCase]; + + // The idea is to replace an map with the same key without "Formatted " + // so if "Date of Birth" and "Formatted Date of Birth" are both found, then only the "Date of Birth" entry is + // found, but it takes on the value from what would be "Formatted Date of Birth" + [resultData enumerateObjectsUsingBlock:^(ALResultEntry * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSString *title = [fieldNameDisplay stringByReplacingOccurrencesOfString:@"Formatted " withString:@""]; + if ([obj.title localizedCaseInsensitiveContainsString:title]) { + obj.value = field.latinText; + } + }]; + } + }]; + return [ALUniveralIDResultHelper sortedResultListFrom:resultData]; +} + +@end + + +@implementation ALMrzResult (ALExtras) + +- (NSArray *)resultEntryList { + + NSMutableArray *resultData = [NSMutableArray array]; + + // ACO I think we give VIZ fields priority if they are found + [resultData appendValue:self.givenNames forKey:@"Given Names"]; + [resultData appendValue:self.surname forKey:@"Surname"]; + [resultData appendValue:self.sex forKey:@"Sex"]; + [resultData appendValue:self.dateOfBirthObject.formattedDate forKey:@"Date of Birth"]; + [resultData appendValue:self.documentType forKey:@"Document Type"]; + [resultData appendValue:self.documentNumber forKey:@"Document Number"]; + [resultData appendValue:self.dateOfExpiryObject.formattedDate forKey:@"Date of Expiry"]; + [resultData appendValue:self.nationalityCountryCode forKey:@"Nationality"]; + [resultData appendValue:self.personalNumber forKey:@"Personal Number" scriptCode:nil spellOut:YES]; + + // VIZ fields + [resultData appendValue:self.vizGivenNames forKey:@"Given Names (VIZ)"]; + [resultData appendValue:self.vizSurname forKey:@"Surname (VIZ)"]; + [resultData appendValue:self.vizAddress forKey:@"Address (VIZ)"]; + [resultData appendValue:self.vizDateOfBirthObject.formattedDate forKey:@"Date of Birth (VIZ)"]; + [resultData appendValue:self.vizDateOfExpiry.formattedDate forKey:@"Date of Expiry (VIZ)"]; + [resultData appendValue:self.vizDateOfIssueObject.formattedDate forKey:@"Date of Issue (VIZ)"]; + + return resultData; +} + +@end + + +@implementation ALUniversalIDResultField (ALExtras) + +- (NSString * _Nullable)latinText { + return [self.textValues.latin.text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; +} + +- (NSString * _Nullable)arabicText { + return [self.textValues.arabic.text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; +} + +- (NSString * _Nullable)cyrillicText { + return [self.textValues.cyrillic.text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; +} + +@end + + +@implementation ALLicensePlateResult (ALExtras) + +- (NSArray *)resultEntryList { + NSMutableArray *ret = [NSMutableArray array]; + [ret appendValue:self.plateText forKey:@"Plate Text"]; + [ret appendValue:self.country.value forKey:@"Country"]; + [ret appendValue:self.area.value forKey:@"Area"]; + return ret; +} + +@end + + +@implementation ALBarcodeResult (ALExtras) + +- (NSArray *)resultEntryList { + NSMutableArray *ret = [NSMutableArray array]; + for (ALBarcode *barcode in self.barcodes) { + ALBodyPart *aamvaData = barcode.aamva.bodyPart; + if (aamvaData) { // PDF417 special standard + NSCharacterSet *underscores = [NSCharacterSet characterSetWithCharactersInString:@"_"]; + NSArray *fields = [self.class aamvaFieldNames]; + for (NSString *field in fields) { + NSString *value; + if ((value = [aamvaData valueForKey:field])) { + + NSString *betterFieldName = [ALUniveralIDResultHelper camelCaseToTitleCaseModified:[field stringByTrimmingCharactersInSet:underscores]]; + // "City", "DateOfBirth", etc + [ret appendValue:value forKey:[NSString stringWithFormat:@"%@ (AAMVA)", betterFieldName]]; + } + } + } else { + [ret appendValue:barcode.decoded forKey:@"Barcode"]; + [ret appendValue:barcode.format forKey:@"Format"]; + } + } + return ret; +} + +// This generates a list of fields found in ALBodyPart (an ALAamva property) during runtime. ++ (NSArray *)aamvaFieldNames { + // ------------ + unsigned int count; + Ivar* ivars = class_copyIvarList(ALBodyPart.class, &count); + NSMutableArray *ivarArray = [NSMutableArray arrayWithCapacity:count]; + for (int i = 0; i < count ; i++) { + const char *ivarName = ivar_getName(ivars[i]); + [ivarArray addObject:[NSString stringWithCString:ivarName encoding:NSUTF8StringEncoding]]; + } + free(ivars); + return ivarArray; +} + +@end + + +@implementation ALMeterResult (ALExtras) + +- (NSArray *)resultEntryList { + NSMutableArray *ret = [NSMutableArray array]; + NSString *reading = self.value; + if (self.unit.length) { + reading = [NSString stringWithFormat:@"%@ %@", reading, self.unit]; + } + [ret appendValue:reading forKey:@"Meter Reading"]; + return ret; +} + +@end + + +@implementation ALBarcode (ALExtras) + +- (NSString *)decoded { + NSString *barcodeResultStr = self.value; + if (self.isBase64) { + barcodeResultStr = self.value; // set the fallback if this fails + NSData *data = [[NSData alloc] initWithBase64EncodedString:self.value + options:0]; + if (data) { + NSString *decodedStr = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + if (decodedStr.length > 0) { + barcodeResultStr = decodedStr; + } + } + } + return barcodeResultStr; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALUniveralIDResultHelper.h b/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALUniveralIDResultHelper.h new file mode 100644 index 000000000..561eef51a --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALUniveralIDResultHelper.h @@ -0,0 +1,39 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@class ALResultEntry; + +@interface ALUniveralIDResultHelper : NSObject + +// these are shown in order for the ID scan results displayed, unless that field is blank or null for +// the sample. The list of field names can be found in ALIDResult. ++ (NSArray *)universalIDFieldsToSelect; + +// This generates a list of fields in the ALIDResult during runtime. ++ (NSArray *)fieldNames; + +/// Ordered list of ID field names that should be, when present, on the top of the list +/// displayed. ++ (NSArray *)priorityIDFieldNames; + ++ (NSArray *)sortedResultListFrom:(NSArray *)resultData; + ++ (NSString *)camelCaseToTitleCaseModified:(NSString *)inputString; + ++ (NSString *)camelCaseToTitleCase:(NSString *)inputString; + ++ (NSString *)stringForDate:(NSDate *)date; + ++ (NSString *)dateStringFromString:(NSString *)string; + ++ (ALResultEntry * _Nullable)resultEntryFromFieldName:(NSString *)fieldName value:(NSString *)fieldValue; + ++ (ALResultEntry * _Nullable)resultEntryFromFieldName:(NSString *)fieldName + value:(NSString *)fieldValue + scriptCode:(NSString * _Nullable)scriptCode; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALUniveralIDResultHelper.m b/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALUniveralIDResultHelper.m new file mode 100644 index 000000000..162a54605 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Utility/Extensions/ALUniveralIDResultHelper.m @@ -0,0 +1,200 @@ +#import "ALUniveralIDResultHelper.h" +#import +#import +#import "AnylineExamples-Swift.h" + +@implementation ALUniveralIDResultHelper + +// these are shown in order for the ID scan results displayed, unless that field is blank or null for +// the sample. The list of field names can be found in ALIDResult. ++ (NSArray *)universalIDFieldsToSelect { + return @[ + @"_fullName", + @"_firstName", + @"_lastName", + @"_nationality", + @"_sex", + @"_dateOfExpiry", + @"_dateOfBirth", + @"_placeOfBirth", + @"_dateOfIssue", + @"_address", + @"_authority", + @"_documentNumber" + ]; +} + +// This generates a list of fields in the ALIDResult during runtime. ++ (NSArray *)fieldNames { + // ------------ + unsigned int count; + Ivar* ivars = class_copyIvarList(ALIDResult.class, &count); + NSMutableArray *ivarArray = [NSMutableArray arrayWithCapacity:count]; + for (int i = 0; i < count ; i++) { + const char *ivarName = ivar_getName(ivars[i]); + [ivarArray addObject:[NSString stringWithCString:ivarName encoding:NSUTF8StringEncoding]]; + } + free(ivars); + return ivarArray; +} + +/// Ordered list of ID field names that should be, when present, on the top of the list +/// displayed. ++ (NSArray *)priorityIDFieldNames { + return @[ + @"name", + @"surname", + @"last name", + @"given names", + @"first name", + @"date of birth", + @"place of birth", + @"date of issue", + @"date of expiry", + @"document number", + @"country", + ]; +} + ++ (NSArray *)sortedResultListFrom:(NSArray *)resultData { + NSArray *priorityFieldsArray = [self.class priorityIDFieldNames]; + + NSArray *sortedArray = [resultData sortedArrayUsingComparator:^NSComparisonResult(ALResultEntry * _Nonnull obj1, ALResultEntry * _Nonnull obj2) { + NSUInteger index1 = [priorityFieldsArray indexOfObjectPassingTest:^BOOL(NSString *title, NSUInteger idx, BOOL * _Nonnull stop) { + return [obj1.title localizedCaseInsensitiveContainsString:title]; + }]; + NSUInteger index2 = [priorityFieldsArray indexOfObjectPassingTest:^BOOL(NSString *title, NSUInteger idx, BOOL * _Nonnull stop) { + return [obj2.title localizedCaseInsensitiveContainsString:title]; + }]; + if (index2 == index1) { + return (NSComparisonResult)NSOrderedSame; + } else if (index1 == NSNotFound && index2 != NSNotFound) { + return (NSComparisonResult)NSOrderedDescending; + } else if (index2 == NSNotFound && index1 != NSNotFound) { + return (NSComparisonResult)NSOrderedAscending; + } else if (index2 > index1) { + return (NSComparisonResult)NSOrderedAscending; + } else if (index1 > index2) { + return (NSComparisonResult)NSOrderedDescending; + } + return (NSComparisonResult)NSOrderedSame; + }]; + + return sortedArray; +} + ++ (NSString *)camelCaseToTitleCaseModified:(NSString *)inputString { + // split a camel case string into spaces + NSString *strModified = [inputString stringByReplacingOccurrencesOfString:@"([a-z])([A-Z])" + withString:@"$1 $2" + options:NSRegularExpressionSearch + range:NSMakeRange(0, inputString.length)]; + + strModified = strModified.capitalizedString; + + // eg. Date 'Of' Birth => Date of Birth + strModified = [strModified stringByReplacingOccurrencesOfString:@"Of" + withString:@"of" + options:NSLiteralSearch + range:NSMakeRange(0, inputString.length)]; + + return strModified; +} + ++ (NSString *)camelCaseToTitleCase:(NSString *)inputString { + NSString *str = [inputString copy]; + NSMutableString *str2 = [NSMutableString string]; + + for (NSInteger i=0; i ALResultEntry { + return .init(title: title, value: value) + } + + @objc + static func with(title: String, value: String, shouldSpellOutValue: Bool) -> ALResultEntry { + return .init(title: title, value: value, shouldSpellOutValue: shouldSpellOutValue) + } + + @objc + static func JSONStringFromList(_ list: [ALResultEntry]) -> String? { + return list.JSONStringFromResultData + } +} + +extension Array where Element == ALResultEntry { + var JSONStringFromResultData: String? { + let maps: [[String: Any]] = self.map { $0.toDictionary() } + let dict = ["result": maps] + if let data = try? JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted) { + return .init(data: data, encoding: .utf8) + } + return nil + } } diff --git a/AnylineExamples/Anyline Examples Source/Utility/View/ResultScreen/ALResultViewController.swift b/AnylineExamples/Anyline Examples Source/Utility/View/ResultScreen/ALResultViewController.swift index d2dc66c05..1b18d0a27 100644 --- a/AnylineExamples/Anyline Examples Source/Utility/View/ResultScreen/ALResultViewController.swift +++ b/AnylineExamples/Anyline Examples Source/Utility/View/ResultScreen/ALResultViewController.swift @@ -21,8 +21,24 @@ The result fields above display a selection of scannable ID information only. Pl } // the keys can be used as titles for section headers, we choose not to display them + @objc var resultData: [String: [ALResultEntry]] = [:] + @objc + var resultList: [ALResultEntry] { + get { + // Constants.defaultSectionTitle or first + var key: String! = Constants.defaultSectionTitle + if !resultData.keys.contains(Constants.defaultSectionTitle) { + key = resultData.keys.first + } + return resultData[key] ?? [] + } + set { + resultData[Constants.defaultSectionTitle] = newValue + } + } + @objc var imageFace: UIImage? @@ -112,6 +128,10 @@ The result fields above display a selection of scannable ID information only. Pl self.navigationController?.popViewController(animated: true) } + override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + } + @objc init(resultMap: [String: [ALResultEntry]]) { self.resultData = resultMap.excludingKeys(Constants.keysToExclude) diff --git a/AnylineExamples/Anyline Examples Source/VIN/ViewController/ALVINScanViewController.m b/AnylineExamples/Anyline Examples Source/VIN/ViewController/ALVINScanViewController.m index ecc3fafb0..88a7392d1 100644 --- a/AnylineExamples/Anyline Examples Source/VIN/ViewController/ALVINScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/VIN/ViewController/ALVINScanViewController.m @@ -1,137 +1,88 @@ -// -// ALVINScanViewController.m -// AnylineExamples -// -// Created by Daniel Albertini on 18.12.17. -// - #import "ALVINScanViewController.h" #import #import "AnylineExamples-Swift.h" +#import "ALPluginResultHelper.h" + +@interface ALVINScanViewController () -@interface ALVINScanViewController () +@property (nonatomic, strong) ALScanViewPlugin *scanViewPlugin; -// The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *vinScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *vinScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +@property (nonatomic, strong) ALScanViewConfig *scanViewConfig; + +@property (nonatomic, readonly) NSDictionary *scanViewConfigDict; @end + +NSString * const kALVINScanVC_configFilename = @"ocr_config_vin"; + + @implementation ALVINScanViewController +- (void)dealloc { + NSLog(@"dealloc ALVINScanViewController"); +} + - (void)viewDidLoad { [super viewDidLoad]; + self.title = @"VIN"; - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - CGRect frame = [self scanViewFrame]; - - ALVINConfig *config = [[ALVINConfig alloc] init]; - - NSError *error = nil; - - self.vinScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.vinScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.vinScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"vin_capture_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.vinScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.vinScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - [self.vinScanViewPlugin addScanViewPluginDelegate:self]; - NSAssert(self.vinScanViewPlugin, @"Setup Error: %@", error.debugDescription); - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.vinScanViewPlugin]; + self.controllerType = ALScanHistoryVIN; - //Enable Zoom Gesture - [self.scanView enableZoomPinchGesture:YES]; + NSError *error; + self.scanViewPlugin = [ALScanViewPluginFactory withJSONDictionary:self.scanViewConfigDict]; - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; + self.scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:self.scanViewConfigDict error:&error]; + + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.scanViewPlugin + scanViewConfig:self.scanViewConfig + error:&error]; - //Start Camera: + [self installScanView:self.scanView]; + + ALScanViewPlugin *scanViewPlugin = self.scanViewPlugin; + scanViewPlugin.scanPlugin.delegate = self; + [self.scanView startCamera]; - [self startListeningForMotion]; - - self.controllerType = ALScanHistoryVIN; } -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.vinScanViewPlugin stopAndReturnError:nil]; + NSError *error; + [self.scanViewPlugin startWithError:&error]; // could check the error } -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.vinScanViewPlugin]; -} +// MARK: - Getters and Setters -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; +- (NSDictionary *)scanViewConfigDict { + return [[self configJSONStrWithFilename:kALVINScanVC_configFilename] asJSONObject]; // could check the error } -#pragma mark -- AnylineOCRModuleDelegate -/* - This is the main delegate method Anyline uses to report its results - */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin - didFindResult:(ALOCRResult *)result { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Vehicle Identification Number" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; +// MARK: - Handle & present results + +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + [self enableLandscapeOrientation:NO]; + + ALVinResult *vinResult = scanResult.pluginResult.vinResult; + NSArray *resultData = vinResult.resultEntryList; + NSString *JSONResultString = [ALResultEntry JSONStringFromList:resultData]; __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString - barcodeResult:@"" - image:result.image - scanPlugin:anylineOCRScanPlugin - viewPlugin:self.vinScanViewPlugin - completion:^{ + [self anylineDidFindResult:JSONResultString + barcodeResult:nil + image:scanResult.croppedImage + scanPlugin:scanPlugin + viewPlugin:self.scanViewPlugin completion:^{ ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = result.image; - + vc.imagePrimary = scanResult.croppedImage; [weakSelf.navigationController pushViewController:vc animated:YES]; }]; } @end + diff --git a/AnylineExamples/Anyline Examples Source/VIN/ocr_config_vin.json b/AnylineExamples/Anyline Examples Source/VIN/ocr_config_vin.json new file mode 100644 index 000000000..79375a607 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/VIN/ocr_config_vin.json @@ -0,0 +1,46 @@ +{ + "cameraConfig": { + "captureResolution": "1080p", + "zoomGesture": true + }, + "flashConfig": { + "mode": "manual", + "alignment": "top_left", + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "VIN", + "cancelOnResult": true, + "vinConfig": { + } + }, + "cutoutConfig": { + "style": "animated_rect", + "maxWidthPercent": "70%", + "maxHeightPercent": "70%", + "alignment": "top_half", + "ratioFromSize": { + "width": 62, + "height": 9 + }, + "outerColor": "000000", + "outerAlpha": 0.3, + "strokeWidth": 2, + "strokeColor": "0099FF", + "cornerRadius": 4, + "feedbackStrokeColor": "0099FF" + }, + "scanFeedbackConfig": { + "animation": "traverse_multi", + "animationDuration": 250, + "style": "contour_rect", + "strokeWidth": 2, + "strokeColor": "0099FF", + "fillColor": "220099FF", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": true + } + } +} + diff --git a/AnylineExamples/Anyline Examples Source/VIN/vin_capture_config.json b/AnylineExamples/Anyline Examples Source/VIN/vin_capture_config.json index e8a52de6c..f02f9d124 100644 --- a/AnylineExamples/Anyline Examples Source/VIN/vin_capture_config.json +++ b/AnylineExamples/Anyline Examples Source/VIN/vin_capture_config.json @@ -11,8 +11,8 @@ }, "outerColor": "000000", "outerAlpha": 0.3, - "strokeWidth": 1, - "strokeColor": "FFFFFF", + "strokeWidth": 2, + "strokeColor": "0099FF", "cornerRadius": 2, "feedbackStrokeColor": "0099FF" }, diff --git a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVRCScanViewController.h b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVRCScanViewController.h new file mode 100644 index 000000000..fbb16c7a8 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVRCScanViewController.h @@ -0,0 +1,10 @@ +#import +#import "ALBaseScanViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ALVRCScanViewController : ALBaseScanViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVRCScanViewController.m b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVRCScanViewController.m new file mode 100644 index 000000000..61faf8a49 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVRCScanViewController.m @@ -0,0 +1,92 @@ +#import "ALVRCScanViewController.h" +#import +#import "AnylineExamples-Swift.h" +#import "ALPluginResultHelper.h" + +@interface ALVRCScanViewController () + +@property (nonatomic, strong) ALScanViewPlugin *scanViewPlugin; + +@property (nonatomic, strong) ALScanViewConfig *scanViewConfig; + +@property (nonatomic, readonly) NSDictionary *scanViewConfigDict; + +@end + + +NSString * const kALVRCScanVC_configFilename = @"vehicle_registration_cert_config"; + + +@implementation ALVRCScanViewController + +- (void)dealloc { + NSLog(@"dealloc ALVRCScanViewController"); +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.title = @"VRC"; + self.controllerType = ALScanHistoryVehicleRegistrationCertificate; + + NSError *error; + self.scanViewPlugin = [ALScanViewPluginFactory withJSONDictionary:self.scanViewConfigDict]; + // check if there are errors + + self.scanViewConfig = [[ALScanViewConfig alloc] initWithJSONDictionary:self.scanViewConfigDict error:&error]; + // check if there are errors + + self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero + scanViewPlugin:self.scanViewPlugin + scanViewConfig:self.scanViewConfig + error:&error]; + // check if there are errors + + [self installScanView:self.scanView]; + + ALScanViewPlugin *scanViewPlugin = self.scanViewPlugin; + scanViewPlugin.scanPlugin.delegate = self; + + [self.scanView startCamera]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + NSError *error; + [self.scanViewPlugin startWithError:&error]; // could check the error +} + +// MARK: - Getters and Setters + +- (NSDictionary *)scanViewConfigDict { + return [[self configJSONStrWithFilename:kALVRCScanVC_configFilename] asJSONObject]; +} + + +// MARK: - Handle & present results + +- (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult { + [self enableLandscapeOrientation:NO]; + + ALVehicleRegistrationCertificateResult *vrcResult = scanResult.pluginResult.vehicleRegistrationCertificateResult; + NSArray *resultData = vrcResult.resultEntryList; + + NSString *resultJSONString = [ALResultEntry JSONStringFromList:resultData]; + + __weak __block typeof(self) weakSelf = self; + [self anylineDidFindResult:resultJSONString + barcodeResult:nil image:scanResult.croppedImage + scanPlugin:scanPlugin + viewPlugin:self.scanViewPlugin completion:^{ + + ALResultViewController *vc = [[ALResultViewController alloc] + initWithResults:resultData]; + vc.imagePrimary = scanResult.croppedImage; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]; +} + +@end + + diff --git a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVehicleRegistrationCertificateViewController.h b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVehicleRegistrationCertificateViewController.h deleted file mode 100644 index 3b65f4532..000000000 --- a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVehicleRegistrationCertificateViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// ALVehicleRegistrationCertificateViewController.h -// AnylineExamples -// -// Created by Renato Neves Ribeiro on 21.07.22. -// - -#import "ALBaseScanViewController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface ALVehicleRegistrationCertificateViewController : ALBaseScanViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVehicleRegistrationCertificateViewController.m b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVehicleRegistrationCertificateViewController.m deleted file mode 100644 index 20bd7fb55..000000000 --- a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/ALVehicleRegistrationCertificateViewController.m +++ /dev/null @@ -1,141 +0,0 @@ -// -// ALVehicleRegistrationCertificateViewController.m -// AnylineExamples -// -// Created by Renato Neves Ribeiro on 21.07.22. -// - -#import "ALVehicleRegistrationCertificateViewController.h" -#import "ALUniversalIDFieldnameUtil.h" - -@interface ALVehicleRegistrationCertificateViewController () - -@property (nonatomic, strong) ALIDScanViewPlugin *scanViewPlugin; -@property (nonatomic, strong) ALIDScanPlugin *scanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; - -@end - -@implementation ALVehicleRegistrationCertificateViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - CGRect frame = [self scanViewFrame]; - [self setTitle:@"Vehicle Registration Certificate"]; - NSError *error = nil; - NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:@"vehicle_registration_certificate_config" ofType:@"json"]; - NSData *jsonFile = [NSData dataWithContentsOfFile:jsonFilePath]; - NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData: jsonFile options: NSJSONReadingMutableContainers error: &error]; - self.scanViewPlugin = (ALIDScanViewPlugin *)[ALAbstractScanViewPlugin scanViewPluginForConfigDict:configDict delegate:self error:&error]; - - [self.scanViewPlugin addScanViewPluginDelegate:self]; - - NSAssert(self.scanViewPlugin, @"Setup Error: %@", error.debugDescription); - self.scanPlugin = self.scanViewPlugin.idScanPlugin; - - [self.scanPlugin addInfoDelegate:self]; - - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.scanViewPlugin]; - - self.controllerType = ALScanHistoryUniversalID; - - // After setup is complete we add the scanView to the view of this view controller - [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.view addSubview:self.scanView]; - [self.view sendSubviewToBack:self.scanView]; - NSArray *scanViewConstraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.scanView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor], - [self.scanView.rightAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.rightAnchor], - [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]]; - [self.view addConstraints:scanViewConstraints]; - [NSLayoutConstraint activateConstraints:scanViewConstraints]; - - //Start Camera: - [self.scanView startCamera]; - [self startListeningForMotion]; - [self setupFlipOrientationButton]; -} - -/* - This method will be called once the view controller and its subviews have appeared on screen - */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} - -/* - Cancel scanning to allow the module to clean up - */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.scanViewPlugin stopAndReturnError:nil]; -} - -/* - This method is used to tell Anyline to start scanning. It gets called in - viewDidAppear to start scanning the moment the view appears. Once a result - is found scanning will stop automatically (you can change this behaviour - with cancelOnResult:). When the user dismisses self.identificationView this - method will get called again. - */ -- (void)startAnyline { - [self startPlugin:self.scanViewPlugin]; -} - -#pragma mark -- ALIDPluginDelegate - -/* - This is the main delegate method Anyline uses to report its results - */ -- (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin - didFindResult:(ALIDResult *)scanResult { - [self.scanViewPlugin stopAndReturnError:nil]; - - // Handle a UniversalID result - ALUniversalIDIdentification *identification = (ALUniversalIDIdentification *)scanResult.result; - NSMutableString *resultHistoryString = [NSMutableString string]; - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - - [resultData addObjectsFromArray:[ALUniversalIDFieldnameUtil addIDSubResult:identification titleSuffix:@"" resultHistoryString:resultHistoryString]]; - resultData = [ALUniversalIDFieldnameUtil sortResultDataUsingFieldNamesWithSpace:resultData].mutableCopy; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:scanResult.image scanPlugin:anylineIDScanPlugin viewPlugin:self.scanViewPlugin completion:^{ - - ALResultViewController *vc = [[ALResultViewController alloc] initWithResults:resultData]; - vc.imagePrimary = scanResult.image; - vc.imageFace = [scanResult.result faceImage]; - - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.scanPlugin]; - } - -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin * _Nonnull)anylineScanPlugin - runSkipped:(ALRunSkippedReason * _Nonnull)runSkippedReason { - if (runSkippedReason.reason == ALRunFailureIDTypeNotSupported) { - [self updateScanWarnings:ALWarningStateIDNotSupported]; - } -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} - -@end diff --git a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/vehicle_registration_cert_config.json b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/vehicle_registration_cert_config.json new file mode 100644 index 000000000..f49ff84d0 --- /dev/null +++ b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/vehicle_registration_cert_config.json @@ -0,0 +1,55 @@ +{ + "flashConfig": { + "mode": "manual", + "alignment": "bottom_right" + }, + "viewPluginConfig": { + "pluginConfig": { + "id": "com.anyline.configs.plugin.vrc", + "vehicleRegistrationCertificateConfig": { + "vehicleRegistrationCertificate": { + "documentNumber": { "scanOption": 1, "minConfidence": 40 }, + "licensePlate": { "scanOption": 0, "minConfidence": 40 }, + "lastName": { "scanOption": 0, "minConfidence": 60 }, + "firstName": { "scanOption": 1, "minConfidence": 40 }, + "address": { "scanOption": 0, "minConfidence": 50 }, + "firstIssued": { "scanOption": 0, "minConfidence": 60 }, + "manufacturerCode": { "scanOption": 0, "minConfidence": 50 }, + "vehicleTypeCode": { "scanOption": 0, "minConfidence": 50 }, + "vehicleIdentificationNumber": { "scanOption": 0, "minConfidence": 60 }, + "brand": { "scanOption": 1, "minConfidence": 40 }, + "vehicleType": { "scanOption": 1, "minConfidence": 40 }, + "displacement": { "scanOption": 1, "minConfidence": 40 }, + "tire": { "scanOption": 1, "minConfidence": 50 } + } + }, + "cancelOnResult": true + }, + "cutoutConfig": { + "animation": "none", + "maxWidthPercent": "90%", + "maxHeightPercent": "80%", + "alignment": "center", + "ratioFromSize": { "width": 90, "height": 46 }, + "offset": { "x": 0, "y": 0 }, + "cropOffset": { "x": 0, "y": 0 }, + "cropPadding": { "x": 50, "y": 50 }, + "cornerRadius": 4, + "strokeColor": "0099FF", + "strokeWidth": 2, + "outerColor": "000000", + "feedbackStrokeColor": "0099FF", + "outerAlpha": 0.3 + }, + "scanFeedbackConfig": { + "style": "animated_rect", + "strokeWidth": 0, + "strokeColor": "0099ff", + "fillColor": "000099ff", + "beepOnResult": true, + "vibrateOnResult": true, + "blinkAnimationOnResult": false + } + } +} + diff --git a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/vehicle_registration_certificate_config.json b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/vehicle_registration_certificate_config.json index dfb20f563..4fd881292 100644 --- a/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/vehicle_registration_certificate_config.json +++ b/AnylineExamples/Anyline Examples Source/Vehicle Registration Certificate/vehicle_registration_certificate_config.json @@ -36,9 +36,9 @@ "maxWidthPercent": "90%", "maxHeightPercent": "80%", "alignment": "center", - "strokeWidth": 3, - "cornerRadius": 8, - "strokeColor": "FFFFFF", + "strokeWidth": 2, + "cornerRadius": 4, + "strokeColor": "0099FF", "outerColor": "000000", "outerAlpha": 0.3, "ratioFromSize": { diff --git a/AnylineExamples/Anyline Examples Source/VoucherCode/ViewController/ALVoucherCodeScanViewController.m b/AnylineExamples/Anyline Examples Source/VoucherCode/ViewController/ALVoucherCodeScanViewController.m index b294ddb46..f63f3bc44 100644 --- a/AnylineExamples/Anyline Examples Source/VoucherCode/ViewController/ALVoucherCodeScanViewController.m +++ b/AnylineExamples/Anyline Examples Source/VoucherCode/ViewController/ALVoucherCodeScanViewController.m @@ -13,12 +13,12 @@ #import "AnylineExamples-Swift.h" // The controller has to conform to to be able to receive results -@interface ALVoucherCodeScanViewController () +@interface ALVoucherCodeScanViewController () // // The Anyline plugin used for OCR -@property (nonatomic, strong) ALOCRScanViewPlugin *voucherScanViewPlugin; -@property (nonatomic, strong) ALOCRScanPlugin *voucherScanPlugin; -@property (nullable, nonatomic, strong) ALScanView *scanView; +//@property (nonatomic, strong) ALOCRScanViewPlugin *voucherScanViewPlugin; +//@property (nonatomic, strong) ALOCRScanPlugin *voucherScanPlugin; +//@property (nullable, nonatomic, strong) ALScanView *scanView; @end @@ -33,30 +33,30 @@ - (void)viewDidLoad { CGRect frame = [self scanViewFrame]; - ALOCRConfig *config = [[ALOCRConfig alloc] init]; - config.characterWhitelist = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - config.validationRegex = @"[A-Z0-9]{8}$"; - config.scanMode = ALLine; - - NSError *error = nil; - - self.voucherScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" - delegate:self - ocrConfig:config - error:&error]; - NSAssert(self.voucherScanPlugin, @"Setup Error: %@", error.debugDescription); - [self.voucherScanPlugin addInfoDelegate:self]; - - NSString *confPath = [[NSBundle mainBundle] pathForResource:@"voucher_code_config" ofType:@"json"]; - ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; - - self.voucherScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.voucherScanPlugin - scanViewPluginConfig:scanViewPluginConfig]; - NSAssert(self.voucherScanViewPlugin, @"Setup Error: %@", error.debugDescription); - [self.voucherScanViewPlugin addScanViewPluginDelegate:self]; - - // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen - self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.voucherScanViewPlugin]; +// ALOCRConfig *config = [[ALOCRConfig alloc] init]; +// config.characterWhitelist = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; +// config.validationRegex = @"[A-Z0-9]{8}$"; +// config.scanMode = ALLine; +// +// NSError *error = nil; +// +// self.voucherScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR" +// delegate:self +// ocrConfig:config +// error:&error]; +// NSAssert(self.voucherScanPlugin, @"Setup Error: %@", error.debugDescription); +// [self.voucherScanPlugin addInfoDelegate:self]; +// +// NSString *confPath = [[NSBundle mainBundle] pathForResource:@"voucher_code_config" ofType:@"json"]; +// ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath]; +// +// self.voucherScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.voucherScanPlugin +// scanViewPluginConfig:scanViewPluginConfig]; +// NSAssert(self.voucherScanViewPlugin, @"Setup Error: %@", error.debugDescription); +// [self.voucherScanViewPlugin addScanViewPluginDelegate:self]; +// +// // Initializing the scan view. It's a UIView subclass. We set the frame to fill the whole screen +// self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.voucherScanViewPlugin]; // After setup is complete we add the scanView to the view of this view controller [self.scanView setTranslatesAutoresizingMaskIntoConstraints:NO]; @@ -71,7 +71,7 @@ - (void)viewDidLoad { //Start Camera: [self.scanView startCamera]; - [self startListeningForMotion]; +// [self startListeningForMotion]; self.controllerType = ALScanHistoryIban; @@ -80,21 +80,21 @@ - (void)viewDidLoad { /* This method will be called once the view controller and its subviews have appeared on screen */ --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // We use this subroutine to start Anyline. The reason it has its own subroutine is - // so that we can later use it to restart the scanning process. - [self startAnyline]; -} +//-(void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// +// // We use this subroutine to start Anyline. The reason it has its own subroutine is +// // so that we can later use it to restart the scanning process. +// [self startAnyline]; +//} /* Cancel scanning to allow the scan view plugin to clean up */ -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.voucherScanViewPlugin stopAndReturnError:nil]; -} +//- (void)viewWillDisappear:(BOOL)animated { +// [super viewWillDisappear:animated]; +// [self.voucherScanViewPlugin stopAndReturnError:nil]; +//} /* This method is used to tell Anyline to start scanning. It gets called in @@ -103,51 +103,51 @@ is found scanning will stop automatically (you can change this behaviour with cancelOnResult:). When the user dismisses self.identificationView this method will get called again. */ -- (void)startAnyline { - [self startPlugin:self.voucherScanViewPlugin]; - self.startTime = CACurrentMediaTime(); -} - -- (void)stopAnyline { - if (self.voucherScanPlugin.isRunning) { - [self.voucherScanViewPlugin stopAndReturnError:nil]; - } -} - -- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { - //Update Position of Warning Indicator - [self updateWarningPosition: - cutoutRect.origin.y + - cutoutRect.size.height + - self.scanView.frame.origin.y + - 80]; -} +//- (void)startAnyline { +// [self startPlugin:self.voucherScanViewPlugin]; +// self.startTime = CACurrentMediaTime(); +//} +// +//- (void)stopAnyline { +// if (self.voucherScanPlugin.isRunning) { +// [self.voucherScanViewPlugin stopAndReturnError:nil]; +// } +//} + +//- (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin updatedCutout:(CGRect)cutoutRect { +// //Update Position of Warning Indicator +// [self updateWarningPosition: +// cutoutRect.origin.y + +// cutoutRect.size.height + +// self.scanView.frame.origin.y + +// 80]; +//} #pragma mark -- ALOCRScanPluginDelegate /* This is the main delegate method Anyline uses to report its results */ -- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { - NSMutableArray *resultData = [[NSMutableArray alloc] init]; - [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Voucher Code" value:result.result shouldSpellOutValue:YES]]; - NSString *jsonString = [self jsonStringFromResultData:resultData]; - - __weak __block typeof(self) weakSelf = self; - [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.voucherScanViewPlugin completion:^{ - [self stopAnyline]; - ALResultViewController *vc = [[ALResultViewController alloc] - initWithResults:resultData]; - vc.imagePrimary = result.image; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]; -} - -- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ - if ([info.variableName isEqualToString:@"$brightness"]) { - [self updateBrightness:[info.value floatValue] forModule:self.voucherScanViewPlugin]; - } - -} +//- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result { +// NSMutableArray *resultData = [[NSMutableArray alloc] init]; +// [resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Voucher Code" value:result.result shouldSpellOutValue:YES]]; +// NSString *jsonString = [self JSONStringFromResultData:resultData]; +// +// __weak __block typeof(self) weakSelf = self; +// [self anylineDidFindResult:jsonString barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.voucherScanViewPlugin completion:^{ +// [self stopAnyline]; +// ALResultViewController *vc = [[ALResultViewController alloc] +// initWithResults:resultData]; +// vc.imagePrimary = result.image; +// [weakSelf.navigationController pushViewController:vc animated:YES]; +// }]; +//} +// +//- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{ +// if ([info.variableName isEqualToString:@"$brightness"]) { +// [self updateBrightness:[info.value floatValue] forModule:self.voucherScanViewPlugin]; +// } +// +//} @end diff --git a/AnylineExamples/Anyline Examples Source/VoucherCode/voucher_code_config.json b/AnylineExamples/Anyline Examples Source/VoucherCode/voucher_code_config.json index 8491b50c3..eadfcebd6 100644 --- a/AnylineExamples/Anyline Examples Source/VoucherCode/voucher_code_config.json +++ b/AnylineExamples/Anyline Examples Source/VoucherCode/voucher_code_config.json @@ -11,8 +11,8 @@ "height": 1 }, "strokeWidth": 2, - "cornerRadius": 10, - "strokeColor": "FFFFFF", + "cornerRadius": 4, + "strokeColor": "0099FF", "outerColor": "000000", "outerAlpha": 0.3, "feedbackStrokeColor": "32ADFF" @@ -20,7 +20,7 @@ "scanFeedback" : { "style": "contour_point", "strokeColor": "32ADFF", - "strokeWidth": 3, + "strokeWidth": 2, "beepOnResult": true, "vibrateOnResult": true, "blinkAnimationOnResult": true diff --git a/AnylineExamples/AnylineExamples.xcodeproj/project.pbxproj b/AnylineExamples/AnylineExamples.xcodeproj/project.pbxproj index 6895c8c9e..773640b5e 100644 --- a/AnylineExamples/AnylineExamples.xcodeproj/project.pbxproj +++ b/AnylineExamples/AnylineExamples.xcodeproj/project.pbxproj @@ -20,43 +20,45 @@ 07C382512D3E2C2456D47B16 /* UIColor+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E96287CC71693DD8C9232C6 /* UIColor+ALExamplesAdditions.m */; }; 095CB4818B3736D4CCF60B13 /* ALBarcodeResultUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = D99C3AF7A5F231E20545B326 /* ALBarcodeResultUtil.m */; }; 0AFBB4F74889B1364B1EA233 /* ALScrabbleScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ACCFE8F5694C900C7A15F44 /* ALScrabbleScanViewController.m */; }; - 0BA197D595DC6A8477FC5343 /* ALAFLicensePlateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F00A41DD54298180480D664 /* ALAFLicensePlateViewController.m */; }; + 0DFF6DD995D15E50D7163470 /* vehicle_config_license_plate_eu.json in Resources */ = {isa = PBXBuildFile; fileRef = 3602E347A7732F9343FB718B /* vehicle_config_license_plate_eu.json */; }; 0F5545C5A922F2ABCFAE2845 /* ReadingTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B7A174D434351C30AA815B7 /* ReadingTableViewCell.m */; }; 110B69C401740F597F4D4237 /* ALISBNScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C2DE5E7E740DE6CE65330E56 /* ALISBNScanViewController.m */; }; 1175ADE866CE976EFFC54EDB /* TireViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB06AE3FB930F1B0781316C /* TireViewController.swift */; }; - 122FC76CBA910344E10CA488 /* ALUniversalIDFieldnameUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AD2327535110C3026475005 /* ALUniversalIDFieldnameUtil.m */; }; - 126C1E99EAA1D1E63FAB2CCE /* meter_barcode_view_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 7A74558707FFE3B297265433 /* meter_barcode_view_config.json */; }; 13805B096B1C7489DE2D956E /* WorkforceToolResultViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F5CA65FF0C687D43AC37D3 /* WorkforceToolResultViewController.m */; }; 14D077C321FC3BD2C4E48A2A /* ALCattleTagScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AE6E061296A4581FB66B20 /* ALCattleTagScanViewController.m */; }; 169B4C9E31B54A76C796C481 /* ALCustomBarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 8559369BC2271AFE0A5F4A67 /* ALCustomBarButton.m */; }; + 17A53ACF560340D93B51F9DD /* SerialNumberSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961E85891D0EB4CCC53350BC /* SerialNumberSettings.swift */; }; 182D8027B52B44AEF891E12D /* serial_number_view_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A5A0B8B16A226B0EAC39924 /* serial_number_view_config.json */; }; 18CCD1DA39115412EB8F04DD /* ALMROExampleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A0D5067A874DE2D141541714 /* ALMROExampleManager.m */; }; - 190C9F7DC0103BDD709F6701 /* GifuWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4413505AA97F9234BD1A420 /* GifuWrapper.swift */; }; 194E973F43A3B0B57A330BB5 /* energyMockData2.json in Resources */ = {isa = PBXBuildFile; fileRef = 2DC7E98210F6761127C7F0CD /* energyMockData2.json */; }; 1B339AD1A6982A23A58AFBD5 /* AnylineEnergyModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 42A56CBF24159FDD12C0076B /* AnylineEnergyModel.xcdatamodeld */; }; 1BDA70B0798FEBA9AED871A9 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = A55CA11F512D1EB3147C6D35 /* Reachability.m */; }; 216AD56855460694DB2EAFD2 /* ALToggleControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 602AF9DF62FC564C6646D2E5 /* ALToggleControl.m */; }; 21A22328A97C63E67AE854BA /* ALProductExampleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F1E78B6137D667B2BAFF771 /* ALProductExampleManager.m */; }; - 2281E6053A1BED4163CDDC0F /* universal_id_arabic_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B87E9374F67894CA3A1F4FE /* universal_id_arabic_config.json */; }; + 2311BF58E7C0C70EADF84D27 /* sample_barcode_config.json in Resources */ = {isa = PBXBuildFile; fileRef = E3F1A5ADF3152DDB67BBB2EC /* sample_barcode_config.json */; }; 236D1FD2A106E2966CD41B30 /* WorkforceTool+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = C474F22983E364473A5F91A8 /* WorkforceTool+CoreDataProperties.m */; }; - 253C818A2B144F00DB6636B0 /* ALUSLicensePlateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF3E107E3628045E2154C532 /* ALUSLicensePlateViewController.m */; }; 2546FA63E48995AA69412DE5 /* CustomerDataView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E59DF7BD4220A8FE5450AAA9 /* CustomerDataView.xib */; }; 258A4B98277993719781A15A /* ALBarcodeFormatHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 53BF35330525A5B4B80547BB /* ALBarcodeFormatHelper.m */; }; 264757EB2EB2998FB04CDC77 /* ALDeviceInformationHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = FDCEFD699881115D834BAA3A /* ALDeviceInformationHelper.m */; }; 27533612D3BBEC73BCD89200 /* ALScrabbleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E148202561E98484D64F0C /* ALScrabbleViewController.m */; }; + 27F51F97C80D8187F68CFF83 /* ALUniversalIDScanConfigController.m in Sources */ = {isa = PBXBuildFile; fileRef = 11A8F717AE5215355CA0790F /* ALUniversalIDScanConfigController.m */; }; 283D6E7FAC03BE4255C5B030 /* ALColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 678CE157440B405ADF327B28 /* ALColor.m */; }; - 29831F17C4FF37E76BC5B011 /* ALLicensePlateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EFF08A08B5EE72241A016DF0 /* ALLicensePlateViewController.m */; }; + 28FFA95E225588B9EB89B8FF /* template_type_and_region_mapping.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B81AFCF2CBCB3331B584E5C /* template_type_and_region_mapping.json */; }; 29D8242790C62F87231582E6 /* ALLicensePlateResultOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13881BADEC0C6D4F757DEC90 /* ALLicensePlateResultOverlayView.m */; }; 2D1EC37BF43B70AA6016824D /* CustomerSelfReadingConfirmationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E539A0891F231A43F3A7089A /* CustomerSelfReadingConfirmationViewController.xib */; }; + 2D8766A4864BC62B9A6F85C1 /* tire_config_tin.json in Resources */ = {isa = PBXBuildFile; fileRef = 8CEEE043EF359766A6BCDBAA /* tire_config_tin.json */; }; 2FEAFACDC392E8898C3C97BD /* ALRoundedView.m in Sources */ = {isa = PBXBuildFile; fileRef = A15FCC2BD1A9E95397F7F99F /* ALRoundedView.m */; }; 30F4F4027665E6F24DC48EC5 /* ALParallelMeterWithJSONScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9990A51CA256F52B88A59AE0 /* ALParallelMeterWithJSONScanViewController.m */; }; + 328BE2F58D9676B0DB02BC20 /* serial_meter_barcode_config.json in Resources */ = {isa = PBXBuildFile; fileRef = D158CCA376D3897CDD7B0313 /* serial_meter_barcode_config.json */; }; 332E5FE5513F6CDD2346D6D2 /* ALUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BBEF6BE85BA00F9E1011D1E1 /* ALUtils.m */; }; + 35A59E9A177AEDC684FE6631 /* vehicle_config_license_plate_af.json in Resources */ = {isa = PBXBuildFile; fileRef = 12D7CF237BE3E4DB8F98A5C9 /* vehicle_config_license_plate_af.json */; }; 37B2D510A28CED75400D97AF /* ALExampleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B7F93940133379A464B2ECA1 /* ALExampleManager.m */; }; 37B8BA82610E2579475245FC /* ALNFCScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D76DB0B1EDA3DEE5553F4D2 /* ALNFCScanViewController.m */; }; 37FA8753994D60E353707D5E /* cow_tag_capture_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 464FAFFE2D244084E91CABC9 /* cow_tag_capture_config.json */; }; 382DD1C0C8F51585A0F699F6 /* CustomerSelfReadingConfirmationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BB04F45409076E98165CCE2D /* CustomerSelfReadingConfirmationViewController.m */; }; 385239AF4AE6238CE1452B31 /* Customer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D1C8024BC707860460ECFCE /* Customer.m */; }; 3960189A0D924E92E93599B8 /* ALGridCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AC802CBECE3BEC190BB90BC /* ALGridCollectionViewController.m */; }; + 39E93F86C5BACD85EB12E556 /* ALLicensePlateScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D4E1293D86A9F5436B4C64AD /* ALLicensePlateScanViewController.m */; }; 3A9ED79B2EAD0E0CDC1E2F88 /* ALRecordNumberScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 40D95BAB90478502C129F9F4 /* ALRecordNumberScanViewController.m */; }; 3AB4C32E8B0BB9540DBD4A22 /* WorkorderViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 355AD17D434245A0D11FBA9E /* WorkorderViewController.xib */; }; 3D4CF193812283821EE0C52F /* ALIdentificationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2EB9E82C48102735C47BF0 /* ALIdentificationView.m */; }; @@ -66,6 +68,7 @@ 3FD6E7E2F5050E4CE427F62F /* ALMeterReadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90082EB5EF42EDECAF5C0CA0 /* ALMeterReadingView.m */; }; 406E5D4689D2162E66631DCF /* iban_config.json in Resources */ = {isa = PBXBuildFile; fileRef = C6710658F42970400FD78BD0 /* iban_config.json */; }; 409F58D9331828393B73B29D /* ALTutorialViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A168F44A92FFCA7CAD631C9 /* ALTutorialViewController.m */; }; + 40F8338328B75E861FD31AC7 /* pepsi_code_scanner.ale in Resources */ = {isa = PBXBuildFile; fileRef = DE2078D35FF9AFB200722103 /* pepsi_code_scanner.ale */; }; 4132425F48F3428439BDDBA5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = ACF1D09EF06128D92632D6CB /* AppDelegate.m */; }; 41EB653535CEAEE4A8E075C5 /* ALIBANScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 997B2A1F82805B0685BBA76E /* ALIBANScanViewController.m */; }; 443B304C865770E9A68AE47A /* Customer+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AE01852827507975736BFED /* Customer+CoreDataProperties.m */; }; @@ -74,24 +77,34 @@ 473E4D82CC7B3C037319283D /* NSString+Util.m in Sources */ = {isa = PBXBuildFile; fileRef = 23117B72847A07EB7D0A2AC0 /* NSString+Util.m */; }; 486D260E0AA1DCD6BC257483 /* ScanHistory+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D39733E2B7D3BF8963BE7BD /* ScanHistory+CoreDataProperties.m */; }; 48BF457F44BE29DECD0930B7 /* WorkForceViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF9D4EDF7F1ACEEF688A8784 /* WorkForceViewController.xib */; }; + 49CE1D6389C3AF9CD8A7D0AE /* driver_license_front_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 2505BCAB8B12C613CE696B74 /* driver_license_front_config.json */; }; 4A5A1D0364B519D7F3FFABC6 /* ALDialMeterScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A424D0F5DC83E2BFF249BA05 /* ALDialMeterScanViewController.m */; }; + 4A9D8E4A7DD96DCF12704AF2 /* ALUniveralIDResultHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0500DAD07B3DEA2CD595D9B9 /* ALUniveralIDResultHelper.m */; }; + 4BA88C71EE692683050BB74D /* vertical_container_scanner_capture_config.json in Resources */ = {isa = PBXBuildFile; fileRef = AA690CB35CB9AE5A1C41EF3E /* vertical_container_scanner_capture_config.json */; }; 4D515F3438EE08E225088CA7 /* ALTINScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A3E33501354D63AEBF450ACA /* ALTINScanViewController.m */; }; + 4EAD3FECAD05047D60A98D59 /* ALLeftCheckmarkCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F152B3906D4618C66634019C /* ALLeftCheckmarkCell.swift */; }; 4FFCDDFFE82E17F6D6C38CCE /* ALOthersExampleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D734F16D23B623323CB450A /* ALOthersExampleManager.m */; }; 503DCA316D0C202AF406CCAA /* AnylineResources.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5D09863F2A78CC2C3B9EBE0E /* AnylineResources.bundle */; }; - 507F27646299BFC4E6A3B20E /* vertical_container_scanner_capture_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 3A67ACF7B450115C3E36A9EA /* vertical_container_scanner_capture_config.json */; }; 515D752A0145EBC1C4F37E79 /* ALCustomToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF73219598C155CF0603175 /* ALCustomToolbar.m */; }; 51C38786D4765B59D70915BC /* vin_capture_config.json in Resources */ = {isa = PBXBuildFile; fileRef = CB56AC0CF88F101A75FF5F3E /* vin_capture_config.json */; }; 51E7110C5AC4276620609EAC /* WorkforceTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 24612698857CFE3971A3AE51 /* WorkforceTool.m */; }; 53029EFD2163E8748EC913AE /* ALDialogSelectionTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E2CEF352E355ABC1E7A6A81 /* ALDialogSelectionTableViewCell.m */; }; - 5696F41B6116EFE209F7D4A4 /* ALVerticalContainerScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4206191D0D142A20C1D05C8F /* ALVerticalContainerScanViewController.m */; }; 5A7ED66F3BA5635A9B183B5B /* ALIdentityDocumentsExampleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B40F5ACD2BF3B121A490FAE /* ALIdentityDocumentsExampleManager.m */; }; + 5A8A2848CE8A3CBDFE0B1EAA /* bottlecap_config.json in Resources */ = {isa = PBXBuildFile; fileRef = B77C4FF2B3BC5111904B600C /* bottlecap_config.json */; }; 5BC563C4483045E763BA0EAF /* NSManagedObject+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B1866752D7457CFD00F2BB10 /* NSManagedObject+ALExamplesAdditions.m */; }; + 5C797FDAC23F78495D38EF03 /* ALTextInputTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEDF1910585C87FCEEDA12A /* ALTextInputTableViewCell.swift */; }; + 5CAB42391E1E0AC65BB4CB1E /* universal_id_front_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 75EE32EDE551A66FEB4F027B /* universal_id_front_config.json */; }; 620A72D55067A153CAD7F4DF /* UIFont+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A18C42E39BF797CCFDCA51E9 /* UIFont+ALExamplesAdditions.m */; }; + 62DFD74D11E735783CFF2034 /* mrz_nfc_config.json in Resources */ = {isa = PBXBuildFile; fileRef = C5F2509735729617E12FA0F8 /* mrz_nfc_config.json */; }; + 64E90611C37D3635E6146855 /* CutoutSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 938DEE22539D3F061BDD3825 /* CutoutSettings.swift */; }; + 653B10DE44298C689DBB4163 /* horizontal_container_scanner_capture_config.json in Resources */ = {isa = PBXBuildFile; fileRef = E4CAC353654020B0D2C04771 /* horizontal_container_scanner_capture_config.json */; }; 6A3B7F7A4EB2FA1224CB7B3C /* ALEnergyBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8BBF33123C5DED64F598FF /* ALEnergyBaseViewController.m */; }; 6A5F1FB469924DC9ACCF4163 /* ALExample.m in Sources */ = {isa = PBXBuildFile; fileRef = B7B4776BB82FA4F7729784D0 /* ALExample.m */; }; - 6D18D4FC00EE5AACCBB6B2BD /* ALVehicleRegistrationCertificateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 65DAADF2E811C3B198393F6C /* ALVehicleRegistrationCertificateViewController.m */; }; + 6B8886F14C250DC89003C287 /* template_type_and_region_mapping_cyrillic.json in Resources */ = {isa = PBXBuildFile; fileRef = 0A5E58E4C86C0605BE083881 /* template_type_and_region_mapping_cyrillic.json */; }; 6E36CB15F322CF98A84D8467 /* ALScanResultViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8CB4729C4A9C0FEBF226E57 /* ALScanResultViewController.m */; }; + 6E4690B70636736BC2A31923 /* AdvancedSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FB7DBE59B9BF6DE051F5B91 /* AdvancedSettingsViewController.swift */; }; 6F80C436AEC24B717740CF88 /* ScanHistoryMigration3to4.m in Sources */ = {isa = PBXBuildFile; fileRef = 61A5FEA61C1C1ACB0265F519 /* ScanHistoryMigration3to4.m */; }; + 70858487365B8FDA346F4E9D /* ALBottlecapScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F36A14C14B24C4B5D0C59E1E /* ALBottlecapScanViewController.m */; }; 70A4D305EAB9D7D45D30B58A /* voucher_code_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 96A3D3139D636DFCF875E8FA /* voucher_code_config.json */; }; 7160AD923669EB0720FCD3C9 /* CoreDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D11E06DF396B1B2615A7D5C2 /* CoreDataManager.m */; }; 71E8873219BC85D682B35AF1 /* UIViewController+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 993E94F5B4D905C28394B2AD /* UIViewController+ALExamplesAdditions.m */; }; @@ -108,7 +121,10 @@ 82098553EF9F70DCD53166C1 /* NSUserDefaults+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E35EBC0F2547C2A286FD841 /* NSUserDefaults+ALExamplesAdditions.m */; }; 825554D17F253D580D3E6603 /* ALMeterExampleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B7E4BDD67B0B2AA88763193 /* ALMeterExampleManager.m */; }; 83C2E2BFA23265B9E254A1D1 /* ALBaseScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 49A507ABFDFAE4C3298D842D /* ALBaseScanViewController.m */; }; + 8405CEB9C5B8E864D8430024 /* tire_config_commercial_tire_id.json in Resources */ = {isa = PBXBuildFile; fileRef = 5F6EBC6A23FB72F8EA3B013F /* tire_config_commercial_tire_id.json */; }; + 840FADEE4C91C71438F86666 /* ALContainerScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 65BAE9DE655BD12A9D60F3AC /* ALContainerScanViewController.m */; }; 841B7C06D4FA85F6D334580C /* ALISBNHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7474A92ECB1EC93FFE2A523F /* ALISBNHeaderCell.m */; }; + 84BDD80EFB9A397D56E23831 /* template_type_and_region_mapping_arabic.json in Resources */ = {isa = PBXBuildFile; fileRef = BBE040B07CF4EF032821E053 /* template_type_and_region_mapping_arabic.json */; }; 8543A04986941842302938D1 /* UIView+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A8B3E959502E4A04A0D95FF /* UIView+ALExamplesAdditions.m */; }; 860F95A49274210ADE787DA0 /* meter_barcode_parallel.json in Resources */ = {isa = PBXBuildFile; fileRef = F84B123B1654CB102F551D25 /* meter_barcode_parallel.json */; }; 8678F0EF3FACD7EB8A9AAE26 /* ReadingTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 254FBCFC83BBCE0B37B8CD99 /* ReadingTableViewCell.xib */; }; @@ -116,27 +132,34 @@ 87CCC52F9F8B0CFEE789DAFF /* NSAttributedString+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 54C6C24B452735E53395244B /* NSAttributedString+ALExamplesAdditions.m */; }; 89AFB0E5A483B31B0AFCCA85 /* CustomerDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F92107DB6698B83180CD5864 /* CustomerDataViewController.m */; }; 8DF1F05CDED63700EEF343C5 /* NSArray+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8997ECCC3F31FC24E06298FD /* NSArray+ALExamplesAdditions.m */; }; + 8EB00F60AFB0F24DE41ECE84 /* BaseSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51CE329A413946D4A19C6D8 /* BaseSettingsViewController.swift */; }; 90EE64FF8696C360624B0722 /* ALMeterReading.m in Sources */ = {isa = PBXBuildFile; fileRef = E01BF8D357703EF4FA7E4F3F /* ALMeterReading.m */; }; 91302FC86FDA4BCFCE864CAD /* NSManagedObjectContext+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A570607C0C1C45A39FFE134C /* NSManagedObjectContext+ALExamplesAdditions.m */; }; 91B62B8BB91EF62AE767AF17 /* barcode_pdf417_in_id.json in Resources */ = {isa = PBXBuildFile; fileRef = 78F03F897F8FDA41B978488D /* barcode_pdf417_in_id.json */; }; 923D2E3DC71E410C28E45910 /* CustomerSelfReadingResultViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFD7D8491897962E508C552 /* CustomerSelfReadingResultViewController.m */; }; + 928506238F97E4339010FB34 /* mrz_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 140C530F385C9A0ADC32A183 /* mrz_config.json */; }; 9516DCB1D2B2D301D7A01D36 /* colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 678532EDC412A7D9CFA127A7 /* colors.xcassets */; }; 960A7953672EA0B639A30FA5 /* WorkforceToolResultViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2093FE4EF48CEEDBC2CE51D8 /* WorkforceToolResultViewController.xib */; }; - 98040C0E88114B038FA681E9 /* universal_id_camera_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 1C16DC0D29C28EA8EF20D654 /* universal_id_camera_config.json */; }; + 964A314C4CDF9A84E1E2A899 /* ALMeterScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FFDFBDFBA612C608534753 /* ALMeterScanViewController.swift */; }; 993857DE93729EB601CD1A8E /* ALMeterSelectView.m in Sources */ = {isa = PBXBuildFile; fileRef = DBCCB00C4D68018A8D821988 /* ALMeterSelectView.m */; }; 99C4087E7BEAFC425D5F1736 /* Anyline.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 79974B0F2C88170B9C8C9E08 /* Anyline.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9AEE556559232DFCD1E18C3A /* ALCheckbox.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D7E8D46EC14ED14B84F0FAE /* ALCheckbox.m */; }; + 9B35130FC37EEA0189FA764E /* vehicle_registration_cert_config.json in Resources */ = {isa = PBXBuildFile; fileRef = C08544CE3BE7CEFE3FCCA267 /* vehicle_registration_cert_config.json */; }; 9B85D1299B1E0B254BA1C6CA /* ALRBScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 733B96E1E727AC69E01649E6 /* ALRBScanViewController.m */; }; 9BA532A518522696002B0872 /* ALAwardsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 06B40EC29D2A0CFA6AC2651C /* ALAwardsView.m */; }; 9D6D1A47066EC5C9D3CAE9F4 /* ALLicensePlateExampleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C4E617625C1AA097008BADE0 /* ALLicensePlateExampleManager.m */; }; + A07CD1E8B7D961556C9221D1 /* ALRatioTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42E52B6E0AF185BDA0E6B79E /* ALRatioTableViewCell.swift */; }; A19EC2C4EDE4E23A8233D63A /* ALAutoAnalogDigitalMeterScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 182DEF617BE080B414491B04 /* ALAutoAnalogDigitalMeterScanViewController.m */; }; A58132C2E27BA742474165A3 /* vehicle_registration_certificate_config.json in Resources */ = {isa = PBXBuildFile; fileRef = ECBB4E54E07A19394D2AD07B /* vehicle_registration_certificate_config.json */; }; A66630A6C0A9ECB50C022625 /* FormFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9DE990FB41CB3666F5E3B58 /* FormFieldView.swift */; }; A70B12B1EB0583ABBFAAAECF /* CustomerSelfReading+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = DF764271604E0EB992306FBB /* CustomerSelfReading+CoreDataProperties.m */; }; A7778909FCEA0763AF157E37 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7026ED1172CCE2593E132DFF /* main.m */; }; A8924A6DC244EC095BD6BCB1 /* AnylineExamples.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = D498A3A2FC5316566EC89F7F /* AnylineExamples.xcdatamodeld */; }; + A8D45D4954D11214DE13AC73 /* vehicle_config_license_plate_us.json in Resources */ = {isa = PBXBuildFile; fileRef = 122ECADCFD6E28BF208F6186 /* vehicle_config_license_plate_us.json */; }; A8E6D97EEE1E0D0A5C675964 /* CustomerDataViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 442C9FF1588611259A884BC4 /* CustomerDataViewController.xib */; }; A9B86F7EC70516E6742E48BA /* ALParallelMeterScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA6D34271AD62305E175DE9 /* ALParallelMeterScanViewController.m */; }; + A9BBFD1ACDD29006C67B5142 /* ALUnselectableLinkableTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3B3AB626A67D05468E6576C /* ALUnselectableLinkableTextView.swift */; }; + ABDA19B56626D2838BF2B00B /* AnylineBottlecapScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439AB981070B2ADD388639C1 /* AnylineBottlecapScanViewController.swift */; }; ACD1F695702B436C98BFB2A1 /* ALResultCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A569212ED42ECA2D294EA7A /* ALResultCell.swift */; }; AE24A6531BBE3500185E26EE /* energyMockData1.json in Resources */ = {isa = PBXBuildFile; fileRef = 8423FA8B204ED6781568BABD /* energyMockData1.json */; }; AE4562D43E2A1260A78D10EE /* ALScrabbleWord.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F54895F8F550A096FEF90C1 /* ALScrabbleWord.m */; }; @@ -147,40 +170,49 @@ B49B5638CE76407C30941E70 /* scrabble_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 6FCF06B3B2CD8A6056D6CAD5 /* scrabble_config.json */; }; B8C1BB40368F01856FE10792 /* ReadingDetailsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FEFF3B2A195CB1BC742F07A4 /* ReadingDetailsViewController.m */; }; B9C04394AB2B1F3688EABC98 /* ReadingTransformationPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4156A1644B315B70FE0B8419 /* ReadingTransformationPolicy.m */; }; + BA0A886211727B22CD490B62 /* ALBarcodeTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CBB31FD29F5241AD587F39A /* ALBarcodeTypes.m */; }; BB1A1B3F63B629057BC79103 /* ALMainPageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B76762D974C43BF0286E13 /* ALMainPageViewController.m */; }; BBE58E8DA06EF48150752E93 /* ALIDCountryHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BCDB9656CE8EF8FF43E78C1 /* ALIDCountryHelper.m */; }; BCBE543B8A4F2D0438610730 /* ALBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F2143CC6945384EC804BA0 /* ALBaseViewController.m */; }; BCEDAE444AB969E5885E0B84 /* ALIntroHelpView.m in Sources */ = {isa = PBXBuildFile; fileRef = E84E52042DF87A432B7C4A09 /* ALIntroHelpView.m */; }; + BD506409ECC64FFF9C9A5628 /* parallel_meter_barcode_config.json in Resources */ = {isa = PBXBuildFile; fileRef = DCFFEEDAD51ED4572C937402 /* parallel_meter_barcode_config.json */; }; + BE300F0D1554BC645D1EF04A /* driver_license_composite_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 0383C6755E8D9BC974CC11A8 /* driver_license_composite_config.json */; }; BE3BFA9D178805750111044D /* ALScanResultViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B99D95A790613724D2917D97 /* ALScanResultViewController.xib */; }; BF07386056E53CFE5C441BB7 /* ALVINScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDE8754C4C6459C4483851D /* ALVINScanViewController.m */; }; BF280388FFE08C65889B8199 /* ALBaseGridCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5408415289B1FE9524543AA3 /* ALBaseGridCollectionViewController.m */; }; BF5534687932FF0FBC0742BB /* record_number_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 57B53E62AD3B670B163C3777 /* record_number_config.json */; }; - BF6F82EFCC1CC484AB861FEF /* ALContainerScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E8F1BC85E70148A9D26AAE9 /* ALContainerScanViewController.m */; }; C170B4970555750081E80741 /* ALUniversalIDScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 186AC71508B2BFEF5BB5537E /* ALUniversalIDScanViewController.m */; }; C1AB4556E5C27951FCB76C00 /* ALHeaderCollectionReusableView.m in Sources */ = {isa = PBXBuildFile; fileRef = F79688067905522060BCFE75 /* ALHeaderCollectionReusableView.m */; }; C42ACC412805B581937ABA15 /* ALScrabblePoints.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D90102F4DB805B0DA85EC33 /* ALScrabblePoints.m */; }; - C8302D96CB313E588383B035 /* container_scanner_capture_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 43BE0DB9AD5AA0BBB178E0D2 /* container_scanner_capture_config.json */; }; C9E50E9B907B2A85325FE0A1 /* ALMeterCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34760A85BED4BAACE6AEE1EB /* ALMeterCollectionViewController.m */; }; + CA1A08EB4544AF442551E42B /* ScanAreaEditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A3E8BCC8C9EA7355FD9306 /* ScanAreaEditorViewController.swift */; }; + CBAE26FD8584C84E9A97D868 /* ALSliderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2A78103E3F6503963BE57C /* ALSliderTableViewCell.swift */; }; + CC67FAA55F51DF471B2E95E4 /* sample_barcode_fullframe_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 8BD59742F478684E39DB300F /* sample_barcode_fullframe_config.json */; }; CCC5514E032352AA175A7E5A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = FE403053A2456208EE360328 /* LaunchScreen.xib */; }; - CE8264C3DD5BF63959DA3888 /* ALMultiformatBarcodeScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BBEFBE6F914B852ADD0A6208 /* ALMultiformatBarcodeScanViewController.m */; }; + CF1C8FA3AE4C955E406C048F /* BasicSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1597E47D75D1FBE3AA40BCF0 /* BasicSettingsViewController.swift */; }; + D1C525D095389570CE3D94A0 /* tire_config_tire_size.json in Resources */ = {isa = PBXBuildFile; fileRef = 6E66765DD1BC6A7F177D4D1B /* tire_config_tire_size.json */; }; D1ECDA522B38A0E201B91196 /* CustomerSelfReadingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8662031085DE12141D4411AF /* CustomerSelfReadingViewController.m */; }; D221E2CBB91120179EF6758D /* ALConfigurationDialogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F289962042BE8D33F12F6561 /* ALConfigurationDialogViewController.m */; }; - D30B74B0A2CFE68B8E57FE58 /* universal_id_flash_config.json in Resources */ = {isa = PBXBuildFile; fileRef = BB58D041BD1FA3AE07D151E4 /* universal_id_flash_config.json */; }; + D4A07FD4B1F394518AFF3CA6 /* ocr_config_vin.json in Resources */ = {isa = PBXBuildFile; fileRef = 46122D14ED5C57EA54D4FBB8 /* ocr_config_vin.json */; }; + D6B05EA56B02926FFDE63DD0 /* ALPluginResultHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E909C879E88B739A3D81BF22 /* ALPluginResultHelper.m */; }; D80E517E3BE07B4373E44F22 /* CustomerDataView.m in Sources */ = {isa = PBXBuildFile; fileRef = BFC15BAECD966B47C03DB1BF /* CustomerDataView.m */; }; DA33191870A1459EB23DCD4A /* Reading.m in Sources */ = {isa = PBXBuildFile; fileRef = DF3FF2562FFAF1D0AC162F63 /* Reading.m */; }; DBD0CB5D7B8AED3B3E083BE3 /* ALVoucherCodeScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 680F47A285E894B2DED8FA49 /* ALVoucherCodeScanViewController.m */; }; DD6D666DD6B9C7CF1CD894FD /* ALJSONDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D075BC2783D5FC21D973C78 /* ALJSONDownloader.m */; }; DDACD680801D8D6BED0F6F18 /* ALBasePageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DAA1365E502956D7038FAD1 /* ALBasePageViewController.m */; }; DED860F64AF49DD872DCAC2C /* isbn_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 084643E9DC61FCF5C414457E /* isbn_config.json */; }; - DF769EF1A4C7A11DE916D0B1 /* universal_id_config.json in Resources */ = {isa = PBXBuildFile; fileRef = BD32A60DAB173ECCAC90D9D4 /* universal_id_config.json */; }; DFFFD961846F72E077B90DC9 /* ALScriptSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB16BC10A7E2CE509ACBDC2 /* ALScriptSelectionViewController.m */; }; E2B5A3C0DD9F2F95F8DBD47A /* ALPrivacyForwardingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FEDC526109C03A6213FF8973 /* ALPrivacyForwardingViewController.m */; }; E4660E0BAEC49D4B4180D824 /* ScanHistoryMigration3to4.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 3D8772DC75560F15A05F6C69 /* ScanHistoryMigration3to4.xcmappingmodel */; }; + E4B8C00D1277B100526EB09F /* id_composite_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 552DD220AD71D440CEDFE0AB /* id_composite_config.json */; }; + E5461597FBA8D7ED0339F0DE /* universal_id_composite_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 5CCF370CDE77C6F2BB4A8B77 /* universal_id_composite_config.json */; }; E59639494B52B250C0143E0E /* ALSpaceViews.m in Sources */ = {isa = PBXBuildFile; fileRef = F3BA12F0082427C9B897F096 /* ALSpaceViews.m */; }; E7017766A5591720AE2CBCDA /* ALISBNViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D42728150F52CC8887535DC /* ALISBNViewController.m */; }; + E73EECCE7C6D35F8C70BBC8F /* SerialNumberSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C571574E122E009D003B3015 /* SerialNumberSettingsViewController.swift */; }; E81F0DED94A08AAB70CDBD5F /* ALMRZScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FC613FC690FD7C7C742CE2F /* ALMRZScanViewController.m */; }; - E9608A9789B2711CC5501AAF /* ALUniversalIDScanViewControllerFrontAndBack.m in Sources */ = {isa = PBXBuildFile; fileRef = A5AFADA28C4329DEC5E6100F /* ALUniversalIDScanViewControllerFrontAndBack.m */; }; E980239BD86AEAFB3F31054D /* WorkorderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 554E9384C128A108EB06BEEE /* WorkorderViewController.m */; }; + EAB86D1B9FA83DC872276C25 /* PepsiCo.any in Resources */ = {isa = PBXBuildFile; fileRef = 41D07B8132742DE010F6487C /* PepsiCo.any */; }; + EB9B3989CEA7F790F0459E43 /* id_front_config.json in Resources */ = {isa = PBXBuildFile; fileRef = FCD4D6A3F49D03247162F346 /* id_front_config.json */; }; EDFD83EF777DB60784943E89 /* NSTimer+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E2FCCDD73155DB06E083452 /* NSTimer+ALExamplesAdditions.m */; }; EFCF9293DCE54B0BB32ED198 /* rb_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 9E9D04C26C4E7E9D9FBEA655 /* rb_config.json */; }; F00A3D1FC8632FEA4AB60C44 /* Model.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = C279DBD77DEDB8A0AB2D80C9 /* Model.xcmappingmodel */; }; @@ -189,12 +221,14 @@ F41D6D9F6AD538727145B081 /* ALBlackWhiteSelectView.m in Sources */ = {isa = PBXBuildFile; fileRef = D4BA4A73673E308855423FF7 /* ALBlackWhiteSelectView.m */; }; F4A12D154F1AA631417B5910 /* ALEnergyMeterScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0018BF97083F73F2EAAFAC3B /* ALEnergyMeterScanViewController.m */; }; F4F2A31F71743A62504EF460 /* ALMeterScanResultViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ED0774AF77528E119EC1C3DA /* ALMeterScanResultViewController.m */; }; + F6EE2B9862A9B3AC5954000D /* meter_config.json in Resources */ = {isa = PBXBuildFile; fileRef = 61AAC616AFF035DA85B16F32 /* meter_config.json */; }; F7BFE2085451648DD83A41FB /* ALBundleInfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C12ECB31388816698425036A /* ALBundleInfoViewController.m */; }; - F941A07E7CE5C1FA5D76DC06 /* universal_id_cyrillic_config.json in Resources */ = {isa = PBXBuildFile; fileRef = A60A0607CA2A5832783E431E /* universal_id_cyrillic_config.json */; }; F9EC2303CE0D73D7FD969655 /* UISwitch+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = E9AB1474AA11E583864902DE /* UISwitch+ALExamplesAdditions.m */; }; FB59DBE530C4A7AE40738423 /* NSMutableAttributedString+ALExamplesAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 24923CA36F1AD9C467B08D23 /* NSMutableAttributedString+ALExamplesAdditions.m */; }; + FC5EA4D4F0E987CD614361AA /* ALBarcodeScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CFF8905F66F25ABB0D2C1E52 /* ALBarcodeScanViewController.m */; }; FDC12FEC02C4898E09BDA87B /* ALGridCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 915CDA4B2C757B7BA6510E8D /* ALGridCollectionViewCell.m */; }; FDF9C7606A984B1535B26B21 /* ALAnagramAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C20747B24FE141B33681784 /* ALAnagramAPI.m */; }; + FF05E84C997F8A8D6E0884D4 /* ALVRCScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF7AB21A03E152D672217DB /* ALVRCScanViewController.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -214,12 +248,16 @@ /* Begin PBXFileReference section */ 0018BF97083F73F2EAAFAC3B /* ALEnergyMeterScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALEnergyMeterScanViewController.m; sourceTree = ""; }; 005560AF7A0CBA5061149D9C /* ALScrabbleLabel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALScrabbleLabel.h; sourceTree = ""; }; + 01FFDFBDFBA612C608534753 /* ALMeterScanViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALMeterScanViewController.swift; sourceTree = ""; }; 02B5A4089D8B53653660E64B /* ALOthersExampleManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALOthersExampleManager.h; sourceTree = ""; }; + 0383C6755E8D9BC974CC11A8 /* driver_license_composite_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = driver_license_composite_config.json; sourceTree = ""; }; + 0500DAD07B3DEA2CD595D9B9 /* ALUniveralIDResultHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALUniveralIDResultHelper.m; sourceTree = ""; }; 055F5792009F2D77F67FCB9A /* Order+CoreDataProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Order+CoreDataProperties.h"; sourceTree = ""; }; 065082027942E2FDCA937017 /* ALPrivacyViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALPrivacyViewController.h; sourceTree = ""; }; 06B40EC29D2A0CFA6AC2651C /* ALAwardsView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALAwardsView.m; sourceTree = ""; }; 0773AADFFF89D2B32D9D4BEA /* MeterImagesAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = MeterImagesAssets.xcassets; sourceTree = ""; }; 084643E9DC61FCF5C414457E /* isbn_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = isbn_config.json; sourceTree = ""; }; + 0A5E58E4C86C0605BE083881 /* template_type_and_region_mapping_cyrillic.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = template_type_and_region_mapping_cyrillic.json; sourceTree = ""; }; 0ACCFE8F5694C900C7A15F44 /* ALScrabbleScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALScrabbleScanViewController.m; sourceTree = ""; }; 0B7A174D434351C30AA815B7 /* ReadingTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReadingTableViewCell.m; sourceTree = ""; }; 0D6F9EC2F4D67258FA29CA19 /* ALRecordNumberScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALRecordNumberScanViewController.h; sourceTree = ""; }; @@ -227,10 +265,15 @@ 0ECC3257448DCAB603DC774A /* UIView+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIView+ALExamplesAdditions.h"; sourceTree = ""; }; 0FDE2987C13D2F7C0E76AFD8 /* ALBarcodeResultUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBarcodeResultUtil.h; sourceTree = ""; }; 111253080C848FCF66FC8FE6 /* ALBundleInfoViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBundleInfoViewController.h; sourceTree = ""; }; + 11A8F717AE5215355CA0790F /* ALUniversalIDScanConfigController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALUniversalIDScanConfigController.m; sourceTree = ""; }; + 122ECADCFD6E28BF208F6186 /* vehicle_config_license_plate_us.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = vehicle_config_license_plate_us.json; sourceTree = ""; }; 128D3D12B6C087CF8CF11306 /* UIFont+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIFont+ALExamplesAdditions.h"; sourceTree = ""; }; + 12D7CF237BE3E4DB8F98A5C9 /* vehicle_config_license_plate_af.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = vehicle_config_license_plate_af.json; sourceTree = ""; }; 13881BADEC0C6D4F757DEC90 /* ALLicensePlateResultOverlayView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALLicensePlateResultOverlayView.m; sourceTree = ""; }; 13E9FE873FC5D8CA2D980753 /* UIViewController+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIViewController+ALExamplesAdditions.h"; sourceTree = ""; }; + 140C530F385C9A0ADC32A183 /* mrz_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = mrz_config.json; sourceTree = ""; }; 154CDA4F434DE3D5A626CD6F /* ALColor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALColor.h; sourceTree = ""; }; + 1597E47D75D1FBE3AA40BCF0 /* BasicSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicSettingsViewController.swift; sourceTree = ""; }; 16DB7A75A5F8AD5B606F58EE /* Order+CoreDataProperties.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Order+CoreDataProperties.m"; sourceTree = ""; }; 182DEF617BE080B414491B04 /* ALAutoAnalogDigitalMeterScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALAutoAnalogDigitalMeterScanViewController.m; sourceTree = ""; }; 186AC71508B2BFEF5BB5537E /* ALUniversalIDScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALUniversalIDScanViewController.m; sourceTree = ""; }; @@ -238,8 +281,6 @@ 1B40F5ACD2BF3B121A490FAE /* ALIdentityDocumentsExampleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALIdentityDocumentsExampleManager.m; sourceTree = ""; }; 1B7E4BDD67B0B2AA88763193 /* ALMeterExampleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALMeterExampleManager.m; sourceTree = ""; }; 1BAA2AE99970DC8FDF5C7C42 /* Order.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Order.m; sourceTree = ""; }; - 1BFD92ABE162E26D9D31394B /* ALMultiformatBarcodeScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALMultiformatBarcodeScanViewController.h; sourceTree = ""; }; - 1C16DC0D29C28EA8EF20D654 /* universal_id_camera_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = universal_id_camera_config.json; sourceTree = ""; }; 1CC34D7EAD1A849899340DD0 /* ALISBNHeaderCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALISBNHeaderCell.h; sourceTree = ""; }; 1D441F11D2B3236170AB0AE9 /* AnylineExamples 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AnylineExamples 2.xcdatamodel"; sourceTree = ""; }; 1D7E8D46EC14ED14B84F0FAE /* ALCheckbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALCheckbox.m; sourceTree = ""; }; @@ -249,25 +290,27 @@ 1F1E78B6137D667B2BAFF771 /* ALProductExampleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALProductExampleManager.m; sourceTree = ""; }; 200D1EBB7219D783E812650B /* NSTimer+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSTimer+ALExamplesAdditions.h"; sourceTree = ""; }; 2093FE4EF48CEEDBC2CE51D8 /* WorkforceToolResultViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WorkforceToolResultViewController.xib; sourceTree = ""; }; + 226D77AA78D7A7E610E82B3B /* ALLicensePlateScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALLicensePlateScanViewController.h; sourceTree = ""; }; 22E8CB56EA54CFB534DA589B /* AnylineExamples 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AnylineExamples 3.xcdatamodel"; sourceTree = ""; }; 23117B72847A07EB7D0A2AC0 /* NSString+Util.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+Util.m"; sourceTree = ""; }; 2408E133998590A79393C9F5 /* ALIdentityDocumentsExampleManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALIdentityDocumentsExampleManager.h; sourceTree = ""; }; 243B0BAAB8D99EDCD9DED87C /* ALGridCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALGridCollectionViewCell.h; sourceTree = ""; }; 24612698857CFE3971A3AE51 /* WorkforceTool.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WorkforceTool.m; sourceTree = ""; }; 24923CA36F1AD9C467B08D23 /* NSMutableAttributedString+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSMutableAttributedString+ALExamplesAdditions.m"; sourceTree = ""; }; + 2505BCAB8B12C613CE696B74 /* driver_license_front_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = driver_license_front_config.json; sourceTree = ""; }; 254FBCFC83BBCE0B37B8CD99 /* ReadingTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ReadingTableViewCell.xib; sourceTree = ""; }; 25A60D43D79D5825421AEE0C /* NSManagedObjectContext+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+ALExamplesAdditions.h"; sourceTree = ""; }; - 26ADB261A4028273D6D149D4 /* ALUniversalIDFieldnameUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALUniversalIDFieldnameUtil.h; sourceTree = ""; }; + 26A3E8BCC8C9EA7355FD9306 /* ScanAreaEditorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanAreaEditorViewController.swift; sourceTree = ""; }; 292FF76F299F378309092273 /* NSAttributedString+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+ALExamplesAdditions.h"; sourceTree = ""; }; 296AB81BA49A0F52F5E679E3 /* AnylineEnergyModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = AnylineEnergyModel.xcdatamodel; sourceTree = ""; }; 2AB85CDAF0E3CBE3888B5576 /* ALIntroHelpViewElectric.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALIntroHelpViewElectric.m; sourceTree = ""; }; 2AC802CBECE3BEC190BB90BC /* ALGridCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALGridCollectionViewController.m; sourceTree = ""; }; 2AE01852827507975736BFED /* Customer+CoreDataProperties.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Customer+CoreDataProperties.m"; sourceTree = ""; }; 2BCDB9656CE8EF8FF43E78C1 /* ALIDCountryHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALIDCountryHelper.m; sourceTree = ""; }; + 2BF7AB21A03E152D672217DB /* ALVRCScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALVRCScanViewController.m; sourceTree = ""; }; 2C4BB2860826353A412BB303 /* ALHeaderCollectionReusableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALHeaderCollectionReusableView.h; sourceTree = ""; }; 2DC7E98210F6761127C7F0CD /* energyMockData2.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = energyMockData2.json; sourceTree = ""; }; 2E35EBC0F2547C2A286FD841 /* NSUserDefaults+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSUserDefaults+ALExamplesAdditions.m"; sourceTree = ""; }; - 2E8F1BC85E70148A9D26AAE9 /* ALContainerScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALContainerScanViewController.m; sourceTree = ""; }; 2FC2BB5DD1BB6961AD1E9871 /* ALRBScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALRBScanViewController.h; sourceTree = ""; }; 30B76762D974C43BF0286E13 /* ALMainPageViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALMainPageViewController.m; sourceTree = ""; }; 3233635513FC2480136E99EB /* ReadingTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReadingTableViewCell.h; sourceTree = ""; }; @@ -275,11 +318,10 @@ 34F5CA65FF0C687D43AC37D3 /* WorkforceToolResultViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WorkforceToolResultViewController.m; sourceTree = ""; }; 3539C0A29CDC3ADF0C13AF08 /* Reading+CoreDataProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Reading+CoreDataProperties.h"; sourceTree = ""; }; 355AD17D434245A0D11FBA9E /* WorkorderViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WorkorderViewController.xib; sourceTree = ""; }; + 3602E347A7732F9343FB718B /* vehicle_config_license_plate_eu.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = vehicle_config_license_plate_eu.json; sourceTree = ""; }; 367F467BC78460348A00040D /* ALScrabblePoints.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALScrabblePoints.h; sourceTree = ""; }; 393827A2900685456384FB31 /* AnylineExamples-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AnylineExamples-Bridging-Header.h"; sourceTree = ""; }; - 395C010F945BB525FA78FA95 /* ALVehicleRegistrationCertificateViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALVehicleRegistrationCertificateViewController.h; sourceTree = ""; }; 3A3D5278F44BE2939E3CCA12 /* ALPrivacyViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALPrivacyViewController.m; sourceTree = ""; }; - 3A67ACF7B450115C3E36A9EA /* vertical_container_scanner_capture_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = vertical_container_scanner_capture_config.json; sourceTree = ""; }; 3AF73219598C155CF0603175 /* ALCustomToolbar.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALCustomToolbar.m; sourceTree = ""; }; 3B765E09017714AD35B457E0 /* UIButton+ALExamplesExtensions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIButton+ALExamplesExtensions.m"; sourceTree = ""; }; 3D8772DC75560F15A05F6C69 /* ScanHistoryMigration3to4.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = ScanHistoryMigration3to4.xcmappingmodel; sourceTree = ""; }; @@ -289,40 +331,46 @@ 4034A31CD2F393BE7D5E1EC4 /* ALUniversalIDScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALUniversalIDScanViewController.h; sourceTree = ""; }; 40D95BAB90478502C129F9F4 /* ALRecordNumberScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALRecordNumberScanViewController.m; sourceTree = ""; }; 4156A1644B315B70FE0B8419 /* ReadingTransformationPolicy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReadingTransformationPolicy.m; sourceTree = ""; }; + 41D07B8132742DE010F6487C /* PepsiCo.any */ = {isa = PBXFileReference; path = PepsiCo.any; sourceTree = ""; }; 41F0702B990CC38E25592A32 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 4206191D0D142A20C1D05C8F /* ALVerticalContainerScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALVerticalContainerScanViewController.m; sourceTree = ""; }; 42B4B012ACF1BCFB9BE76DED /* ALLicensePlateResultOverlayView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALLicensePlateResultOverlayView.h; sourceTree = ""; }; + 42E52B6E0AF185BDA0E6B79E /* ALRatioTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALRatioTableViewCell.swift; sourceTree = ""; }; 42F084242F64F44150C36582 /* ScanHistory+CoreDataClass.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ScanHistory+CoreDataClass.h"; sourceTree = ""; }; - 43BE0DB9AD5AA0BBB178E0D2 /* container_scanner_capture_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = container_scanner_capture_config.json; sourceTree = ""; }; + 439AB981070B2ADD388639C1 /* AnylineBottlecapScanViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnylineBottlecapScanViewController.swift; sourceTree = ""; }; 442C9FF1588611259A884BC4 /* CustomerDataViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomerDataViewController.xib; sourceTree = ""; }; 44F4A434C2E88DA003698E0B /* Customer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Customer.h; sourceTree = ""; }; + 46122D14ED5C57EA54D4FBB8 /* ocr_config_vin.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ocr_config_vin.json; sourceTree = ""; }; 464FAFFE2D244084E91CABC9 /* cow_tag_capture_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = cow_tag_capture_config.json; sourceTree = ""; }; 49A507ABFDFAE4C3298D842D /* ALBaseScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBaseScanViewController.m; sourceTree = ""; }; - 4AD2327535110C3026475005 /* ALUniversalIDFieldnameUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALUniversalIDFieldnameUtil.m; sourceTree = ""; }; 4B2EB9E82C48102735C47BF0 /* ALIdentificationView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALIdentificationView.m; sourceTree = ""; }; + 4B81AFCF2CBCB3331B584E5C /* template_type_and_region_mapping.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = template_type_and_region_mapping.json; sourceTree = ""; }; 4BDE8754C4C6459C4483851D /* ALVINScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALVINScanViewController.m; sourceTree = ""; }; + 4CD7ADAFE0B190C6F06E32E2 /* ALVRCScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALVRCScanViewController.h; sourceTree = ""; }; 502F956464F930CDC7019386 /* ALMRZScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALMRZScanViewController.h; sourceTree = ""; }; 52625CFC0155561D041823A8 /* ALUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALUtils.h; sourceTree = ""; }; 53BF35330525A5B4B80547BB /* ALBarcodeFormatHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBarcodeFormatHelper.m; sourceTree = ""; }; 5408415289B1FE9524543AA3 /* ALBaseGridCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBaseGridCollectionViewController.m; sourceTree = ""; }; 54C6C24B452735E53395244B /* NSAttributedString+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+ALExamplesAdditions.m"; sourceTree = ""; }; + 552DD220AD71D440CEDFE0AB /* id_composite_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = id_composite_config.json; sourceTree = ""; }; 554E9384C128A108EB06BEEE /* WorkorderViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WorkorderViewController.m; sourceTree = ""; }; 5705BFBBA0600773D0A9A837 /* ALResultEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALResultEntry.swift; sourceTree = ""; }; 57B53E62AD3B670B163C3777 /* record_number_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = record_number_config.json; sourceTree = ""; }; + 592159CC9AF1C1F8572EFFD8 /* ALBarcodeScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBarcodeScanViewController.h; sourceTree = ""; }; 5964989AD328FEB7B4A99F6D /* AnylineExamples.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = AnylineExamples.xcdatamodel; sourceTree = ""; }; 59F2143CC6945384EC804BA0 /* ALBaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBaseViewController.m; sourceTree = ""; }; 5A168F44A92FFCA7CAD631C9 /* ALTutorialViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALTutorialViewController.m; sourceTree = ""; }; 5ABFBDA9A84B279E7614CE2D /* UIToolbar+ExamplesExtensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIToolbar+ExamplesExtensions.h"; sourceTree = ""; }; - 5B87E9374F67894CA3A1F4FE /* universal_id_arabic_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = universal_id_arabic_config.json; sourceTree = ""; }; + 5CCF370CDE77C6F2BB4A8B77 /* universal_id_composite_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = universal_id_composite_config.json; sourceTree = ""; }; 5CE7DC7F34357ECB360C50C3 /* ALResultViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALResultViewController.swift; sourceTree = ""; }; 5D09863F2A78CC2C3B9EBE0E /* AnylineResources.bundle */ = {isa = PBXFileReference; lastKnownFileType = wrapper.cfbundle; path = AnylineResources.bundle; sourceTree = ""; }; 5D734F16D23B623323CB450A /* ALOthersExampleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALOthersExampleManager.m; sourceTree = ""; }; - 5D7732507A0D4EA588C3067F /* ALUSLicensePlateViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALUSLicensePlateViewController.h; sourceTree = ""; }; 5E2CEF352E355ABC1E7A6A81 /* ALDialogSelectionTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALDialogSelectionTableViewCell.m; sourceTree = ""; }; 5ECFD208BD47657AE983B207 /* ALScriptSelectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALScriptSelectionViewController.h; sourceTree = ""; }; + 5F6EBC6A23FB72F8EA3B013F /* tire_config_commercial_tire_id.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = tire_config_commercial_tire_id.json; sourceTree = ""; }; 602AF9DF62FC564C6646D2E5 /* ALToggleControl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALToggleControl.m; sourceTree = ""; }; 616461B6587A181665857FC9 /* AnylineEnergyModel 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AnylineEnergyModel 2.xcdatamodel"; sourceTree = ""; }; 61A5FEA61C1C1ACB0265F519 /* ScanHistoryMigration3to4.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScanHistoryMigration3to4.m; sourceTree = ""; }; + 61AAC616AFF035DA85B16F32 /* meter_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = meter_config.json; sourceTree = ""; }; 61AE6E061296A4581FB66B20 /* ALCattleTagScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALCattleTagScanViewController.m; sourceTree = ""; }; 61B15A0A73D0C8E7D041B7C9 /* ALScrabbleLabel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALScrabbleLabel.m; sourceTree = ""; }; 61CEE047492B9C3C53DD2D30 /* ALResultOverlayView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALResultOverlayView.m; sourceTree = ""; }; @@ -330,22 +378,22 @@ 61E28046271DB6906980A266 /* ALIntroHelpViewElectric.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALIntroHelpViewElectric.h; sourceTree = ""; }; 620DDA19128BF378985E3D28 /* UIColor+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIColor+ALExamplesAdditions.h"; sourceTree = ""; }; 62F0E5633DD1DEC9F8DC107D /* ALMeterSerialNumberScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALMeterSerialNumberScanViewController.h; sourceTree = ""; }; - 62FB49A32254DCD700160EB5 /* ALParallelMeterScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALParallelMeterScanViewController.h; sourceTree = ""; }; 63BB1A422354B6B767547049 /* Reading+CoreDataProperties.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Reading+CoreDataProperties.m"; sourceTree = ""; }; + 63C73C8FBA74603DFEBF79CA /* ALUniveralIDResultHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALUniveralIDResultHelper.h; sourceTree = ""; }; 63F14023856F87ABE98CD7BB /* UIToolbar+ExamplesExtensions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIToolbar+ExamplesExtensions.m"; sourceTree = ""; }; 64EDE98D6457AAEEED1DAEE4 /* ALEnergyMeterScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALEnergyMeterScanViewController.h; sourceTree = ""; }; - 65DAADF2E811C3B198393F6C /* ALVehicleRegistrationCertificateViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALVehicleRegistrationCertificateViewController.m; sourceTree = ""; }; + 65BAE9DE655BD12A9D60F3AC /* ALContainerScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALContainerScanViewController.m; sourceTree = ""; }; 65DCF7ACFE373E5E0AD7B3FA /* ALMeterScanResultViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALMeterScanResultViewController.h; sourceTree = ""; }; 678532EDC412A7D9CFA127A7 /* colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = colors.xcassets; sourceTree = ""; }; 678CE157440B405ADF327B28 /* ALColor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALColor.m; sourceTree = ""; }; 680F47A285E894B2DED8FA49 /* ALVoucherCodeScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALVoucherCodeScanViewController.m; sourceTree = ""; }; 69ACC6825C5974B0013C1DA8 /* ALISBNScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALISBNScanViewController.h; sourceTree = ""; }; 6A1B847ABBBCB75DE193888F /* UISwitch+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UISwitch+ALExamplesAdditions.h"; sourceTree = ""; }; - 6AEF1B386B2B10E25D61BAD7 /* ALAFLicensePlateViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALAFLicensePlateViewController.h; sourceTree = ""; }; 6D075BC2783D5FC21D973C78 /* ALJSONDownloader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALJSONDownloader.m; sourceTree = ""; }; 6DA99468936EB2988674CA18 /* CustomerSelfReadingConfirmationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomerSelfReadingConfirmationViewController.h; sourceTree = ""; }; 6DB0BC9CD4703D73176FC148 /* CustomerDataViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomerDataViewController.h; sourceTree = ""; }; 6DF6C8153DB85BEE9490FE62 /* ALVINScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALVINScanViewController.h; sourceTree = ""; }; + 6E66765DD1BC6A7F177D4D1B /* tire_config_tire_size.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = tire_config_tire_size.json; sourceTree = ""; }; 6E8E59D1138CECF3DF866E2B /* ALISBNAPI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALISBNAPI.m; sourceTree = ""; }; 6EC24F1676AB06FB79BEC213 /* ALBaseScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBaseScanViewController.h; sourceTree = ""; }; 6F7D7848B680799B4E40C5EE /* Reachability.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = ""; }; @@ -360,19 +408,22 @@ 745454B7CEEBC464BE126EE1 /* ISBNInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ISBNInfo.h; sourceTree = ""; }; 7474A92ECB1EC93FFE2A523F /* ALISBNHeaderCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALISBNHeaderCell.m; sourceTree = ""; }; 752F0DD94ED9F2120A3061F5 /* ALIBANScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALIBANScanViewController.h; sourceTree = ""; }; + 75EE32EDE551A66FEB4F027B /* universal_id_front_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = universal_id_front_config.json; sourceTree = ""; }; 771CC0DB53619FBFD1807769 /* NSManagedObject+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+ALExamplesAdditions.h"; sourceTree = ""; }; 78F03F897F8FDA41B978488D /* barcode_pdf417_in_id.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = barcode_pdf417_in_id.json; sourceTree = ""; }; 79974B0F2C88170B9C8C9E08 /* Anyline.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Anyline.xcframework; path = ../Framework/Anyline.xcframework; sourceTree = ""; }; 7A459BC0A1F181E2AF7D5C6D /* ALBaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBaseViewController.h; sourceTree = ""; }; - 7A74558707FFE3B297265433 /* meter_barcode_view_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = meter_barcode_view_config.json; sourceTree = ""; }; 7A8B3E959502E4A04A0D95FF /* UIView+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIView+ALExamplesAdditions.m"; sourceTree = ""; }; 7AFD7B0BB707496B3B440353 /* CustomerSelfReadingViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomerSelfReadingViewController.xib; sourceTree = ""; }; + 7B2A78103E3F6503963BE57C /* ALSliderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALSliderTableViewCell.swift; sourceTree = ""; }; 7B9E6F9BED62D417EA6BFF21 /* ALScrabbleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALScrabbleViewController.h; sourceTree = ""; }; + 7CBB31FD29F5241AD587F39A /* ALBarcodeTypes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBarcodeTypes.m; sourceTree = ""; }; 7D1C8024BC707860460ECFCE /* Customer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Customer.m; sourceTree = ""; }; 7D42728150F52CC8887535DC /* ALISBNViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALISBNViewController.m; sourceTree = ""; }; 7DD1CC4044B59146DF078A85 /* ALSelectionTable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALSelectionTable.h; sourceTree = ""; }; 7E65C2A8FE68C13A20583F31 /* ALIdentificationView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALIdentificationView.h; sourceTree = ""; }; 7EAC107D810BDA1E0DD6A546 /* ALEnergyBaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALEnergyBaseViewController.h; sourceTree = ""; }; + 7FB7DBE59B9BF6DE051F5B91 /* AdvancedSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsViewController.swift; sourceTree = ""; }; 821B9CF8C823115446349BF5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 82F96EB29788438DC60C51BF /* ALBarcodeFormatHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBarcodeFormatHelper.h; sourceTree = ""; }; 83ADB2D0DE56FFFBDBC03619 /* ALAnagramAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALAnagramAPI.h; sourceTree = ""; }; @@ -389,7 +440,9 @@ 88DAC270B239121767EBC0C9 /* Reading.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Reading.h; sourceTree = ""; }; 8997ECCC3F31FC24E06298FD /* NSArray+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSArray+ALExamplesAdditions.m"; sourceTree = ""; }; 8A569212ED42ECA2D294EA7A /* ALResultCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALResultCell.swift; sourceTree = ""; }; + 8BD59742F478684E39DB300F /* sample_barcode_fullframe_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = sample_barcode_fullframe_config.json; sourceTree = ""; }; 8C20747B24FE141B33681784 /* ALAnagramAPI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALAnagramAPI.m; sourceTree = ""; }; + 8CEEE043EF359766A6BCDBAA /* tire_config_tin.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = tire_config_tin.json; sourceTree = ""; }; 8E2FCCDD73155DB06E083452 /* NSTimer+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSTimer+ALExamplesAdditions.m"; sourceTree = ""; }; 8F54895F8F550A096FEF90C1 /* ALScrabbleWord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALScrabbleWord.m; sourceTree = ""; }; 8F9592E10BAADEF3FFCD6D52 /* ALTextViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTextViewCell.h; sourceTree = ""; }; @@ -398,9 +451,10 @@ 915CDA4B2C757B7BA6510E8D /* ALGridCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALGridCollectionViewCell.m; sourceTree = ""; }; 91E148202561E98484D64F0C /* ALScrabbleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALScrabbleViewController.m; sourceTree = ""; }; 92A698A60AD33BFD242A7B53 /* ALCustomToolbar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALCustomToolbar.h; sourceTree = ""; }; + 938DEE22539D3F061BDD3825 /* CutoutSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CutoutSettings.swift; sourceTree = ""; }; 9424406670994538E1F5D202 /* CoreDataManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreDataManager.h; sourceTree = ""; }; 9444087F811BB5FA23DCE9AB /* ISBNInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ISBNInfo.m; sourceTree = ""; }; - 95EC580E5D102787DB5DB9AD /* ALContainerScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALContainerScanViewController.h; sourceTree = ""; }; + 961E85891D0EB4CCC53350BC /* SerialNumberSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialNumberSettings.swift; sourceTree = ""; }; 96A3D3139D636DFCF875E8FA /* voucher_code_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = voucher_code_config.json; sourceTree = ""; }; 9780D7F513FBA5687A612B99 /* ALGridCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALGridCollectionViewController.h; sourceTree = ""; }; 987864E0F8E8E2F22C729406 /* CustomerSelfReading.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomerSelfReading.h; sourceTree = ""; }; @@ -417,7 +471,6 @@ 9E97F2F856C896EBAFEBFBBB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 9E9D04C26C4E7E9D9FBEA655 /* rb_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = rb_config.json; sourceTree = ""; }; 9EF4CE74F76B1AF1F3C25C5D /* CustomerSelfReading+CoreDataProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CustomerSelfReading+CoreDataProperties.h"; sourceTree = ""; }; - 9F00A41DD54298180480D664 /* ALAFLicensePlateViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALAFLicensePlateViewController.m; sourceTree = ""; }; 9F13764F90E1669ECB532F66 /* WorkforceToolResultViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WorkforceToolResultViewController.h; sourceTree = ""; }; A051CF5CEFA364EC2288953E /* ALScanResultViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALScanResultViewController.h; sourceTree = ""; }; A0D5067A874DE2D141541714 /* ALMROExampleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALMROExampleManager.m; sourceTree = ""; }; @@ -431,9 +484,7 @@ A5180ACF531CB4BCE715E077 /* ALIDCountryHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALIDCountryHelper.h; sourceTree = ""; }; A55CA11F512D1EB3147C6D35 /* Reachability.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = ""; }; A570607C0C1C45A39FFE134C /* NSManagedObjectContext+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+ALExamplesAdditions.m"; sourceTree = ""; }; - A5AFADA28C4329DEC5E6100F /* ALUniversalIDScanViewControllerFrontAndBack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALUniversalIDScanViewControllerFrontAndBack.m; sourceTree = ""; }; A5EBDB086634A2C26C320F12 /* ScanHistory+CoreDataClass.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "ScanHistory+CoreDataClass.m"; sourceTree = ""; }; - A60A0607CA2A5832783E431E /* universal_id_cyrillic_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = universal_id_cyrillic_config.json; sourceTree = ""; }; A680DA979CBA5B2D057A62BA /* WorkforceTool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WorkforceTool.h; sourceTree = ""; }; A69B1A2F844B7CED945DC4AF /* CustomerSelfReadingResultViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomerSelfReadingResultViewController.xib; sourceTree = ""; }; A701089685066A8503F97EB2 /* ALToggleControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALToggleControl.h; sourceTree = ""; }; @@ -441,13 +492,16 @@ A79B7275D336824CB329A214 /* AnylineEnergyModel 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AnylineEnergyModel 4.xcdatamodel"; sourceTree = ""; }; A7D5F404BA40404FC2843ED9 /* ALUmbrella.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALUmbrella.h; sourceTree = ""; }; A8CB4729C4A9C0FEBF226E57 /* ALScanResultViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALScanResultViewController.m; sourceTree = ""; }; + AA690CB35CB9AE5A1C41EF3E /* vertical_container_scanner_capture_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = vertical_container_scanner_capture_config.json; sourceTree = ""; }; AAC2E6C8E9E1996B60427EA3 /* CustomerSelfReadingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomerSelfReadingViewController.h; sourceTree = ""; }; ACF1D09EF06128D92632D6CB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; AE87444EC65713470FCAA981 /* ReadingDetailsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReadingDetailsViewController.h; sourceTree = ""; }; B1866752D7457CFD00F2BB10 /* NSManagedObject+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+ALExamplesAdditions.m"; sourceTree = ""; }; B1D774A5ADDF5C4E7628C04F /* ALLicensePlateExampleManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALLicensePlateExampleManager.h; sourceTree = ""; }; B2609040C0044ED642B23323 /* ALMeterSerialNumberScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALMeterSerialNumberScanViewController.m; sourceTree = ""; }; + B267CBC94F9A37441E5297C6 /* ALPluginResultHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALPluginResultHelper.h; sourceTree = ""; }; B47BD6FE89D95F7402CF807D /* ALParallelMeterWithJSONScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALParallelMeterWithJSONScanViewController.h; sourceTree = ""; }; + B77C4FF2B3BC5111904B600C /* bottlecap_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = bottlecap_config.json; sourceTree = ""; }; B796B03399AA17084BF87FE2 /* ALIntroHelpView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALIntroHelpView.h; sourceTree = ""; }; B7B4776BB82FA4F7729784D0 /* ALExample.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALExample.m; sourceTree = ""; }; B7F93940133379A464B2ECA1 /* ALExampleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALExampleManager.m; sourceTree = ""; }; @@ -455,46 +509,51 @@ BA89E85175CED5995CE165C6 /* ALExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALExample.h; sourceTree = ""; }; BAA0A933607B261163D39272 /* ALDialMeterScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALDialMeterScanViewController.h; sourceTree = ""; }; BB04F45409076E98165CCE2D /* CustomerSelfReadingConfirmationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomerSelfReadingConfirmationViewController.m; sourceTree = ""; }; - BB58D041BD1FA3AE07D151E4 /* universal_id_flash_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = universal_id_flash_config.json; sourceTree = ""; }; BBA41B615F51A7CDFA149051 /* ALAwardsView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALAwardsView.h; sourceTree = ""; }; BBDBF5E431741F6576F3DA9F /* ALProductExampleManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALProductExampleManager.h; sourceTree = ""; }; + BBE040B07CF4EF032821E053 /* template_type_and_region_mapping_arabic.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = template_type_and_region_mapping_arabic.json; sourceTree = ""; }; BBEF6BE85BA00F9E1011D1E1 /* ALUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALUtils.m; sourceTree = ""; }; - BBEFBE6F914B852ADD0A6208 /* ALMultiformatBarcodeScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALMultiformatBarcodeScanViewController.m; sourceTree = ""; }; BC01755C0A3AD293F0ABB7F1 /* ALCustomBarButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALCustomBarButton.h; sourceTree = ""; }; BCFD7D8491897962E508C552 /* CustomerSelfReadingResultViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomerSelfReadingResultViewController.m; sourceTree = ""; }; - BD32A60DAB173ECCAC90D9D4 /* universal_id_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = universal_id_config.json; sourceTree = ""; }; - BF3E107E3628045E2154C532 /* ALUSLicensePlateViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALUSLicensePlateViewController.m; sourceTree = ""; }; BF88446A84FC3EC6F15B2B1E /* ALDocumentScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALDocumentScanViewController.h; sourceTree = ""; }; BF9D4EDF7F1ACEEF688A8784 /* WorkForceViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WorkForceViewController.xib; sourceTree = ""; }; BFA2D24537BE819B9E82E04D /* WorkorderViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WorkorderViewController.h; sourceTree = ""; }; BFADAFA9683F3BC78869E42C /* UIButton+ALExamplesExtensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIButton+ALExamplesExtensions.h"; sourceTree = ""; }; BFC15BAECD966B47C03DB1BF /* CustomerDataView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomerDataView.m; sourceTree = ""; }; + C08544CE3BE7CEFE3FCCA267 /* vehicle_registration_cert_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = vehicle_registration_cert_config.json; sourceTree = ""; }; C0978B57E2E7E3A98728F35F /* ALSpaceViews.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALSpaceViews.h; sourceTree = ""; }; C12ECB31388816698425036A /* ALBundleInfoViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBundleInfoViewController.m; sourceTree = ""; }; + C1ABE28D1A049D4A9EBA90E1 /* ALUniversalIDScanConfigController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALUniversalIDScanConfigController.h; sourceTree = ""; }; C1E6D1D70BE3806996A6A46C /* ALDialogSelectionTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALDialogSelectionTableViewCell.h; sourceTree = ""; }; C26DCA1CBAC60A9A22BE6DDC /* ALBaseGridCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBaseGridCollectionViewController.h; sourceTree = ""; }; C279DBD77DEDB8A0AB2D80C9 /* Model.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = Model.xcmappingmodel; sourceTree = ""; }; C2DE5E7E740DE6CE65330E56 /* ALISBNScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALISBNScanViewController.m; sourceTree = ""; }; - C35708656BE5895E6037B2A8 /* ALVerticalContainerScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALVerticalContainerScanViewController.h; sourceTree = ""; }; C401B4BF009D1D8E2BED8173 /* CustomerSelfReading.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomerSelfReading.m; sourceTree = ""; }; C474F22983E364473A5F91A8 /* WorkforceTool+CoreDataProperties.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "WorkforceTool+CoreDataProperties.m"; sourceTree = ""; }; C4E617625C1AA097008BADE0 /* ALLicensePlateExampleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALLicensePlateExampleManager.m; sourceTree = ""; }; + C571574E122E009D003B3015 /* SerialNumberSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialNumberSettingsViewController.swift; sourceTree = ""; }; + C5F2509735729617E12FA0F8 /* mrz_nfc_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = mrz_nfc_config.json; sourceTree = ""; }; C6710658F42970400FD78BD0 /* iban_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = iban_config.json; sourceTree = ""; }; C693A94797CE4C0904AAA627 /* NSArray+ALExamplesAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSArray+ALExamplesAdditions.h"; sourceTree = ""; }; C7B781000A27A5EBD168F708 /* ALTINScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTINScanViewController.h; sourceTree = ""; }; CA1844EA54C7D8B97D895C05 /* ReadingTransformationPolicy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReadingTransformationPolicy.h; sourceTree = ""; }; + CAEDF1910585C87FCEEDA12A /* ALTextInputTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALTextInputTableViewCell.swift; sourceTree = ""; }; CB56AC0CF88F101A75FF5F3E /* vin_capture_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = vin_capture_config.json; sourceTree = ""; }; CC75DF6BB98F730B445F418A /* WorkForceViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WorkForceViewController.h; sourceTree = ""; }; CCFB0172F33527DC467752AE /* ALConfigurationDialogViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALConfigurationDialogViewController.h; sourceTree = ""; }; CD45FF61F08237CA8F7D06B2 /* ALCheckbox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALCheckbox.h; sourceTree = ""; }; CDB06AE3FB930F1B0781316C /* TireViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TireViewController.swift; sourceTree = ""; }; CE844E43F308E9D0C6E8736D /* ALPDF417ScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALPDF417ScanViewController.m; sourceTree = ""; }; + CFF8905F66F25ABB0D2C1E52 /* ALBarcodeScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBarcodeScanViewController.m; sourceTree = ""; }; + D090ED0AC92FBE04D8640A06 /* ALBottlecapScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBottlecapScanViewController.h; sourceTree = ""; }; D0A26198973324CFA59191B6 /* ALUniversalSerialNumberScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALUniversalSerialNumberScanViewController.m; sourceTree = ""; }; D11E06DF396B1B2615A7D5C2 /* CoreDataManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreDataManager.m; sourceTree = ""; }; + D158CCA376D3897CDD7B0313 /* serial_meter_barcode_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = serial_meter_barcode_config.json; sourceTree = ""; }; D3731B30F8DD7C95B525B422 /* CustomerSelfReadingResultViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomerSelfReadingResultViewController.h; sourceTree = ""; }; - D4413505AA97F9234BD1A420 /* GifuWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifuWrapper.swift; sourceTree = ""; }; + D3B3AB626A67D05468E6576C /* ALUnselectableLinkableTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALUnselectableLinkableTextView.swift; sourceTree = ""; }; D4BA4A73673E308855423FF7 /* ALBlackWhiteSelectView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBlackWhiteSelectView.m; sourceTree = ""; }; D4BB9182561EC02717CD1ADF /* ALTextViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALTextViewCell.m; sourceTree = ""; }; + D4E1293D86A9F5436B4C64AD /* ALLicensePlateScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALLicensePlateScanViewController.m; sourceTree = ""; }; D7E79AE8BC99BE84D0DF663C /* NSString+Util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+Util.h"; sourceTree = ""; }; D99C3AF7A5F231E20545B326 /* ALBarcodeResultUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBarcodeResultUtil.m; sourceTree = ""; }; D9DE990FB41CB3666F5E3B58 /* FormFieldView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldView.swift; sourceTree = ""; }; @@ -504,17 +563,22 @@ DC8BBF33123C5DED64F598FF /* ALEnergyBaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALEnergyBaseViewController.m; sourceTree = ""; }; DCA6D34271AD62305E175DE9 /* ALParallelMeterScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALParallelMeterScanViewController.m; sourceTree = ""; }; DCB16BC10A7E2CE509ACBDC2 /* ALScriptSelectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALScriptSelectionViewController.m; sourceTree = ""; }; + DCFFEEDAD51ED4572C937402 /* parallel_meter_barcode_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = parallel_meter_barcode_config.json; sourceTree = ""; }; + DE2078D35FF9AFB200722103 /* pepsi_code_scanner.ale */ = {isa = PBXFileReference; path = pepsi_code_scanner.ale; sourceTree = ""; }; + DE41F0028C4089E060E40194 /* ALBarcodeTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBarcodeTypes.h; sourceTree = ""; }; DF3FF2562FFAF1D0AC162F63 /* Reading.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Reading.m; sourceTree = ""; }; DF764271604E0EB992306FBB /* CustomerSelfReading+CoreDataProperties.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CustomerSelfReading+CoreDataProperties.m"; sourceTree = ""; }; E01BF8D357703EF4FA7E4F3F /* ALMeterReading.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALMeterReading.m; sourceTree = ""; }; E03FEACAF88B29254C2111D6 /* ALISBNViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALISBNViewController.h; sourceTree = ""; }; + E22BC03628E43B403E040936 /* ALContainerScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALContainerScanViewController.h; sourceTree = ""; }; E2BF3BCCA12C3AC67230D6FD /* ALScrabbleWord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALScrabbleWord.h; sourceTree = ""; }; - E2D4B221C41469C27B5628E7 /* ALUniversalIDScanViewControllerFrontAndBack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALUniversalIDScanViewControllerFrontAndBack.h; sourceTree = ""; }; + E3F1A5ADF3152DDB67BBB2EC /* sample_barcode_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = sample_barcode_config.json; sourceTree = ""; }; + E4CAC353654020B0D2C04771 /* horizontal_container_scanner_capture_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = horizontal_container_scanner_capture_config.json; sourceTree = ""; }; E539A0891F231A43F3A7089A /* CustomerSelfReadingConfirmationViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomerSelfReadingConfirmationViewController.xib; sourceTree = ""; }; E59DF7BD4220A8FE5450AAA9 /* CustomerDataView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomerDataView.xib; sourceTree = ""; }; E64C4332E9A496E8F018505C /* ALMeterSelectView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALMeterSelectView.h; sourceTree = ""; }; - E771391FA2E8364BDC5E168F /* ALLicensePlateViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALLicensePlateViewController.h; sourceTree = ""; }; E84E52042DF87A432B7C4A09 /* ALIntroHelpView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALIntroHelpView.m; sourceTree = ""; }; + E909C879E88B739A3D81BF22 /* ALPluginResultHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALPluginResultHelper.m; sourceTree = ""; }; E9AB1474AA11E583864902DE /* UISwitch+ALExamplesAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UISwitch+ALExamplesAdditions.m"; sourceTree = ""; }; E9ECA85494F681157BC59F5B /* ALDeviceInformationHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALDeviceInformationHelper.h; sourceTree = ""; }; EB78932388C374EF93341EE8 /* ALMeter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALMeter.m; sourceTree = ""; }; @@ -526,10 +590,12 @@ EE56A15754A593AB5CE2C523 /* ALJSONDownloader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALJSONDownloader.h; sourceTree = ""; }; EEB003E6E30CAC9DB3C20C66 /* ALMeterReadingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALMeterReadingView.h; sourceTree = ""; }; EECA5BF9DE5003F3B36EC15C /* ALRoundedView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALRoundedView.h; sourceTree = ""; }; - EFF08A08B5EE72241A016DF0 /* ALLicensePlateViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALLicensePlateViewController.m; sourceTree = ""; }; + F152B3906D4618C66634019C /* ALLeftCheckmarkCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALLeftCheckmarkCell.swift; sourceTree = ""; }; F289962042BE8D33F12F6561 /* ALConfigurationDialogViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALConfigurationDialogViewController.m; sourceTree = ""; }; + F36A14C14B24C4B5D0C59E1E /* ALBottlecapScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALBottlecapScanViewController.m; sourceTree = ""; }; F3BA12F0082427C9B897F096 /* ALSpaceViews.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALSpaceViews.m; sourceTree = ""; }; F489CC9CA221D896272E881A /* ALISBNAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALISBNAPI.h; sourceTree = ""; }; + F51CE329A413946D4A19C6D8 /* BaseSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSettingsViewController.swift; sourceTree = ""; }; F5F3F4D726FC915731B73AE3 /* ALDocumentScanViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALDocumentScanViewController.m; sourceTree = ""; }; F7151F89C55A657556691214 /* ScanHistory+CoreDataProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ScanHistory+CoreDataProperties.h"; sourceTree = ""; }; F72E21F38E68BE8268DA8B75 /* ALVoucherCodeScanViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALVoucherCodeScanViewController.h; sourceTree = ""; }; @@ -537,6 +603,7 @@ F84B123B1654CB102F551D25 /* meter_barcode_parallel.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = meter_barcode_parallel.json; sourceTree = ""; }; F8F473BAEC7288A2E304C228 /* ScanHistoryMigration3to4.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScanHistoryMigration3to4.h; sourceTree = ""; }; F92107DB6698B83180CD5864 /* CustomerDataViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomerDataViewController.m; sourceTree = ""; }; + FCD4D6A3F49D03247162F346 /* id_front_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = id_front_config.json; sourceTree = ""; }; FDCEFD699881115D834BAA3A /* ALDeviceInformationHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALDeviceInformationHelper.m; sourceTree = ""; }; FE8E97DFB75BB606736A5B8F /* ALBasePageViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALBasePageViewController.h; sourceTree = ""; }; FEDC526109C03A6213FF8973 /* ALPrivacyForwardingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALPrivacyForwardingViewController.m; sourceTree = ""; }; @@ -557,32 +624,72 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0A182AFC6A2917DADF101F5E /* Products */ = { + 00D2BFCA589E54655658493B /* ViewController */ = { isa = PBXGroup; children = ( - A1D9E32583A9312C676B518E /* AnylineExamples.app */, + D090ED0AC92FBE04D8640A06 /* ALBottlecapScanViewController.h */, + F36A14C14B24C4B5D0C59E1E /* ALBottlecapScanViewController.m */, + 439AB981070B2ADD388639C1 /* AnylineBottlecapScanViewController.swift */, ); - name = Products; + path = ViewController; + sourceTree = ""; + }; + 043EEDE8F87BFEDF473939CC /* Templates */ = { + isa = PBXGroup; + children = ( + BBE040B07CF4EF032821E053 /* template_type_and_region_mapping_arabic.json */, + 0A5E58E4C86C0605BE083881 /* template_type_and_region_mapping_cyrillic.json */, + 4B81AFCF2CBCB3331B584E5C /* template_type_and_region_mapping.json */, + ); + path = Templates; sourceTree = ""; }; - 0D9835CFDE0CC62A1A02D0DF /* ContainerScannerVertical */ = { + 04A2EA21905FE1A49540BE22 /* Settings */ = { isa = PBXGroup; children = ( - 3A67ACF7B450115C3E36A9EA /* vertical_container_scanner_capture_config.json */, - 400C77DA9D2A9E34CDA1C08C /* ViewController */, + 7FB7DBE59B9BF6DE051F5B91 /* AdvancedSettingsViewController.swift */, + F152B3906D4618C66634019C /* ALLeftCheckmarkCell.swift */, + 42E52B6E0AF185BDA0E6B79E /* ALRatioTableViewCell.swift */, + 7B2A78103E3F6503963BE57C /* ALSliderTableViewCell.swift */, + CAEDF1910585C87FCEEDA12A /* ALTextInputTableViewCell.swift */, + D3B3AB626A67D05468E6576C /* ALUnselectableLinkableTextView.swift */, + F51CE329A413946D4A19C6D8 /* BaseSettingsViewController.swift */, + 1597E47D75D1FBE3AA40BCF0 /* BasicSettingsViewController.swift */, + 938DEE22539D3F061BDD3825 /* CutoutSettings.swift */, + 26A3E8BCC8C9EA7355FD9306 /* ScanAreaEditorViewController.swift */, + 961E85891D0EB4CCC53350BC /* SerialNumberSettings.swift */, + C571574E122E009D003B3015 /* SerialNumberSettingsViewController.swift */, ); - path = ContainerScannerVertical; + path = Settings; + sourceTree = ""; + }; + 0A182AFC6A2917DADF101F5E /* Products */ = { + isa = PBXGroup; + children = ( + A1D9E32583A9312C676B518E /* AnylineExamples.app */, + ); + name = Products; sourceTree = ""; }; 130C58F489D374A154DB76C2 /* Barcode */ = { isa = PBXGroup; children = ( 78F03F897F8FDA41B978488D /* barcode_pdf417_in_id.json */, + E3F1A5ADF3152DDB67BBB2EC /* sample_barcode_config.json */, + 8BD59742F478684E39DB300F /* sample_barcode_fullframe_config.json */, 3F8D864CC1FBB735930B1943 /* ViewController */, ); path = Barcode; sourceTree = ""; }; + 16156F8619DADC87FC5825D5 /* Configs */ = { + isa = PBXGroup; + children = ( + D158CCA376D3897CDD7B0313 /* serial_meter_barcode_config.json */, + ); + path = Configs; + sourceTree = ""; + }; 16C90035C38013048BAC4561 /* ViewController */ = { isa = PBXGroup; children = ( @@ -621,6 +728,10 @@ 1B58DB2EF5A2CF9F6238A963 /* Extensions */ = { isa = PBXGroup; children = ( + B267CBC94F9A37441E5297C6 /* ALPluginResultHelper.h */, + E909C879E88B739A3D81BF22 /* ALPluginResultHelper.m */, + 63C73C8FBA74603DFEBF79CA /* ALUniveralIDResultHelper.h */, + 0500DAD07B3DEA2CD595D9B9 /* ALUniveralIDResultHelper.m */, C693A94797CE4C0904AAA627 /* NSArray+ALExamplesAdditions.h */, 8997ECCC3F31FC24E06298FD /* NSArray+ALExamplesAdditions.m */, 771CC0DB53619FBFD1807769 /* NSManagedObject+ALExamplesAdditions.h */, @@ -647,6 +758,16 @@ path = Extensions; sourceTree = ""; }; + 21E6F3B0F1143DC05AB3CF07 /* ContainerScanner */ = { + isa = PBXGroup; + children = ( + E4CAC353654020B0D2C04771 /* horizontal_container_scanner_capture_config.json */, + AA690CB35CB9AE5A1C41EF3E /* vertical_container_scanner_capture_config.json */, + BFA9771B2518D26DA35BD28A /* ViewController */, + ); + path = ContainerScanner; + sourceTree = ""; + }; 2515C046DBF27ED7ED40F713 /* GridViews */ = { isa = PBXGroup; children = ( @@ -665,12 +786,8 @@ 25B865680DAF95A866C48832 /* ViewController */ = { isa = PBXGroup; children = ( - 6AEF1B386B2B10E25D61BAD7 /* ALAFLicensePlateViewController.h */, - 9F00A41DD54298180480D664 /* ALAFLicensePlateViewController.m */, - E771391FA2E8364BDC5E168F /* ALLicensePlateViewController.h */, - EFF08A08B5EE72241A016DF0 /* ALLicensePlateViewController.m */, - 5D7732507A0D4EA588C3067F /* ALUSLicensePlateViewController.h */, - BF3E107E3628045E2154C532 /* ALUSLicensePlateViewController.m */, + 226D77AA78D7A7E610E82B3B /* ALLicensePlateScanViewController.h */, + D4E1293D86A9F5436B4C64AD /* ALLicensePlateScanViewController.m */, ); path = ViewController; sourceTree = ""; @@ -724,8 +841,9 @@ 2F6F5EE96EB464D7C09E4BAC /* Vehicle Registration Certificate */ = { isa = PBXGroup; children = ( - 395C010F945BB525FA78FA95 /* ALVehicleRegistrationCertificateViewController.h */, - 65DAADF2E811C3B198393F6C /* ALVehicleRegistrationCertificateViewController.m */, + 4CD7ADAFE0B190C6F06E32E2 /* ALVRCScanViewController.h */, + 2BF7AB21A03E152D672217DB /* ALVRCScanViewController.m */, + C08544CE3BE7CEFE3FCCA267 /* vehicle_registration_cert_config.json */, ECBB4E54E07A19394D2AD07B /* vehicle_registration_certificate_config.json */, ); path = "Vehicle Registration Certificate"; @@ -765,23 +883,16 @@ children = ( 82F96EB29788438DC60C51BF /* ALBarcodeFormatHelper.h */, 53BF35330525A5B4B80547BB /* ALBarcodeFormatHelper.m */, - 1BFD92ABE162E26D9D31394B /* ALMultiformatBarcodeScanViewController.h */, - BBEFBE6F914B852ADD0A6208 /* ALMultiformatBarcodeScanViewController.m */, + 592159CC9AF1C1F8572EFFD8 /* ALBarcodeScanViewController.h */, + CFF8905F66F25ABB0D2C1E52 /* ALBarcodeScanViewController.m */, + DE41F0028C4089E060E40194 /* ALBarcodeTypes.h */, + 7CBB31FD29F5241AD587F39A /* ALBarcodeTypes.m */, 7DD1CC4044B59146DF078A85 /* ALSelectionTable.h */, 1EFBCB2ECDA30B85C2A54B48 /* ALSelectionTable.m */, ); path = ViewController; sourceTree = ""; }; - 400C77DA9D2A9E34CDA1C08C /* ViewController */ = { - isa = PBXGroup; - children = ( - C35708656BE5895E6037B2A8 /* ALVerticalContainerScanViewController.h */, - 4206191D0D142A20C1D05C8F /* ALVerticalContainerScanViewController.m */, - ); - path = ViewController; - sourceTree = ""; - }; 4044E435FFB85598EBF9E136 /* Extensions */ = { isa = PBXGroup; children = ( @@ -829,10 +940,10 @@ 393827A2900685456384FB31 /* AnylineExamples-Bridging-Header.h */, 0773AADFFF89D2B32D9D4BEA /* MeterImagesAssets.xcassets */, 130C58F489D374A154DB76C2 /* Barcode */, + 4760F3B0C794C579303E5E82 /* Bottlecap */, 920FC7041BC75E7BC7B66293 /* CattleTag */, FE110D9D8770D6DC4767AC0C /* CompositeScanning */, - FDBF785D090EB8336A7FD16D /* ContainerScannerHorizontal */, - 0D9835CFDE0CC62A1A02D0DF /* ContainerScannerVertical */, + 21E6F3B0F1143DC05AB3CF07 /* ContainerScanner */, 5829676095E89FA2B57CAD0E /* CoreData */, FCCCCEB66ACAC7F418ABEBA7 /* Document */, B4E54664451AC52545CC0966 /* IBAN */, @@ -858,6 +969,17 @@ path = "Anyline Examples Source"; sourceTree = ""; }; + 4760F3B0C794C579303E5E82 /* Bottlecap */ = { + isa = PBXGroup; + children = ( + B77C4FF2B3BC5111904B600C /* bottlecap_config.json */, + DE2078D35FF9AFB200722103 /* pepsi_code_scanner.ale */, + E5A6E21F3A8CEBA5D9A433BE /* trained_models */, + 00D2BFCA589E54655658493B /* ViewController */, + ); + path = Bottlecap; + sourceTree = ""; + }; 50494BD46BC6ABEF8504466F /* CustomerSelfReading */ = { isa = PBXGroup; children = ( @@ -919,6 +1041,7 @@ 24612698857CFE3971A3AE51 /* WorkforceTool.m */, 7212AEEBA9351E028AFC229F /* WorkforceTool+CoreDataProperties.h */, C474F22983E364473A5F91A8 /* WorkforceTool+CoreDataProperties.m */, + 16156F8619DADC87FC5825D5 /* Configs */, 50494BD46BC6ABEF8504466F /* CustomerSelfReading */, D060D46C2B51104DE5091B0A /* ScanViewController */, D3C9911ACD47A693F72D9EAC /* Workforce */, @@ -929,6 +1052,7 @@ 56F4DAC0C2ADD79A3A5A1B1C /* MRZ */ = { isa = PBXGroup; children = ( + 140C530F385C9A0ADC32A183 /* mrz_config.json */, F6A12E72845BDF2D34EBEB80 /* ViewController */, F47AA2DCBA7DE8B2174BBC76 /* Views */, ); @@ -966,6 +1090,7 @@ isa = PBXGroup; children = ( 9A5A0B8B16A226B0EAC39924 /* serial_number_view_config.json */, + 04A2EA21905FE1A49540BE22 /* Settings */, 16C90035C38013048BAC4561 /* ViewController */, ); path = SerialNumber; @@ -1005,11 +1130,8 @@ 761C0429062CC48DC697E44E /* UniversalID */ = { isa = PBXGroup; children = ( - 5B87E9374F67894CA3A1F4FE /* universal_id_arabic_config.json */, - 1C16DC0D29C28EA8EF20D654 /* universal_id_camera_config.json */, - BD32A60DAB173ECCAC90D9D4 /* universal_id_config.json */, - A60A0607CA2A5832783E431E /* universal_id_cyrillic_config.json */, - BB58D041BD1FA3AE07D151E4 /* universal_id_flash_config.json */, + B496880B9AC4D047E030ABE7 /* Configs */, + 043EEDE8F87BFEDF473939CC /* Templates */, 7827C4BE8CF0D9B0246BF7C8 /* ViewController */, ); path = UniversalID; @@ -1018,13 +1140,10 @@ 7827C4BE8CF0D9B0246BF7C8 /* ViewController */ = { isa = PBXGroup; children = ( - 26ADB261A4028273D6D149D4 /* ALUniversalIDFieldnameUtil.h */, - 4AD2327535110C3026475005 /* ALUniversalIDFieldnameUtil.m */, + C1ABE28D1A049D4A9EBA90E1 /* ALUniversalIDScanConfigController.h */, + 11A8F717AE5215355CA0790F /* ALUniversalIDScanConfigController.m */, 4034A31CD2F393BE7D5E1EC4 /* ALUniversalIDScanViewController.h */, 186AC71508B2BFEF5BB5537E /* ALUniversalIDScanViewController.m */, - E2D4B221C41469C27B5628E7 /* ALUniversalIDScanViewControllerFrontAndBack.h */, - A5AFADA28C4329DEC5E6100F /* ALUniversalIDScanViewControllerFrontAndBack.m */, - D4413505AA97F9234BD1A420 /* GifuWrapper.swift */, ); path = ViewController; sourceTree = ""; @@ -1100,6 +1219,7 @@ children = ( 8503EA812C39D3BDEEC5B46C /* ALNFCScanViewController.h */, 0D76DB0B1EDA3DEE5553F4D2 /* ALNFCScanViewController.m */, + C5F2509735729617E12FA0F8 /* mrz_nfc_config.json */, ); path = ViewController; sourceTree = ""; @@ -1172,14 +1292,15 @@ A424D0F5DC83E2BFF249BA05 /* ALDialMeterScanViewController.m */, 65DCF7ACFE373E5E0AD7B3FA /* ALMeterScanResultViewController.h */, ED0774AF77528E119EC1C3DA /* ALMeterScanResultViewController.m */, + 01FFDFBDFBA612C608534753 /* ALMeterScanViewController.swift */, E64C4332E9A496E8F018505C /* ALMeterSelectView.h */, DBCCB00C4D68018A8D821988 /* ALMeterSelectView.m */, 62F0E5633DD1DEC9F8DC107D /* ALMeterSerialNumberScanViewController.h */, B2609040C0044ED642B23323 /* ALMeterSerialNumberScanViewController.m */, - 62FB49A32254DCD700160EB5 /* ALParallelMeterScanViewController.h */, DCA6D34271AD62305E175DE9 /* ALParallelMeterScanViewController.m */, FFB4E02BFD8726AC4537520C /* ElectricMeterBlackWhiteScanViewController.swift */, - 7A74558707FFE3B297265433 /* meter_barcode_view_config.json */, + 61AAC616AFF035DA85B16F32 /* meter_config.json */, + DCFFEEDAD51ED4572C937402 /* parallel_meter_barcode_config.json */, ); path = ViewController; sourceTree = ""; @@ -1202,6 +1323,19 @@ path = Views; sourceTree = ""; }; + B496880B9AC4D047E030ABE7 /* Configs */ = { + isa = PBXGroup; + children = ( + 0383C6755E8D9BC974CC11A8 /* driver_license_composite_config.json */, + 2505BCAB8B12C613CE696B74 /* driver_license_front_config.json */, + 552DD220AD71D440CEDFE0AB /* id_composite_config.json */, + FCD4D6A3F49D03247162F346 /* id_front_config.json */, + 5CCF370CDE77C6F2BB4A8B77 /* universal_id_composite_config.json */, + 75EE32EDE551A66FEB4F027B /* universal_id_front_config.json */, + ); + path = Configs; + sourceTree = ""; + }; B4E54664451AC52545CC0966 /* IBAN */ = { isa = PBXGroup; children = ( @@ -1223,12 +1357,24 @@ BDBF69FF241913AB6A5C267D /* LicensePlate */ = { isa = PBXGroup; children = ( + 12D7CF237BE3E4DB8F98A5C9 /* vehicle_config_license_plate_af.json */, + 3602E347A7732F9343FB718B /* vehicle_config_license_plate_eu.json */, + 122ECADCFD6E28BF208F6186 /* vehicle_config_license_plate_us.json */, 25B865680DAF95A866C48832 /* ViewController */, AE56134437D7D117CA96FA79 /* Views */, ); path = LicensePlate; sourceTree = ""; }; + BFA9771B2518D26DA35BD28A /* ViewController */ = { + isa = PBXGroup; + children = ( + E22BC03628E43B403E040936 /* ALContainerScanViewController.h */, + 65BAE9DE655BD12A9D60F3AC /* ALContainerScanViewController.m */, + ); + path = ViewController; + sourceTree = ""; + }; D060D46C2B51104DE5091B0A /* ScanViewController */ = { isa = PBXGroup; children = ( @@ -1241,6 +1387,7 @@ D1ABF7FDD836391CA8BBD34C /* TIN */ = { isa = PBXGroup; children = ( + 8CEEE043EF359766A6BCDBAA /* tire_config_tin.json */, 418E6F934ECA1FE919A0F26A /* ViewController */, ); path = TIN; @@ -1293,6 +1440,14 @@ path = MeterScan; sourceTree = ""; }; + E5A6E21F3A8CEBA5D9A433BE /* trained_models */ = { + isa = PBXGroup; + children = ( + 41D07B8132742DE010F6487C /* PepsiCo.any */, + ); + path = trained_models; + sourceTree = ""; + }; E8163E9009B9BB00DE233A33 = { isa = PBXGroup; children = ( @@ -1313,18 +1468,10 @@ path = ViewController; sourceTree = ""; }; - E9C484A43E99F87F15370D32 /* ViewController */ = { - isa = PBXGroup; - children = ( - 95EC580E5D102787DB5DB9AD /* ALContainerScanViewController.h */, - 2E8F1BC85E70148A9D26AAE9 /* ALContainerScanViewController.m */, - ); - path = ViewController; - sourceTree = ""; - }; EC8DCF8EDC90B897688C6F82 /* VIN */ = { isa = PBXGroup; children = ( + 46122D14ED5C57EA54D4FBB8 /* ocr_config_vin.json */, CB56AC0CF88F101A75FF5F3E /* vin_capture_config.json */, AAA7C59283D5484725BF0BFE /* ViewController */, ); @@ -1400,6 +1547,8 @@ F9E818A444CA5C245D4F4123 /* Tire */ = { isa = PBXGroup; children = ( + 5F6EBC6A23FB72F8EA3B013F /* tire_config_commercial_tire_id.json */, + 6E66765DD1BC6A7F177D4D1B /* tire_config_tire_size.json */, CDB06AE3FB930F1B0781316C /* TireViewController.swift */, ); path = Tire; @@ -1423,15 +1572,6 @@ path = ViewController; sourceTree = ""; }; - FDBF785D090EB8336A7FD16D /* ContainerScannerHorizontal */ = { - isa = PBXGroup; - children = ( - 43BE0DB9AD5AA0BBB178E0D2 /* container_scanner_capture_config.json */, - E9C484A43E99F87F15370D32 /* ViewController */, - ); - path = ContainerScannerHorizontal; - sourceTree = ""; - }; FE110D9D8770D6DC4767AC0C /* CompositeScanning */ = { isa = PBXGroup; children = ( @@ -1472,7 +1612,7 @@ LastUpgradeCheck = 1200; TargetAttributes = { 242FC013065B3266CB6CC4CB = { - DevelopmentTeam = 35RHL53WRE; + DevelopmentTeam = 2MSE892CA7; }; }; }; @@ -1509,32 +1649,53 @@ CCC5514E032352AA175A7E5A /* LaunchScreen.xib in Resources */, 05811D0CE8A832E9CBFF0411 /* Main.storyboard in Resources */, 3E9CFE14949C30B1DAC523D5 /* MeterImagesAssets.xcassets in Resources */, + EAB86D1B9FA83DC872276C25 /* PepsiCo.any in Resources */, F2966A08EF5C306C23684775 /* ReadingDetailsViewController.xib in Resources */, 8678F0EF3FACD7EB8A9AAE26 /* ReadingTableViewCell.xib in Resources */, 48BF457F44BE29DECD0930B7 /* WorkForceViewController.xib in Resources */, 960A7953672EA0B639A30FA5 /* WorkforceToolResultViewController.xib in Resources */, 3AB4C32E8B0BB9540DBD4A22 /* WorkorderViewController.xib in Resources */, 91B62B8BB91EF62AE767AF17 /* barcode_pdf417_in_id.json in Resources */, + 5A8A2848CE8A3CBDFE0B1EAA /* bottlecap_config.json in Resources */, 9516DCB1D2B2D301D7A01D36 /* colors.xcassets in Resources */, - C8302D96CB313E588383B035 /* container_scanner_capture_config.json in Resources */, 37FA8753994D60E353707D5E /* cow_tag_capture_config.json in Resources */, + BE300F0D1554BC645D1EF04A /* driver_license_composite_config.json in Resources */, + 49CE1D6389C3AF9CD8A7D0AE /* driver_license_front_config.json in Resources */, AE24A6531BBE3500185E26EE /* energyMockData1.json in Resources */, 194E973F43A3B0B57A330BB5 /* energyMockData2.json in Resources */, + 653B10DE44298C689DBB4163 /* horizontal_container_scanner_capture_config.json in Resources */, 406E5D4689D2162E66631DCF /* iban_config.json in Resources */, + E4B8C00D1277B100526EB09F /* id_composite_config.json in Resources */, + EB9B3989CEA7F790F0459E43 /* id_front_config.json in Resources */, DED860F64AF49DD872DCAC2C /* isbn_config.json in Resources */, 860F95A49274210ADE787DA0 /* meter_barcode_parallel.json in Resources */, - 126C1E99EAA1D1E63FAB2CCE /* meter_barcode_view_config.json in Resources */, + F6EE2B9862A9B3AC5954000D /* meter_config.json in Resources */, + 928506238F97E4339010FB34 /* mrz_config.json in Resources */, + 62DFD74D11E735783CFF2034 /* mrz_nfc_config.json in Resources */, + D4A07FD4B1F394518AFF3CA6 /* ocr_config_vin.json in Resources */, + BD506409ECC64FFF9C9A5628 /* parallel_meter_barcode_config.json in Resources */, + 40F8338328B75E861FD31AC7 /* pepsi_code_scanner.ale in Resources */, EFCF9293DCE54B0BB32ED198 /* rb_config.json in Resources */, BF5534687932FF0FBC0742BB /* record_number_config.json in Resources */, + 2311BF58E7C0C70EADF84D27 /* sample_barcode_config.json in Resources */, + CC67FAA55F51DF471B2E95E4 /* sample_barcode_fullframe_config.json in Resources */, B49B5638CE76407C30941E70 /* scrabble_config.json in Resources */, + 328BE2F58D9676B0DB02BC20 /* serial_meter_barcode_config.json in Resources */, 182D8027B52B44AEF891E12D /* serial_number_view_config.json in Resources */, - 2281E6053A1BED4163CDDC0F /* universal_id_arabic_config.json in Resources */, - 98040C0E88114B038FA681E9 /* universal_id_camera_config.json in Resources */, - DF769EF1A4C7A11DE916D0B1 /* universal_id_config.json in Resources */, - F941A07E7CE5C1FA5D76DC06 /* universal_id_cyrillic_config.json in Resources */, - D30B74B0A2CFE68B8E57FE58 /* universal_id_flash_config.json in Resources */, + 28FFA95E225588B9EB89B8FF /* template_type_and_region_mapping.json in Resources */, + 84BDD80EFB9A397D56E23831 /* template_type_and_region_mapping_arabic.json in Resources */, + 6B8886F14C250DC89003C287 /* template_type_and_region_mapping_cyrillic.json in Resources */, + 8405CEB9C5B8E864D8430024 /* tire_config_commercial_tire_id.json in Resources */, + 2D8766A4864BC62B9A6F85C1 /* tire_config_tin.json in Resources */, + D1C525D095389570CE3D94A0 /* tire_config_tire_size.json in Resources */, + E5461597FBA8D7ED0339F0DE /* universal_id_composite_config.json in Resources */, + 5CAB42391E1E0AC65BB4CB1E /* universal_id_front_config.json in Resources */, + 35A59E9A177AEDC684FE6631 /* vehicle_config_license_plate_af.json in Resources */, + 0DFF6DD995D15E50D7163470 /* vehicle_config_license_plate_eu.json in Resources */, + A8D45D4954D11214DE13AC73 /* vehicle_config_license_plate_us.json in Resources */, + 9B35130FC37EEA0189FA764E /* vehicle_registration_cert_config.json in Resources */, A58132C2E27BA742474165A3 /* vehicle_registration_certificate_config.json in Resources */, - 507F27646299BFC4E6A3B20E /* vertical_container_scanner_capture_config.json in Resources */, + 4BA88C71EE692683050BB74D /* vertical_container_scanner_capture_config.json in Resources */, 51C38786D4765B59D70915BC /* vin_capture_config.json in Resources */, 70A4D305EAB9D7D45D30B58A /* voucher_code_config.json in Resources */, ); @@ -1547,23 +1708,25 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0BA197D595DC6A8477FC5343 /* ALAFLicensePlateViewController.m in Sources */, FDF9C7606A984B1535B26B21 /* ALAnagramAPI.m in Sources */, A19EC2C4EDE4E23A8233D63A /* ALAutoAnalogDigitalMeterScanViewController.m in Sources */, 9BA532A518522696002B0872 /* ALAwardsView.m in Sources */, 258A4B98277993719781A15A /* ALBarcodeFormatHelper.m in Sources */, 095CB4818B3736D4CCF60B13 /* ALBarcodeResultUtil.m in Sources */, + FC5EA4D4F0E987CD614361AA /* ALBarcodeScanViewController.m in Sources */, + BA0A886211727B22CD490B62 /* ALBarcodeTypes.m in Sources */, BF280388FFE08C65889B8199 /* ALBaseGridCollectionViewController.m in Sources */, DDACD680801D8D6BED0F6F18 /* ALBasePageViewController.m in Sources */, 83C2E2BFA23265B9E254A1D1 /* ALBaseScanViewController.m in Sources */, BCBE543B8A4F2D0438610730 /* ALBaseViewController.m in Sources */, F41D6D9F6AD538727145B081 /* ALBlackWhiteSelectView.m in Sources */, + 70858487365B8FDA346F4E9D /* ALBottlecapScanViewController.m in Sources */, F7BFE2085451648DD83A41FB /* ALBundleInfoViewController.m in Sources */, 14D077C321FC3BD2C4E48A2A /* ALCattleTagScanViewController.m in Sources */, 9AEE556559232DFCD1E18C3A /* ALCheckbox.m in Sources */, 283D6E7FAC03BE4255C5B030 /* ALColor.m in Sources */, D221E2CBB91120179EF6758D /* ALConfigurationDialogViewController.m in Sources */, - BF6F82EFCC1CC484AB861FEF /* ALContainerScanViewController.m in Sources */, + 840FADEE4C91C71438F86666 /* ALContainerScanViewController.m in Sources */, 169B4C9E31B54A76C796C481 /* ALCustomBarButton.m in Sources */, 515D752A0145EBC1C4F37E79 /* ALCustomToolbar.m in Sources */, 264757EB2EB2998FB04CDC77 /* ALDeviceInformationHelper.m in Sources */, @@ -1588,9 +1751,10 @@ BCEDAE444AB969E5885E0B84 /* ALIntroHelpView.m in Sources */, 048D926CB90CE382DA386467 /* ALIntroHelpViewElectric.m in Sources */, DD6D666DD6B9C7CF1CD894FD /* ALJSONDownloader.m in Sources */, + 4EAD3FECAD05047D60A98D59 /* ALLeftCheckmarkCell.swift in Sources */, 9D6D1A47066EC5C9D3CAE9F4 /* ALLicensePlateExampleManager.m in Sources */, 29D8242790C62F87231582E6 /* ALLicensePlateResultOverlayView.m in Sources */, - 29831F17C4FF37E76BC5B011 /* ALLicensePlateViewController.m in Sources */, + 39E93F86C5BACD85EB12E556 /* ALLicensePlateScanViewController.m in Sources */, 18CCD1DA39115412EB8F04DD /* ALMROExampleManager.m in Sources */, E81F0DED94A08AAB70CDBD5F /* ALMRZScanViewController.m in Sources */, BB1A1B3F63B629057BC79103 /* ALMainPageViewController.m in Sources */, @@ -1600,18 +1764,20 @@ 90EE64FF8696C360624B0722 /* ALMeterReading.m in Sources */, 3FD6E7E2F5050E4CE427F62F /* ALMeterReadingView.m in Sources */, F4F2A31F71743A62504EF460 /* ALMeterScanResultViewController.m in Sources */, + 964A314C4CDF9A84E1E2A899 /* ALMeterScanViewController.swift in Sources */, 993857DE93729EB601CD1A8E /* ALMeterSelectView.m in Sources */, 0378AF0440628F40F9073D57 /* ALMeterSerialNumberScanViewController.m in Sources */, - CE8264C3DD5BF63959DA3888 /* ALMultiformatBarcodeScanViewController.m in Sources */, 37B8BA82610E2579475245FC /* ALNFCScanViewController.m in Sources */, 4FFCDDFFE82E17F6D6C38CCE /* ALOthersExampleManager.m in Sources */, 7B974FABA902C5631FDD2681 /* ALPDF417ScanViewController.m in Sources */, A9B86F7EC70516E6742E48BA /* ALParallelMeterScanViewController.m in Sources */, 30F4F4027665E6F24DC48EC5 /* ALParallelMeterWithJSONScanViewController.m in Sources */, + D6B05EA56B02926FFDE63DD0 /* ALPluginResultHelper.m in Sources */, E2B5A3C0DD9F2F95F8DBD47A /* ALPrivacyForwardingViewController.m in Sources */, 74BDDA1262C89D83FE54EECB /* ALPrivacyViewController.m in Sources */, 21A22328A97C63E67AE854BA /* ALProductExampleManager.m in Sources */, 9B85D1299B1E0B254BA1C6CA /* ALRBScanViewController.m in Sources */, + A07CD1E8B7D961556C9221D1 /* ALRatioTableViewCell.swift in Sources */, 3A9ED79B2EAD0E0CDC1E2F88 /* ALRecordNumberScanViewController.m in Sources */, ACD1F695702B436C98BFB2A1 /* ALResultCell.swift in Sources */, F37CF9F01356EC3739529DB9 /* ALResultEntry.swift in Sources */, @@ -1626,25 +1792,30 @@ AE4562D43E2A1260A78D10EE /* ALScrabbleWord.m in Sources */, DFFFD961846F72E077B90DC9 /* ALScriptSelectionViewController.m in Sources */, 3F5D3D6335DD200637C834A9 /* ALSelectionTable.m in Sources */, + CBAE26FD8584C84E9A97D868 /* ALSliderTableViewCell.swift in Sources */, E59639494B52B250C0143E0E /* ALSpaceViews.m in Sources */, 4D515F3438EE08E225088CA7 /* ALTINScanViewController.m in Sources */, + 5C797FDAC23F78495D38EF03 /* ALTextInputTableViewCell.swift in Sources */, 3E02A9E81691C221D70DD201 /* ALTextViewCell.m in Sources */, 216AD56855460694DB2EAFD2 /* ALToggleControl.m in Sources */, 409F58D9331828393B73B29D /* ALTutorialViewController.m in Sources */, - 253C818A2B144F00DB6636B0 /* ALUSLicensePlateViewController.m in Sources */, - 122FC76CBA910344E10CA488 /* ALUniversalIDFieldnameUtil.m in Sources */, + 4A9D8E4A7DD96DCF12704AF2 /* ALUniveralIDResultHelper.m in Sources */, + 27F51F97C80D8187F68CFF83 /* ALUniversalIDScanConfigController.m in Sources */, C170B4970555750081E80741 /* ALUniversalIDScanViewController.m in Sources */, - E9608A9789B2711CC5501AAF /* ALUniversalIDScanViewControllerFrontAndBack.m in Sources */, 03DF5696948CA0436A2D9AA8 /* ALUniversalSerialNumberScanViewController.m in Sources */, + A9BBFD1ACDD29006C67B5142 /* ALUnselectableLinkableTextView.swift in Sources */, 332E5FE5513F6CDD2346D6D2 /* ALUtils.m in Sources */, BF07386056E53CFE5C441BB7 /* ALVINScanViewController.m in Sources */, - 6D18D4FC00EE5AACCBB6B2BD /* ALVehicleRegistrationCertificateViewController.m in Sources */, - 5696F41B6116EFE209F7D4A4 /* ALVerticalContainerScanViewController.m in Sources */, + FF05E84C997F8A8D6E0884D4 /* ALVRCScanViewController.m in Sources */, DBD0CB5D7B8AED3B3E083BE3 /* ALVoucherCodeScanViewController.m in Sources */, 45E1C7C5AE4504472B25C3F6 /* ALWarningView.m in Sources */, + 6E4690B70636736BC2A31923 /* AdvancedSettingsViewController.swift in Sources */, + ABDA19B56626D2838BF2B00B /* AnylineBottlecapScanViewController.swift in Sources */, 1B339AD1A6982A23A58AFBD5 /* AnylineEnergyModel.xcdatamodeld in Sources */, A8924A6DC244EC095BD6BCB1 /* AnylineExamples.xcdatamodeld in Sources */, 4132425F48F3428439BDDBA5 /* AppDelegate.m in Sources */, + 8EB00F60AFB0F24DE41ECE84 /* BaseSettingsViewController.swift in Sources */, + CF1C8FA3AE4C955E406C048F /* BasicSettingsViewController.swift in Sources */, 7160AD923669EB0720FCD3C9 /* CoreDataManager.m in Sources */, 443B304C865770E9A68AE47A /* Customer+CoreDataProperties.m in Sources */, 385239AF4AE6238CE1452B31 /* Customer.m in Sources */, @@ -1655,9 +1826,9 @@ 382DD1C0C8F51585A0F699F6 /* CustomerSelfReadingConfirmationViewController.m in Sources */, 923D2E3DC71E410C28E45910 /* CustomerSelfReadingResultViewController.m in Sources */, D1ECDA522B38A0E201B91196 /* CustomerSelfReadingViewController.m in Sources */, + 64E90611C37D3635E6146855 /* CutoutSettings.swift in Sources */, 0653D0F7EFB27B2C65823576 /* ElectricMeterBlackWhiteScanViewController.swift in Sources */, A66630A6C0A9ECB50C022625 /* FormFieldView.swift in Sources */, - 190C9F7DC0103BDD709F6701 /* GifuWrapper.swift in Sources */, AE64F68FC2C785CC42C6D626 /* ISBNInfo.m in Sources */, F00A3D1FC8632FEA4AB60C44 /* Model.xcmappingmodel in Sources */, 8DF1F05CDED63700EEF343C5 /* NSArray+ALExamplesAdditions.m in Sources */, @@ -1676,10 +1847,13 @@ B8C1BB40368F01856FE10792 /* ReadingDetailsViewController.m in Sources */, 0F5545C5A922F2ABCFAE2845 /* ReadingTableViewCell.m in Sources */, B9C04394AB2B1F3688EABC98 /* ReadingTransformationPolicy.m in Sources */, + CA1A08EB4544AF442551E42B /* ScanAreaEditorViewController.swift in Sources */, 78450894B4E04FD3F2CBC860 /* ScanHistory+CoreDataClass.m in Sources */, 486D260E0AA1DCD6BC257483 /* ScanHistory+CoreDataProperties.m in Sources */, 6F80C436AEC24B717740CF88 /* ScanHistoryMigration3to4.m in Sources */, E4660E0BAEC49D4B4180D824 /* ScanHistoryMigration3to4.xcmappingmodel in Sources */, + 17A53ACF560340D93B51F9DD /* SerialNumberSettings.swift in Sources */, + E73EECCE7C6D35F8C70BBC8F /* SerialNumberSettingsViewController.swift in Sources */, 1175ADE866CE976EFFC54EDB /* TireViewController.swift in Sources */, 7F57D792ED6FECA6A50A3F37 /* UIButton+ALExamplesExtensions.m in Sources */, 07C382512D3E2C2456D47B16 /* UIColor+ALExamplesAdditions.m in Sources */, @@ -1725,7 +1899,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = AnylineExamples.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; - DEVELOPMENT_TEAM = 35RHL53WRE; + DEVELOPMENT_TEAM = 2MSE892CA7; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( ./../Framework, @@ -1744,7 +1918,7 @@ /, ); OTHER_LDFLAGS = "-ObjC"; - PRODUCT_BUNDLE_IDENTIFIER = io.anyline.examples.test; + PRODUCT_BUNDLE_IDENTIFIER = io.anyline.examples.bundle; SDKROOT = iphoneos; SWIFT_OBJC_BRIDGING_HEADER = "./Anyline Examples Source/AnylineExamples-Bridging-Header.h"; SWIFT_VERSION = 5; @@ -1813,7 +1987,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = AnylineExamples.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; - DEVELOPMENT_TEAM = 35RHL53WRE; + DEVELOPMENT_TEAM = 2MSE892CA7; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( ./../Framework, @@ -1832,7 +2006,7 @@ /, ); OTHER_LDFLAGS = "-ObjC"; - PRODUCT_BUNDLE_IDENTIFIER = io.anyline.examples.test; + PRODUCT_BUNDLE_IDENTIFIER = io.anyline.examples.bundle; SDKROOT = iphoneos; SWIFT_OBJC_BRIDGING_HEADER = "./Anyline Examples Source/AnylineExamples-Bridging-Header.h"; SWIFT_VERSION = 5; diff --git a/AnylineExamples/AnylineExamples.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/AnylineExamples/AnylineExamples.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/AnylineExamples/AnylineExamples.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Documentation/html/Blocks/ALImageProviderBlock.html b/Documentation/html/Blocks/ALImageProviderBlock.html deleted file mode 100644 index e54ec8f0e..000000000 --- a/Documentation/html/Blocks/ALImageProviderBlock.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - ALImageProviderBlock Block Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

ALImageProviderBlock Block Reference

- - -
- - - - -
Declared inALImageProvider.h
- - - - - - - - - - -

Block Definition

-

ALImageProviderBlock

- - -
-

The block definition which will provide the callback for the next image.

-
- - - -typedef void (^ALImageProviderBlock) (ALImage *image, ALImage *fullImage, CGRect cropRect, NSError *error) - - - - - - - - - - - -
-

Declared In

- ALImageProvider.h
-
- - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Blocks/APDUCompletionHandler.html b/Documentation/html/Blocks/APDUCompletionHandler.html deleted file mode 100644 index 8e3f56b3e..000000000 --- a/Documentation/html/Blocks/APDUCompletionHandler.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - APDUCompletionHandler Block Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

APDUCompletionHandler Block Reference

- - -
- - - - -
Declared inALTagReader.h
- - - - - - - - - - -

Block Definition

-

APDUCompletionHandler

- - -typedef void (^APDUCompletionHandler) (ALResponseAPDU *_Nullable, response , NSError *_Nullable, tagError ) - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Blocks/DataGroupCompletionHandler.html b/Documentation/html/Blocks/DataGroupCompletionHandler.html deleted file mode 100644 index 938cd236c..000000000 --- a/Documentation/html/Blocks/DataGroupCompletionHandler.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - DataGroupCompletionHandler Block Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

DataGroupCompletionHandler Block Reference

- - -
- - - - -
Declared inALNFCPassportModel.h
- - - - - - - - - - -

Block Definition

-

DataGroupCompletionHandler

- - -typedef void (^DataGroupCompletionHandler) (DataGroupId dataGroupID, ALInternalDataGroup *_Nonnull, dataGroup ) - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Blocks/ErrorHandler.html b/Documentation/html/Blocks/ErrorHandler.html deleted file mode 100644 index 3f46c154a..000000000 --- a/Documentation/html/Blocks/ErrorHandler.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - ErrorHandler Block Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

ErrorHandler Block Reference

- - -
- - - - -
Declared inALBACHandler.h
- - - - - - - - - - -

Block Definition

-

ErrorHandler

- - -typedef void (^ErrorHandler) (NSError *_Nullable, tagError ) - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Blocks/NFCCompletionHandler.html b/Documentation/html/Blocks/NFCCompletionHandler.html deleted file mode 100644 index 6886a4602..000000000 --- a/Documentation/html/Blocks/NFCCompletionHandler.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - NFCCompletionHandler Block Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NFCCompletionHandler Block Reference

- - -
- - - - -
Declared inALPassportReader.h
- - - - - - - - - - -

Block Definition

-

NFCCompletionHandler

- - -typedef void (^NFCCompletionHandler) (ALNFCPassportModel *_Nullable, passportModel , NSError *_Nullable, tagError ) - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Blocks/TagReadingCompletionHandler.html b/Documentation/html/Blocks/TagReadingCompletionHandler.html deleted file mode 100644 index e185c9814..000000000 --- a/Documentation/html/Blocks/TagReadingCompletionHandler.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - TagReadingCompletionHandler Block Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

TagReadingCompletionHandler Block Reference

- - -
- - - - -
Declared inALTagReader.h
- - - - - - - - - - -

Block Definition

-

TagReadingCompletionHandler

- - -typedef void (^TagReadingCompletionHandler) (NSArray <, NSNumber *>, * _Nullable, response , NSError *_Nullable, tagError ) - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSArray+ALExtras.html b/Documentation/html/Categories/NSArray+ALExtras.html new file mode 100644 index 000000000..97610aab7 --- /dev/null +++ b/Documentation/html/Categories/NSArray+ALExtras.html @@ -0,0 +1,122 @@ + + + + + + NSArray(ALExtras) Category Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

NSArray(ALExtras) Category Reference

+ + +
+ + + + + + + +
Conforms toALJSONStringRepresentable
Declared inALJSONUtilities.h
+ + + + +
+ +

Overview

+

This extends NSArray to the type ALJSONStringRepresentable, making it possible +to obtain a JSON string as output

+
+ + + + + + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Categories/NSArray+Additions.html b/Documentation/html/Categories/NSArray+Additions.html deleted file mode 100644 index 7b35d6416..000000000 --- a/Documentation/html/Categories/NSArray+Additions.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - NSArray(Additions) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSArray(Additions) Category Reference

- - -
- - - - -
Declared inNSArray+Additions.h
- - - - - - -
- - - - - - -
-
- -

– objectAtIndexOrNil: -

- -
-
- -
- - -
- (id)objectAtIndexOrNil:(NSInteger)index
- - -
-
-
- -

– firstObject -

- -
-
- -
- - -
- (id)firstObject
- - -
-
-
- -

– randomElement -

- -
-
- -
- - -
- (id)randomElement
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSArray+PrefixSuffix.html b/Documentation/html/Categories/NSArray+PrefixSuffix.html deleted file mode 100644 index aa87abcaa..000000000 --- a/Documentation/html/Categories/NSArray+PrefixSuffix.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - NSArray(PrefixSuffix) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSArray(PrefixSuffix) Category Reference

- - -
- - - - -
Declared inNSArray+PrefixSuffix.h
- - - - - - -
- - - - - - -
-
- -

– suffixWithLength: -

- -
-
- -
- - -
- (NSArray *)suffixWithLength:(NSInteger)length
- - -
-
-
- -

– prefixWithLength: -

- -
-
- -
- - -
- (NSArray *)prefixWithLength:(NSInteger)length
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSBundle+ALExtensions.html b/Documentation/html/Categories/NSBundle+ALExtensions.html deleted file mode 100644 index b3028b034..000000000 --- a/Documentation/html/Categories/NSBundle+ALExtensions.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - NSBundle(ALExtensions) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSBundle(ALExtensions) Category Reference

- - -
- - - - -
Declared inNSBundle+ALExtensions.h
- - - - - - -
- - - - - - -
-
- -

+ pathInAllBundlesForResource:type:inDirectory: -

- -
-
- -
- - -
+ (NSString *)pathInAllBundlesForResource:(NSString *)fileName type:(NSString *_Nullable)type inDirectory:(NSString *_Nullable)directoryName
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSData+ALExtras.html b/Documentation/html/Categories/NSData+ALExtras.html new file mode 100644 index 000000000..ecadbe3c8 --- /dev/null +++ b/Documentation/html/Categories/NSData+ALExtras.html @@ -0,0 +1,246 @@ + + + + + + NSData(ALExtras) Category Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

NSData(ALExtras) Category Reference

+ + +
+ + + + +
Declared inALJSONUtilities.h
+ + + + +
+ +

Overview

+

Methods to convert an NSData to a valid JSON object (dictionary or array)

+
+ + + + + +
+ + + + + + +
+
+ +

– toJSONObject: +

+ +
+
+ +
+ + +
+

NSError object that is set when the JSON conversion encountered errors

+
+ + + +
- (id _Nullable)toJSONObject:(NSError *_Nullable *_Nullable)error
+ + + +
+

Parameters

+ + + + + + + +
error

NSError object that is set when the JSON conversion encountered errors

+
+ + + +
+

Return Value

+

the JSON object, or null

+
+ + + + + + + + + + + +
+

Declared In

+

ALJSONUtilities.h

+
+ + +
+
+
+ +

– asJSONObject +

+ +
+
+ +
+ + +
+

Returns a JSON object (could be an NSDictionary or an NSArray) converted from the NSData +object, or null, if conversion is not possible. No error value is set in this version.

+
+ + + +
- (id _Nullable)asJSONObject
+ + + + + +
+

Return Value

+

the JSON object

+
+ + + + + + + + + + + +
+

Declared In

+

ALJSONUtilities.h

+
+ + +
+
+
+
+ +
+ + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Categories/NSData+DataArrays.html b/Documentation/html/Categories/NSData+DataArrays.html deleted file mode 100644 index a6a5483bd..000000000 --- a/Documentation/html/Categories/NSData+DataArrays.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - NSData(DataArrays) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSData(DataArrays) Category Reference

- - -
- - - - -
Declared inNSMutableData+DataArrays.h
- - - - - - -
- - - - - - -
-
- -

– toArray -

- -
-
- -
- - -
- (NSArray<NSNumber*> *)toArray
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSDateFormatter+ALExtensions.html b/Documentation/html/Categories/NSDateFormatter+ALExtensions.html deleted file mode 100644 index 882423253..000000000 --- a/Documentation/html/Categories/NSDateFormatter+ALExtensions.html +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - NSDateFormatter(ALExtensions) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSDateFormatter(ALExtensions) Category Reference

- - -
- - - - -
Declared inNSDateFormatter+ALExtensions.h
- - - - - - -
- - - - - - -
-
- -

+ AL_azureDateFormatterCached -

- -
-
- -
- - -
+ (NSDateFormatter *)AL_azureDateFormatterCached
- - -
-
-
- -

+ AL_azureHeaderDate -

- -
-
- -
- - -
+ (NSString *)AL_azureHeaderDate
- - -
-
-
- -

+ AL_azureHeaderDate: -

- -
-
- -
- - -
+ (NSString *)AL_azureHeaderDate:(NSDate *)date
- - -
-
-
- -

+ AL_partitionDate -

- -
-
- -
- - -
+ (NSString *)AL_partitionDate
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSDictionary+ALExtras.html b/Documentation/html/Categories/NSDictionary+ALExtras.html new file mode 100644 index 000000000..1e0bc4ca6 --- /dev/null +++ b/Documentation/html/Categories/NSDictionary+ALExtras.html @@ -0,0 +1,122 @@ + + + + + + NSDictionary(ALExtras) Category Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

NSDictionary(ALExtras) Category Reference

+ + +
+ + + + + + + +
Conforms toALJSONStringRepresentable
Declared inALJSONUtilities.h
+ + + + +
+ +

Overview

+

This extends NSDictionary to the type ALJSONStringRepresentable, making it possible +to obtain a JSON string as output

+
+ + + + + + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Categories/NSDictionary+ALJSON.html b/Documentation/html/Categories/NSDictionary+ALJSON.html deleted file mode 100644 index 9a74eb55b..000000000 --- a/Documentation/html/Categories/NSDictionary+ALJSON.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - NSDictionary(ALJSON) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSDictionary(ALJSON) Category Reference

- - -
- - - - -
Declared inNSDictionary+ALJSON.h
- - - - - - -
- - - - - - -
-
- -

– AL_jsonStringWithPrettyPrint: -

- -
-
- -
- - -
- (NSString *)AL_jsonStringWithPrettyPrint:(BOOL)prettyPrint
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSDictionary+CPPWrapper.html b/Documentation/html/Categories/NSDictionary+CPPWrapper.html deleted file mode 100644 index 094ea46d8..000000000 --- a/Documentation/html/Categories/NSDictionary+CPPWrapper.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - NSDictionary(CPPWrapper) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSDictionary(CPPWrapper) Category Reference

- - -
- - - - -
Declared inNSDictionary+CPPWrapper.h
NSDictionary+CPPWrapper.mm
- - - - - - -
- - - - - - -
-
- -

– AL_cppMap -

- -
-
- -
- - -
- (std : : map<std::string,std::shared_ptr<al::Variable> >)AL_cppMap
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSError+CPPWrapper.html b/Documentation/html/Categories/NSError+CPPWrapper.html deleted file mode 100644 index a1863eb77..000000000 --- a/Documentation/html/Categories/NSError+CPPWrapper.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - - NSError(CPPWrapper) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSError(CPPWrapper) Category Reference

- - -
- - - - -
Declared inNSError+CPPWrapper.h
NSError+CPPWrapper.mm
- - - - - - -
- - - - - - -
-
- -

+ AL_errorFromSyntaxException: -

- -
-
- -
- - -
+ (NSError *)AL_errorFromSyntaxException:(al : : SyntaxException)syntaxException
- - -
-
-
- -

+ AL_errorFromAnylineException: -

- -
-
- -
- - -
+ (NSError *)AL_errorFromAnylineException:(al : : AnylineException)anylineException
- - -
-
-
- -

+ AL_errorFromLicenseException: -

- -
-
- -
- - -
+ (NSError *)AL_errorFromLicenseException:(al : : LicenseException)licenseException
- - -
-
-
- -

+ AL_errorFromArgumentException: -

- -
-
- -
- - -
+ (NSError *)AL_errorFromArgumentException:(al : : ArgumentException)argumentException
- - -
-
-
- -

+ AL_errorFromRunFailure: -

- -
-
- -
- - -
+ (NSError *)AL_errorFromRunFailure:(al : : RunFailure)runFailure
- - -
-
-
- -

+ AL_errorFromAssetException: -

- -
-
- -
- - -
+ (NSError *)AL_errorFromAssetException:(al : : AssetException)assetException
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSMutableData+DataArrays.html b/Documentation/html/Categories/NSMutableData+DataArrays.html deleted file mode 100644 index 6b66d1676..000000000 --- a/Documentation/html/Categories/NSMutableData+DataArrays.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - NSMutableData(DataArrays) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSMutableData(DataArrays) Category Reference

- - -
- - - - -
Declared inNSMutableData+DataArrays.h
- - - - - - -
- - - - - - -
-
- -

+ dataWithArray: -

- -
-
- -
- - -
+ (instancetype)dataWithArray:(NSArray<NSNumber*> *)array
- - -
-
-
- -

– appendDataFromArray: -

- -
-
- -
- - -
- (void)appendDataFromArray:(NSArray<NSNumber*> *)array
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSString+ALExtensions.html b/Documentation/html/Categories/NSString+ALExtensions.html deleted file mode 100644 index b2c266f75..000000000 --- a/Documentation/html/Categories/NSString+ALExtensions.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - - NSString(ALExtensions) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

NSString(ALExtensions) Category Reference

- - -
- - - - -
Declared inNSString+ALExtensions.h
NSString+ALExtensions.mm
- - - - - - -
- - - - - - -
-
- -

– AL_contains: -

- -
-
- -
- - -
-

Test if the string contains aString

-
- - - -
- (BOOL)AL_contains:(NSString *)aString
- - - -
-

Parameters

- - - - - - - -
aString

the other string to test -returns YES if the string contains the other aString, NO otherwise

-
- - - - - - - - - - - - - -
-

Declared In

-

NSString+ALExtensions.h

-
- - -
-
-
- -

– AL_occurrenceCountOfCharacter: -

- -
-
- -
- - -
- (NSUInteger)AL_occurrenceCountOfCharacter:(UniChar)character
- - -
-
-
- -

– AL_base64_encode: -

- -
-
- -
- - -
- (NSString *)AL_base64_encode:(NSData *)data
- - -
-
-
- -

– AL_base64_decodeToString -

- -
-
- -
- - -
- (NSString *)AL_base64_decodeToString
- - -
-
-
- -

– AL_base64_decodeToData -

- -
-
- -
- - -
- (NSData *)AL_base64_decodeToData
- - -
-
-
- -

+ documentsDirectory -

- -
-
- -
- - -
+ (NSString *)documentsDirectory
- - -
-
-
- -

+ md5HashOfPath: -

- -
-
- -
- - -
+ (NSString *)md5HashOfPath:(NSString *)path
- - -
-
-
- -

+ stringWithCppString: -

- -
-
- -
- - -
+ (instancetype)stringWithCppString:(std : : string)cppString
- - -
-
-
- -

– cppString -

- -
-
- -
- - -
- (std : : string)cppString
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/NSString+ALExtras.html b/Documentation/html/Categories/NSString+ALExtras.html new file mode 100644 index 000000000..523514b62 --- /dev/null +++ b/Documentation/html/Categories/NSString+ALExtras.html @@ -0,0 +1,246 @@ + + + + + + NSString(ALExtras) Category Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

NSString(ALExtras) Category Reference

+ + +
+ + + + +
Declared inALJSONUtilities.h
+ + + + +
+ +

Overview

+

Methods to convert an NSString to a valid JSON object (dictionary or array)

+
+ + + + + +
+ + + + + + +
+
+ +

– toJSONObject: +

+ +
+
+ +
+ + +
+

NSError object that is set when the JSON conversion encountered errors

+
+ + + +
- (id _Nullable)toJSONObject:(NSError *_Nullable *_Nullable)error
+ + + +
+

Parameters

+ + + + + + + +
error

NSError object that is set when the JSON conversion encountered errors

+
+ + + +
+

Return Value

+

the JSON object, or null

+
+ + + + + + + + + + + +
+

Declared In

+

ALJSONUtilities.h

+
+ + +
+
+
+ +

– asJSONObject +

+ +
+
+ +
+ + +
+

Returns a JSON object (could be an NSDictionary or an NSArray) converted from the NSData +object, or null, if conversion is not possible. No error value is set in this version.

+
+ + + +
- (id _Nullable)asJSONObject
+ + + + + +
+

Return Value

+

the JSON object

+
+ + + + + + + + + + + +
+

Declared In

+

ALJSONUtilities.h

+
+ + +
+
+
+
+ +
+ + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Categories/UIColor+ALHexColors.html b/Documentation/html/Categories/UIColor+ALHexColors.html deleted file mode 100644 index 37d043749..000000000 --- a/Documentation/html/Categories/UIColor+ALHexColors.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - - - UIColor(ALHexColors) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

UIColor(ALHexColors) Category Reference

- - -
- - - - -
Declared inUIColor+ALHexColors.h
- - - - - - -
- - - - - - -
-
- -

+ AL_colorWithHexString: -

- -
-
- -
- - -
+ (UIColor *)AL_colorWithHexString:(NSString *)hexString
- - -
-
-
- -

+ AL_hexValuesFromUIColor: -

- -
-
- -
- - -
+ (NSString *)AL_hexValuesFromUIColor:(UIColor *)color
- - -
-
-
- -

– webHexValue -

- -
-
- -
- - -
- (NSString *)webHexValue
- - -
-
-
- -

– webHexValueAlphaLast -

- -
-
- -
- - -
- (NSString *)webHexValueAlphaLast
- - -
-
-
- -

– webHexValueAlphaFirst -

- -
-
- -
- - -
- (NSString *)webHexValueAlphaFirst
- - -
-
-
- -

– getAlphaValue -

- -
-
- -
- - -
- (CGFloat)getAlphaValue
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/UIColor+ALOpenCV.html b/Documentation/html/Categories/UIColor+ALOpenCV.html deleted file mode 100644 index 8cae3c53a..000000000 --- a/Documentation/html/Categories/UIColor+ALOpenCV.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - UIColor(ALOpenCV) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

UIColor(ALOpenCV) Category Reference

- - -
- - - - -
Declared inUIColor+ALOpenCV.h
UIColor+ALOpenCV.mm
- - - - - - -
- - - - - - -
-
- -

+ AL_colorWithScalar: -

- -
-
- -
- - -
+ (UIColor *)AL_colorWithScalar:(const alcv : : Scalar &)scalar
- - -
-
-
- -

– AL_scalar -

- -
-
- -
- - -
- (alcv : : Scalar)AL_scalar
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/UIImage+ALExtensions.html b/Documentation/html/Categories/UIImage+ALExtensions.html deleted file mode 100644 index 7b3187e4d..000000000 --- a/Documentation/html/Categories/UIImage+ALExtensions.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - - UIImage(ALExtensions) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

UIImage(ALExtensions) Category Reference

- - -
- - - - -
Declared inUIImage+ALExtensions.h
UIImage+ALExtensions.mm
- - - - - - -
- - - - -

Other Methods

- -
-
- -

– AL_imageWithSpecOverlay: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithSpecOverlay:(ALROISpec *)displaySpec
- - -
-
-
- -

– AL_imageWithDisplayResult: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithDisplayResult:(ALDisplayResult *)displayResult
- - -
-
-
-
- - - -

Other Methods

- -
-
- -

– AL_imageWithDigitOverlay: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithDigitOverlay:(ALDataPoint *)digitSpec
- - -
-
-
- -

– AL_imageWithRectOverlay: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithRectOverlay:(CGRect)rectToDraw
- - -
-
-
- -

– AL_imageWithSquareOverlay: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithSquareOverlay:(ALSquare *)square
- - -
-
-
- -

– AL_imageWithHorizontalLines: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithHorizontalLines:(NSArray *)lines
- - -
-
-
- -

– AL_imageWithVerticalLines: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithVerticalLines:(NSArray *)lines
- - -
-
-
- -

– AL_imageWithContours: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithContours:(ALContours *)contours
- - -
-
-
- -

– AL_imageWithRectArray: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithRectArray:(NSArray *)rects
- - -
-
-
- -

– AL_imageWithLineFromPoint:toPoint: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithLineFromPoint:(CGPoint)p1 toPoint:(CGPoint)p2
- - -
-
-
- -

– AL_imageWithPixelAtPoint: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithPixelAtPoint:(CGPoint)p1
- - -
-
-
- -

– AL_imageTransformedWithUpLeft:upRight:downLeft:downRight: -

- -
-
- -
- - -
- (UIImage *)AL_imageTransformedWithUpLeft:(CGPoint)upLeft upRight:(CGPoint)upRight downLeft:(CGPoint)downLeft downRight:(CGPoint)downRight
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/UIImage+ALOpenCV.html b/Documentation/html/Categories/UIImage+ALOpenCV.html deleted file mode 100644 index 98a024fcb..000000000 --- a/Documentation/html/Categories/UIImage+ALOpenCV.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - - UIImage(ALOpenCV) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

UIImage(ALOpenCV) Category Reference

- - -
- - - - -
Declared inUIImage+ALOpenCV.hh
UIImage+ALOpenCV.mm
- - - - - - -
- - - - - - -
-
- -

– AL_CVMat_dave -

- -
-
- -
- - -
- (alcv : : Mat)AL_CVMat_dave
- - -
-
-
- -

– AL_CVMat -

- -
-
- -
- - -
- (alcv : : Mat)AL_CVMat
- - -
-
-
- -

+ CVMatfromImageBuffer: -

- -
-
- -
- - -
+ (alcv : : Mat)CVMatfromImageBuffer:(CVImageBufferRef)imageBuffer
- - -
-
-
- -

+ CVMatfromImageBufferHalfSize: -

- -
-
- -
- - -
+ (alcv : : Mat)CVMatfromImageBufferHalfSize:(CVImageBufferRef)imageBuffer
- - -
-
-
- -

– AL_CVMat3 -

- -
-
- -
- - -
- (alcv : : Mat)AL_CVMat3
- - -
-
-
- -

– AL_CVGrayscaleMat -

- -
-
- -
- - -
- (alcv : : Mat)AL_CVGrayscaleMat
- - -
-
-
- -

+ AL_imageWithCVMat:orientation: -

- -
-
- -
- - -
+ (UIImage *)AL_imageWithCVMat:(const alcv : : Mat &)cvMat orientation:(UIImageOrientation)orientation
- - -
-
-
- -

+ AL_imageWithCVMat: -

- -
-
- -
- - -
+ (UIImage *)AL_imageWithCVMat:(const alcv : : Mat &)cvMat
- - -
-
-
- -

– initWithCVMatAL:orientation: -

- -
-
- -
- - -
- (instancetype)initWithCVMatAL:(const alcv : : Mat &)cvMat orientation:(UIImageOrientation)orientation
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/UIImage+ALUtil.html b/Documentation/html/Categories/UIImage+ALUtil.html deleted file mode 100644 index 94497937b..000000000 --- a/Documentation/html/Categories/UIImage+ALUtil.html +++ /dev/null @@ -1,671 +0,0 @@ - - - - - - UIImage(ALUtil) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

UIImage(ALUtil) Category Reference

- - -
- - - - -
Declared inUIImage+ALUtil.h
- - - - - - -
- - - - - - -
-
- -

– AL_saveImageToDisk -

- -
-
- -
- - -
- (NSString *)AL_saveImageToDisk
- - -
-
-
- -

– AL_hasAlpha -

- -
-
- -
- - -
- (BOOL)AL_hasAlpha
- - -
-
-
- -

– AL_imageWithAlpha -

- -
-
- -
- - -
- (UIImage *)AL_imageWithAlpha
- - -
-
-
- -

– AL_roundedCornerImage:borderSize: -

- -
-
- -
- - -
- (UIImage *)AL_roundedCornerImage:(NSInteger)cornerSize borderSize:(NSInteger)borderSize
- - -
-
-
- -

– AL_scaleToSize: -

- -
-
- -
- - -
- (UIImage *)AL_scaleToSize:(CGSize)size
- - -
-
-
- -

– AL_scaleToWidth: -

- -
-
- -
- - -
- (UIImage *)AL_scaleToWidth:(CGFloat)width
- - -
-
-
- -

– AL_flipImageHorizontally -

- -
-
- -
- - -
- (UIImage *)AL_flipImageHorizontally
- - -
-
-
- -

– AL_imageAtRect: -

- -
-
- -
- - -
- (UIImage *)AL_imageAtRect:(CGRect)rect
- - -
-
-
- -

– AL_imageByScalingProportionallyToMinimumSize: -

- -
-
- -
- - -
- (UIImage *)AL_imageByScalingProportionallyToMinimumSize:(CGSize)targetSize
- - -
-
-
- -

– AL_imageByScalingProportionallyToSize: -

- -
-
- -
- - -
- (UIImage *)AL_imageByScalingProportionallyToSize:(CGSize)targetSize
- - -
-
-
- -

– AL_imageByScalingToSize: -

- -
-
- -
- - -
- (UIImage *)AL_imageByScalingToSize:(CGSize)targetSize
- - -
-
-
- -

– AL_imageRotatedByRadians: -

- -
-
- -
- - -
- (UIImage *)AL_imageRotatedByRadians:(CGFloat)radians
- - -
-
-
- -

– AL_imageRotatedByDegrees: -

- -
-
- -
- - -
- (UIImage *)AL_imageRotatedByDegrees:(CGFloat)degrees
- - -
-
-
- -

– AL_imageByScalingAndCroppingForSize: -

- -
-
- -
- - -
- (UIImage *)AL_imageByScalingAndCroppingForSize:(CGSize)targetSize
- - -
-
-
- -

– AL_croppedImage: -

- -
-
- -
- - -
- (UIImage *)AL_croppedImage:(CGRect)bounds
- - -
-
-
- -

– AL_resizedImage:interpolationQuality: -

- -
-
- -
- - -
- (UIImage *)AL_resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality
- - -
-
-
- -

– AL_resizedImageWithContentMode:bounds:interpolationQuality: -

- -
-
- -
- - -
- (UIImage *)AL_resizedImageWithContentMode:(UIViewContentMode)contentMode bounds:(CGSize)bounds interpolationQuality:(CGInterpolationQuality)quality
- - -
-
-
- -

– AL_transformForOrientation: -

- -
-
- -
- - -
- (CGAffineTransform)AL_transformForOrientation:(CGSize)newSize
- - -
-
-
- -

– AL_resizedImage:transform:drawTransposed:interpolationQuality: -

- -
-
- -
- - -
- (UIImage *)AL_resizedImage:(CGSize)newSize transform:(CGAffineTransform)transform drawTransposed:(BOOL)transpose interpolationQuality:(CGInterpolationQuality)quality
- - -
-
-
- -

– AL_fixOrientation -

- -
-
- -
- - -
- (UIImage *)AL_fixOrientation
- - -
-
-
- -

– AL_resizeImage -

- -
-
- -
- - -
- (UIImage *)AL_resizeImage
- - -
-
-
- -

– AL_normalizedImage -

- -
-
- -
- - -
- (UIImage *)AL_normalizedImage
- - -
-
-
- -

– AL_scaleAndRotateImage -

- -
-
- -
- - -
- (UIImage *)AL_scaleAndRotateImage
- - -
-
-
- -

+ AL_imageFromSampleBuffer: -

- -
-
- -
- - -
+ (UIImage *)AL_imageFromSampleBuffer:(CMSampleBufferRef)sampleBuffer
- - -
-
-
- -

+ AL_imageFromImageBuffer: -

- -
-
- -
- - -
+ (UIImage *)AL_imageFromImageBuffer:(CVImageBufferRef)imageBuffer
- - -
-
-
- -

+ AL_imageBufferFromCGImage: -

- -
-
- -
- - -
+ (CVImageBufferRef)AL_imageBufferFromCGImage:(CGImageRef)image
- - -
-
-
- -

– AL_grayscalePixels -

- -
-
- -
- - -
- (unsigned char *)AL_grayscalePixels
- - -
-
-
- -

– AL_rgbaPixels -

- -
-
- -
- - -
- (unsigned char *)AL_rgbaPixels
- - -
-
-
- -

– AL_rawdata -

- -
-
- -
- - -
- (unsigned char *)AL_rawdata
- - -
-
-
- -

– AL_imageWithBox:color: -

- -
-
- -
- - -
- (UIImage *)AL_imageWithBox:(CGRect)box color:(UIColor *)color
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Categories/UIWindow+ALExtensions.html b/Documentation/html/Categories/UIWindow+ALExtensions.html deleted file mode 100644 index c7ece7448..000000000 --- a/Documentation/html/Categories/UIWindow+ALExtensions.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - UIWindow(ALExtensions) Category Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

UIWindow(ALExtensions) Category Reference

- - -
- - - - -
Declared inUIWindow+ALExtensions.h
- - - - - - -
- - - - - - -
-
- -

– AL_visibleViewController -

- -
-
- -
- - -
- (UIViewController *_Nullable)AL_visibleViewController
- - -
-
-
- -

+ AL_keyWindow -

- -
-
- -
- - -
+ (UIWindow *_Nullable)AL_keyWindow
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Classes/ALAamva.html b/Documentation/html/Classes/ALAamva.html new file mode 100644 index 000000000..2353b7893 --- /dev/null +++ b/Documentation/html/Classes/ALAamva.html @@ -0,0 +1,176 @@ + + + + + + ALAamva Class Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

ALAamva Class Reference

+ + +
+ + + + + + + +
Inherits fromNSObject
Declared inALPluginResult.h
+ + + + +
+ +

Overview

+

Holds all encoded barcode information according to the AAMVA standard

+
+ + + + + +
+ + + + + + +
+
+ +

  aamvaVersion +

+ +
+
+ +
+ + +
@property (nonatomic, nullable, strong) NSNumber *aamvaVersion
+ + +
+
+
+ +

  bodyPart +

+ +
+
+ +
+ + +
@property (nonatomic, nullable, strong) ALBodyPart *bodyPart
+ + +
+
+
+
+ +
+ + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Classes/ALAbstractScanPlugin.html b/Documentation/html/Classes/ALAbstractScanPlugin.html deleted file mode 100644 index d2b9e5e2f..000000000 --- a/Documentation/html/Classes/ALAbstractScanPlugin.html +++ /dev/null @@ -1,1159 +0,0 @@ - - - - - - ALAbstractScanPlugin Class Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

ALAbstractScanPlugin Class Reference

- - -
- - - - - - - - - - -
Inherits fromNSObject
Conforms toALCoreControllerDelegate
Declared inALAbstractScanPlugin.h
ALAbstractScanPlugin.mm
- - - - - - -
- - - - -

Other Methods

- -
-
- -

– dealloc -

- -
-
- -
- - -
- (void)dealloc
- - -
-
-
- -

– addInfoDelegate: -

- -
-
- -
- - -
- (void)addInfoDelegate:(id<ALInfoDelegate>)infoDelegate
- - -
-
-
- -

– removeInfoDelegate: -

- -
-
- -
- - -
- (void)removeInfoDelegate:(id<ALInfoDelegate>)infoDelegate
- - -
-
-
- -

– start:error: -

- -
-
- -
- - -
-

Start the scanning with an ImageProvider. Anyline will ask the ImageProvider for new frames until -we get a result with high enough confidence.

-
- - - -
- (BOOL)start:(id<ALImageProvider>)imageProvider error:(NSError **)error
- - - -
-

Parameters

- - - - - - - - - - - - -
imageProvider

The ImageProvider implementation

error

An error if something went wrong during startup

-
- - - -
-

Return Value

-

Boolean indicating the success of the start

-
- - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
- -

– stopAndReturnError: -

- -
-
- -
- - -
-

Stops the scanning.

-
- - - -
- (BOOL)stopAndReturnError:(NSError **)error
- - - -
-

Parameters

- - - - - - - -
error

An error if something went wrong during startup

-
- - - -
-

Return Value

-

Boolean indicating the success of the start

-
- - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
- -

– isRunning -

- -
-
- -
- - -
-

The isRunning boolean indicates if a Anyline process is started.

-
- - - -
- (BOOL)isRunning
- - - - - -
-

Return Value

-

Boolean indicating if Anyline is running

-
- - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
- -

– delayedScanTimeFulfilled -

- -
-
- -
- - -
-

The delayedScanTimeFulfilled indicates if the configured delayStartScanTime has been fulfilled. -No result will be returned unless this method returns true.

-
- - - -
- (BOOL)delayedScanTimeFulfilled
- - - - - -
-

Return Value

-

Boolean indicating if the delayStartScanTime has been fulfilled.

-
- - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
- -

– setCurrentScanStartTime -

- -
-
- -
- - -
-

Will set the current timestamp for the delayedScantimeFulfilled check

-
- - - -
- (void)setCurrentScanStartTime
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
- -

– setCurrentScanStartTimeInvalid -

- -
-
- -
- - -
- (void)setCurrentScanStartTimeInvalid
- - -
-
-
- -

– createModuleErrorWithCode:message: -

- -
-
- -
- - -
- (NSError *)createModuleErrorWithCode:(NSInteger)errorCode message:(NSString *)message
- - -
-
-
- -

– anylineCoreController:didFinishWithOutput: -

- -
-
- -
- - - - -
- (void)anylineCoreController:(ALCoreController *)coreController didFinishWithOutput:(id)object
- - - - - - - - - - - - - - - -
-

Declared In

-

ALCoreController.h

-
- - -
-
-
- -

– anylineCoreController:reportsVariable:value: -

- -
-
- -
- - -
-

Tells the delegate a specified intermediate result. Which intermediate results are reported -can be specified in the .alc command file with the REPORT function.

-
- - - -
- (void)anylineCoreController:(ALCoreController *)anylineController reportsVariable:(NSString *)variableName value:(id)value
- - - -
-

Parameters

- - - - - - - - - - - - -
variableName

The variable name in the .alc file which should be reported.

value

The value of the reported variable.

-
- - - - - - - -
-

Discussion

-

This method is optional. It provides intermediate results, therefore Anyline did not completed the -task yet.

-
- - - - - - - -
-

Declared In

-

ALCoreController.h

-
- - -
-
-
- -

– anylineCoreController:didAbortRun: -

- -
-
- -
- - -
-

Tells the delegate that the processing has not completed successfully. Possible reason would be -for example that the display or paper frame could not be found.

-
- - - -
- (void)anylineCoreController:(ALCoreController *)anylineController didAbortRun:(NSError *)reason
- - - -
-

Parameters

- - - - - - - -
reason

A NSError object with ALErrorDomain and an appropriate status.

-
- - - - - - - - - - - - - -
-

Declared In

-

ALCoreController.h

-
- - -
-
-
- -

– setAssetController:error: -

- -
-
- -
- - -
-

An ALAssetController supplied to the plugin by ALAssetUpdateManager

-
- - - -
- (void)setAssetController:(ALAssetController *_Nonnull)assetController error:(NSError *_Nullable *_Nullable)error
- - - -
-

Parameters

- - - - - - - - - - - - -
assetController

An ALAssetController supplied to the plugin by ALAssetUpdateManager

error

An NSError passed by reference

-
- - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.mm

-
- - -
-
-
- -

– assetPath -

- -
-
- -
- - -
-

If an active assetController matching the current plugin can be found, its asset -path can be used to provide the source of the plugin resources. NOTE: If a subclass -uses a config specifying a custom file path for assets, this path should be used -instead.

-
- - - -
- (NSString *)assetPath
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.mm

-
- - -
-
-
- -

– modelKey -

- -
-
- -
- - -
- (NSString *)modelKey
- - -
-
-
- -

– addStartVariableWithName:value: -

- -
-
- -
- - -
- (void)addStartVariableWithName:(NSString *)name value:(NSString *)value
- - -
-
-
-
- - - -

Other Methods

- -
-
- -

  infoDelegates -

- -
-
- -
- - -
@property (nonatomic, strong, readonly) NSPointerArray<ALInfoDelegate> *infoDelegates
- - -
-
-
- -

  pluginID -

- -
-
- -
- - -
-

The pluginID is useful if there are multiple plugins running at the same time

-
- - - -
@property (nullable, nonatomic, strong) NSString *pluginID
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
- -

  imageProvider -

- -
-
- -
- - -
-

The ImageProvider implementation takes care of getting new images in the SDK for processing

-
- - - -
@property (nullable, nonatomic, weak) id<ALImageProvider> imageProvider
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
- -

  delayStartScanTime -

- -
-
- -
- - -
@property (nonatomic) int delayStartScanTime
- - -
-
-
- -

– assetController -

- -
-
- -
- - -
- (ALAssetController *_Nullable)assetController
- - -
-
-
- -

  confidence -

- -
-
- -
- - -
@property (nonatomic, assign) NSInteger confidence
- - -
-
-
- -

  scanImage -

- -
-
- -
- - -
@property (nullable, nonatomic, strong, readonly) ALImage *scanImage
- - -
-
-
- -

  coreController -

- -
-
- -
- - -
@property (nullable, nonatomic, strong) ALCoreController *coreController
- - -
-
-
- -

  productName -

- -
-
- -
- - -
@property (nullable, nonatomic) NSString *productName
- - -
-
-
- -

  assetController -

- -
-
- -
- - -
@property (nullable, nonatomic, strong) ALAssetController *assetController
- - -
-
-
- -

  resourceSubdirectory -

- -
-
- -
- - -
-

Plugin-specific subdirectory containing the resources for said plugin. Needs to -be set when a ALScanPlugin subclass is initialized.

-
- - - -
@property (nullable, nonatomic, copy) NSString *resourceSubdirectory
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
-
- - - -

Extension Methods

- -
-
- -

  scanStartTime -

- -
-
- -
- - -
@property (nonatomic, strong) NSDate *scanStartTime
- - -
-
-
- -

  assetPath -

- -
-
- -
- - -
@property NSString *assetPath
- - -
-
-
- -

  startVariables -

- -
-
- -
- - -
@property NSDictionary *startVariables
- - -
-
-
- -

  assetService -

- -
-
- -
- - -
@property al : : AssetService *assetService
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Classes/ALAbstractScanViewPlugin.html b/Documentation/html/Classes/ALAbstractScanViewPlugin.html deleted file mode 100644 index 4fef98d58..000000000 --- a/Documentation/html/Classes/ALAbstractScanViewPlugin.html +++ /dev/null @@ -1,1425 +0,0 @@ - - - - - - ALAbstractScanViewPlugin Class Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

ALAbstractScanViewPlugin Class Reference

- - -
- - - - - - - - - - -
Inherits fromUIView
Conforms toALInfoDelegate
Declared inALAbstractScanViewPlugin.h
ALAbstractScanViewPlugin.mm
- - - - - - -
- - - - -

Other Methods

- -
-
- -

– initWithFrame: -

- -
-
- -
- - -
- (instancetype)initWithFrame:(CGRect)frame
- - -
-
-
- -

– initWithCoder: -

- -
-
- -
- - -
- (instancetype)initWithCoder:(NSCoder *)aDecoder
- - -
-
-
- -

– customInit -

- -
-
- -
- - -
- (void)customInit
- - -
-
-
- -

+ readConfigForComposite:fromConfigDict:delegate:error: -

- -
-
- -
- - -
+ (void)readConfigForComposite:(ALAbstractScanViewPluginComposite *)compositePlugin fromConfigDict:(NSDictionary *_Nonnull)configDict delegate:(id _Nonnull)delegate error:(NSError *_Nullable *_Nullable)error
- - -
-
-
- -

+ serialScanViewPluginForConfigDict:delegate:error: -

- -
-
- -
- - -
+ (_Nullable instancetype)serialScanViewPluginForConfigDict:(NSDictionary *_Nonnull)compositeConfig delegate:(id _Nonnull)delegate error:(NSError *_Nullable *_Nullable)error
- - -
-
-
- -

+ parallelScanViewPluginForConfigDict:delegate:error: -

- -
-
- -
- - -
+ (_Nullable instancetype)parallelScanViewPluginForConfigDict:(NSDictionary *_Nonnull)compositeConfig delegate:(id _Nonnull)delegate error:(NSError *_Nullable *_Nullable)error
- - -
-
-
- -

+ singleScanViewPluginForConfigDict:delegate:error: -

- -
-
- -
- - -
+ (instancetype _Nullable)singleScanViewPluginForConfigDict:(NSDictionary *_Nonnull)configDict delegate:(id _Nonnull)delegate error:(NSError *__autoreleasing _Nullable *_Nullable)error
- - -
-
-
- -

+ scanViewPluginForConfigDict:delegate:error: -

- -
-
- -
- - -
+ (_Nullable instancetype)scanViewPluginForConfigDict:(NSDictionary *_Nonnull)configDict delegate:(id _Nonnull)delegate error:(NSError *_Nullable *_Nullable)error
- - -
-
-
- -

– layoutSubviews -

- -
-
- -
- - -
- (void)layoutSubviews
- - -
-
-
- -

– dealloc -

- -
-
- -
- - -
- (void)dealloc
- - -
-
-
- -

– pluginIDWithCutout -

- -
-
- -
- - -
- (NSString *)pluginIDWithCutout
- - -
-
-
- -

– setScanView: -

- -
-
- -
- - -
- (void)setScanView:(ALScanView *)scanView
- - -
-
-
- -

– setScanViewPluginConfig: -

- -
-
- -
- - -
- (void)setScanViewPluginConfig:(ALScanViewPluginConfig *)scanViewPluginConfig
- - -
-
-
- -

– scanViewPluginConfig -

- -
-
- -
- - -
-

The UI Configuration for the scanning UI

-
- - - -
- (ALScanViewPluginConfig *)scanViewPluginConfig
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

– scanViewPluginConfigs -

- -
-
- -
- - -
-

A dictionary mapping plugin IDs to configs. For a simple scan view plugin, this will just be this plugin’s pluginID and scanViewPluginConfig. For composite scan view plugins, this will be the plugin IDs and configs for all the child plugins, and not the composite itself.

-
- - - -
- (NSDictionary<NSString*,ALScanViewPluginConfig*> *)scanViewPluginConfigs
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

– getCropRect -

- -
-
- -
- - -
- (CGRect)getCropRect
- - -
-
-
- -

– orientationDidChange: -

- -
-
- -
- - -
- (void)orientationDidChange:(NSNotification *)notification
- - -
-
-
- -

– startAndReturnError: -

- -
-
- -
- - -
-

Starts the Anyline processing.

-
- - - -
- (BOOL)startAndReturnError:(NSError *_Nullable *_Nullable)error
- - - -
-

Parameters

- - - - - - - -
error

An error if something goes wrong during the startup

-
- - - -
-

Return Value

-

Boolean indicating the success of the start

-
- - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

– stopAndReturnError: -

- -
-
- -
- - -
-

Stops the Anyline processing

-
- - - -
- (BOOL)stopAndReturnError:(NSError *_Nullable *_Nullable)error
- - - -
-

Parameters

- - - - - - - -
error

An error if something goes wrong while stopping

-
- - - -
-

Return Value

-

Boolean indicating whether it stopped successfully

-
- - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

– observeValueForKeyPath:ofObject:change:context: -

- -
-
- -
- - -
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- - -
-
-
- -

– anylineScanPlugin:reportInfo: -

- -
-
- -
- - -
-

Called with interesting values that arise during processing.

- - -

-Some possibly reported values: -

    -
  • $brightness - the brightness of the center region of the cutout as a float value
  • -
  • $confidence - the confidence, an Integer value between 0 and 100
  • -
  • $thresholdedImage - the current image transformed into black and white (the base image used for OCR)
  • -
-

- -
- - - -
- (void)anylineScanPlugin:(ALAbstractScanPlugin *_Nonnull)anylineScanPlugin reportInfo:(ALScanInfo *_Nonnull)info
- - - -
-

Parameters

- - - - - - - - - - - - -
anylineScanPlugin

The ALAbstractScanPlugin

info

An object containing the variable name and value

-
- - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanPlugin.h

-
- - -
-
-
- -

– displayErrorToUser:completion: -

- -
-
- -
- - -
- (void)displayErrorToUser:(NSError **)retError completion:(void ( ^ __nullable ) ( void ))completion
- - -
-
-
- -

– getJsonForNativeBarcodeIsEnabled: -

- -
-
- -
- - -
- (NSString *)getJsonForNativeBarcodeIsEnabled:(BOOL)enabled
- - -
-
-
- -

– convertContours: -

- -
-
- -
- - -
- (NSArray *)convertContours:(ALContours *)contoursValue
- - -
-
-
- -

– convertSquare: -

- -
-
- -
- - -
- (ALSquare *)convertSquare:(ALSquare *)unconvertedSquare
- - -
-
-
- -

– convertCGRect: -

- -
-
- -
- - -
- (ALSquare *)convertCGRect:(NSValue *)concreteValue
- - -
-
-
- -

– convertJSONContour: -

- -
-
- -
- - -
- (ALSquare *)convertJSONContour:(NSArray<NSNumber*> *)contour
- - -
-
-
- -

– convertVisualization: -

- -
-
- -
- - -
- (NSDictionary *)convertVisualization:(NSString *)visualiJSON
- - -
-
-
- -

– convertTextRectFromVisualization: -

- -
-
- -
- - -
- (ALSquare *)convertTextRectFromVisualization:(NSString *)visualiJSON
- - -
-
-
- -

– convertContoursFromVisualization: -

- -
-
- -
- - -
- (NSMutableArray<ALSquare*> *)convertContoursFromVisualization:(NSString *)visualiJSON
- - -
-
-
- -

– updateSubviewsWithConfiguration: -

- -
-
- -
- - -
- (void)updateSubviewsWithConfiguration:(ALScanViewPluginConfig *)newScanViewPluginConfig
- - -
-
-
- -

– updateSubviewsWithConfiguration:isHardReset:isLayoutSubViews: -

- -
-
- -
- - -
- (void)updateSubviewsWithConfiguration:(ALScanViewPluginConfig *)newScanViewPluginConfig isHardReset:(BOOL)isHardReset isLayoutSubViews:(BOOL)layoutSubViews
- - -
-
-
- -

– resetCamera:cutoutRect: -

- -
-
- -
- - -
- (void)resetCamera:(ALScanViewPluginConfig *)config cutoutRect:(CGRect)cutoutRect
- - -
-
-
- -

– triggerScannedFeedback -

- -
-
- -
- - -
- (void)triggerScannedFeedback
- - -
-
-
- -

– blink -

- -
-
- -
- - -
- (void)blink
- - -
-
-
- -

– startListeningForMotionWithThreshold:delegate: -

- -
-
- -
- - -
- (void)startListeningForMotionWithThreshold:(CGFloat)threshold delegate:(id)delegate
- - -
-
-
- -

– stopListeningForMotion -

- -
-
- -
- - -
-

Stop listening for device motion.

-
- - - -
- (void)stopListeningForMotion
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

– updateCutoutRect:forPluginID: -

- -
-
- -
- - -
- (void)updateCutoutRect:(CGRect)rect forPluginID:(NSString *)pluginID
- - -
-
-
- -

– addScanViewPluginDelegate: -

- -
-
- -
- - -
- (void)addScanViewPluginDelegate:(id<ALScanViewPluginDelegate>)scanViewPluginDelegate
- - -
-
-
- -

– removeScanViewPluginDelegate: -

- -
-
- -
- - -
- (void)removeScanViewPluginDelegate:(id<ALScanViewPluginDelegate>)scanViewPluginDelegate
- - -
-
-
-
- - - -

Other Methods

- -
-
- -

  scanViewPluginDelegates -

- -
-
- -
- - -
@property (nonatomic, strong, readonly) NSPointerArray<ALScanViewPluginDelegate> *scanViewPluginDelegates
- - -
-
-
- -

  sampleBufferImageProvider -

- -
-
- -
- - -
-

The SampleBufferImageProvider implements ALImageProvider and AnylineVideoDataSampleBufferDelegate -and prepares the frame for Anyline processing

-
- - - -
@property (nullable, nonatomic, strong) ALSampleBufferImageProvider *sampleBufferImageProvider
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

  scanView -

- -
-
- -
- - -
@property (nonatomic, weak) ALScanView *scanView
- - -
-
-
- -

  cutoutRect -

- -
-
- -
- - -
-

The position of the Cutout in the View

-
- - - -
@property (assign, nonatomic) CGRect cutoutRect
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

  pluginID -

- -
-
- -
- - -
-

The pluginID is useful if there are multiple plugins running at the same time

-
- - - -
@property (nullable, nonatomic, readonly) NSString *pluginID
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

  isOptional -

- -
-
- -
- - -
-

Used when a indicating a child plugin of a composite scan view plugin is allowed to be -skipped depending on rules determined by the parent plugin. Has no significance otherwise.

-
- - - -
@property (nonatomic, assign) BOOL isOptional
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAbstractScanViewPlugin.h

-
- - -
-
-
- -

  outline -

- -
-
- -
- - -
@property (nullable, nonatomic, strong) ALSquare *outline
- - -
-
-
- -

  scanImage -

- -
-
- -
- - -
@property (nullable, nonatomic, strong) ALImage *scanImage
- - -
-
-
- -

  scale -

- -
-
- -
- - -
@property (nonatomic, assign) CGFloat scale
- - -
-
-
-
- - - -

Extension Methods

- -
-
- -

  beepSound -

- -
-
- -
- - -
@property (nonatomic, assign) SystemSoundID beepSound
- - -
-
-
- -

  motionDetector -

- -
-
- -
- - -
@property (nonatomic, strong) ALMotionDetector *motionDetector
- - -
-
-
- -

  oldFrame -

- -
-
- -
- - -
@property (nonatomic) CGRect oldFrame
- - -
-
-
- -

  cropRect -

- -
-
- -
- - -
@property (nonatomic, assign) CGRect cropRect
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Classes/ALAbstractScanViewPluginComposite.html b/Documentation/html/Classes/ALAbstractScanViewPluginComposite.html deleted file mode 100644 index 6abe18551..000000000 --- a/Documentation/html/Classes/ALAbstractScanViewPluginComposite.html +++ /dev/null @@ -1,394 +0,0 @@ - - - - - - ALAbstractScanViewPluginComposite Class Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

ALAbstractScanViewPluginComposite Class Reference

- - -
- - - - - - - -
Inherits fromALAbstractScanViewPlugin : UIView
Declared inALAbstractScanViewPluginComposite.h
- - - - - - -
- - - - -

Other Methods

- -
-
- -

  isRunning -

- -
-
- -
- - -
@property BOOL isRunning
- - -
-
-
- -

  childPlugins -

- -
-
- -
- - -
@property (nonatomic, readonly) NSDictionary<NSString*ALAbstractScanViewPlugin*> *childPlugins
- - -
-
-
- -

– addPlugin: -

- -
-
- -
- - -
- (void)addPlugin:(ALAbstractScanViewPlugin *_Nonnull)plugin
- - -
-
-
- -

– removePlugin: -

- -
-
- -
- - -
- (void)removePlugin:(NSString *_Nonnull)pluginID
- - -
-
-
- -

– initWithPluginID: -

- -
-
- -
- - -
- (instancetype _Nonnull)initWithPluginID:(NSString *_Nonnull)pluginID
- - -
-
-
- -

– addDelegate: -

- -
-
- -
- - -
- (void)addDelegate:(id<ALCompositeScanPluginDelegate> _Nonnull)delegate
- - -
-
-
- -

– removeDelegate: -

- -
-
- -
- - -
- (void)removeDelegate:(id<ALCompositeScanPluginDelegate> _Nonnull)delegate
- - -
-
-
-
- - - -

Extension Methods

- -
-
- -

– allConfigs -

- -
-
- -
- - -
- (NSDictionary<NSString*,ALScanViewPluginConfig*> *)allConfigs
- - -
-
-
- -

– setCurrentChildScanViewPluginConfig: -

- -
-
- -
- - -
- (void)setCurrentChildScanViewPluginConfig:(ALScanViewPluginConfig *)scanViewPluginConfig
- - -
-
-
- -

– allUnfinishedPluginIDs -

- -
-
- -
- - -
- (NSSet<NSString*> *)allUnfinishedPluginIDs
- - -
-
-
- -

– markPluginDone: -

- -
-
- -
- - -
- (void)markPluginDone:(ALAbstractScanViewPlugin *)plugin
- - -
-
-
- -

– addResult:forPluginID: -

- -
-
- -
- - -
- (void)addResult:(ALScanResult *)result forPluginID:(NSString *)pluginID
- - -
-
-
- -

– isPluginFinished: -

- -
-
- -
- - -
- (BOOL)isPluginFinished:(NSString *)pluginID
- - -
-
-
- -

  componentPlugins -

- -
-
- -
- - -
@property NSMutableArray<ALAbstractScanViewPlugin*> *componentPlugins
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Classes/ALAdaptDataPointAreaBoundingRectsWithoutOutliersOperation.html b/Documentation/html/Classes/ALAdaptDataPointAreaBoundingRectsWithoutOutliersOperation.html deleted file mode 100644 index 4934b0ea1..000000000 --- a/Documentation/html/Classes/ALAdaptDataPointAreaBoundingRectsWithoutOutliersOperation.html +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - ALAdaptDataPointAreaBoundingRectsWithoutOutliersOperation Class Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

ALAdaptDataPointAreaBoundingRectsWithoutOutliersOperation Class Reference

- - -
- - - - -
Declared inALAdaptDataPointAreaBoundingRectsWithoutOutliersOperation.mm
- - - - - - -
- - - - - - -
-
- -

– main -

- -
-
- -
- - -
- (void)main
- - -
-
-
- -

– areaForBoundingRectsLargestInDataPoint2: -

- -
-
- -
- - -
- (CGRect)areaForBoundingRectsLargestInDataPoint2:(NSArray *)boundingRectsInDataPoint
- - -
-
-
- -

– areaForBoundingRectsLargestInDataPoint3: -

- -
-
- -
- - -
- (CGRect)areaForBoundingRectsLargestInDataPoint3:(NSArray *)boundingRectsInDataPoint
- - -
-
-
- -

– medianOfArray: -

- -
-
- -
- - -
- (int)medianOfArray:(NSArray *)array
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Classes/ALAllowedLayouts.html b/Documentation/html/Classes/ALAllowedLayouts.html new file mode 100644 index 000000000..f816e8daa --- /dev/null +++ b/Documentation/html/Classes/ALAllowedLayouts.html @@ -0,0 +1,213 @@ + + + + + + ALAllowedLayouts Class Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

ALAllowedLayouts Class Reference

+ + +
+ + + + + + + +
Inherits fromNSObject
Declared inALPluginConfig.h
+ + + + +
+ +

Overview

+

Specifies the document types to be scanned and optionally further specifies which types +of layout are scanned per type.

+
+ + + + + +
+ + + + + + +
+
+ +

  drivingLicense +

+ +
+
+ +
+ + +
@property (nonatomic, nullable, copy) NSArray<NSString*> *drivingLicense
+ + +
+
+
+ +

  theIDFront +

+ +
+
+ +
+ + +
@property (nonatomic, nullable, copy) NSArray<NSString*> *theIDFront
+ + +
+
+
+ +

  insuranceCard +

+ +
+
+ +
+ + +
@property (nonatomic, nullable, copy) NSArray<NSString*> *insuranceCard
+ + +
+
+
+ +

  mrz +

+ +
+
+ +
+ + +
@property (nonatomic, nullable, copy) NSArray<NSString*> *mrz
+ + +
+
+
+
+ +
+ + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Classes/ALAlphabet.html b/Documentation/html/Classes/ALAlphabet.html new file mode 100644 index 000000000..37898b5eb --- /dev/null +++ b/Documentation/html/Classes/ALAlphabet.html @@ -0,0 +1,234 @@ + + + + + + ALAlphabet Class Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

ALAlphabet Class Reference

+ + +
+ + + + + + + +
Inherits fromNSObject
Declared inALPluginConfig.h
+ + + + +
+ +

Overview

+

Sets a specific character set. Per default, only latin characters are processed.

+
+ + + + + +
+ + + + + + +
+
+ +

  value +

+ +
+
+ +
+ + +
@property (nonatomic, readonly, copy) NSString *value
+ + +
+
+
+ +

+ withValue: +

+ +
+
+ +
+ + +
+ (instancetype _Nullable)withValue:(NSString *)value
+ + +
+
+
+ +

+ arabic +

+ +
+
+ +
+ + +
+ (ALAlphabet *)arabic
+ + +
+
+
+ +

+ cyrillic +

+ +
+
+ +
+ + +
+ (ALAlphabet *)cyrillic
+ + +
+
+
+ +

+ latin +

+ +
+
+ +
+ + +
+ (ALAlphabet *)latin
+ + +
+
+
+
+ +
+ + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Classes/ALArabic.html b/Documentation/html/Classes/ALArabic.html new file mode 100644 index 000000000..a4b8c122e --- /dev/null +++ b/Documentation/html/Classes/ALArabic.html @@ -0,0 +1,226 @@ + + + + + + ALArabic Class Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

ALArabic Class Reference

+ + +
+ + + + + + + +
Inherits fromNSObject
Declared inALPluginResult.h
+ + + + +
+ +

Overview

+

The text parameters

+
+ + + + + +
+ + + + + + +
+
+ +

  confidence +

+ +
+
+ +
+ + +
+

The confidence value

+
+ + + +
@property (nonatomic, assign) NSInteger confidence
+ + + + + + + + + + + + + + + +
+

Declared In

+

ALPluginResult.h

+
+ + +
+
+
+ +

  text +

+ +
+
+ +
+ + +
+

The text value

+
+ + + +
@property (nonatomic, copy) NSString *text
+ + + + + + + + + + + + + + + +
+

Declared In

+

ALPluginResult.h

+
+ + +
+
+
+
+ +
+ + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Classes/ALArea.html b/Documentation/html/Classes/ALArea.html new file mode 100644 index 000000000..d0724149d --- /dev/null +++ b/Documentation/html/Classes/ALArea.html @@ -0,0 +1,1152 @@ + + + + + + ALArea Class Reference + + + + + + +
+
+ +

+ Anyline SDK +

+ +

+ Anyline GmbH +

+ +
+
+ + + +
+
+
+
+

ALArea Class Reference

+ + +
+ + + + + + + +
Inherits fromNSObject
Declared inALPluginResult.h
+ + + + +
+ +

Overview

+

The area information

+
+ + + + + +
+ + + + + + +
+
+ +

  value +

+ +
+
+ +
+ + +
@property (nonatomic, readonly, copy) NSString *value
+ + +
+
+
+ +

+ withValue: +

+ +
+
+ +
+ + +
+ (instancetype _Nullable)withValue:(NSString *)value
+ + +
+
+
+ +

+ alabama +

+ +
+
+ +
+ + +
+ (ALArea *)alabama
+ + +
+
+
+ +

+ alaska +

+ +
+
+ +
+ + +
+ (ALArea *)alaska
+ + +
+
+
+ +

+ americanSamoa +

+ +
+
+ +
+ + +
+ (ALArea *)americanSamoa
+ + +
+
+
+ +

+ arizona +

+ +
+
+ +
+ + +
+ (ALArea *)arizona
+ + +
+
+
+ +

+ arkansas +

+ +
+
+ +
+ + +
+ (ALArea *)arkansas
+ + +
+
+
+ +

+ california +

+ +
+
+ +
+ + +
+ (ALArea *)california
+ + +
+
+
+ +

+ colorado +

+ +
+
+ +
+ + +
+ (ALArea *)colorado
+ + +
+
+
+ +

+ connecticut +

+ +
+
+ +
+ + +
+ (ALArea *)connecticut
+ + +
+
+
+ +

+ delaware +

+ +
+
+ +
+ + +
+ (ALArea *)delaware
+ + +
+
+
+ +

+ districtOfColumbia +

+ +
+
+ +
+ + +
+ (ALArea *)districtOfColumbia
+ + +
+
+
+ +

+ florida +

+ +
+
+ +
+ + +
+ (ALArea *)florida
+ + +
+
+
+ +

+ georgia +

+ +
+
+ +
+ + +
+ (ALArea *)georgia
+ + +
+
+
+ +

+ guam +

+ +
+
+ +
+ + +
+ (ALArea *)guam
+ + +
+
+
+ +

+ hawaii +

+ +
+
+ +
+ + +
+ (ALArea *)hawaii
+ + +
+
+
+ +

+ idaho +

+ +
+
+ +
+ + +
+ (ALArea *)idaho
+ + +
+
+
+ +

+ illinois +

+ +
+
+ +
+ + +
+ (ALArea *)illinois
+ + +
+
+
+ +

+ indiana +

+ +
+
+ +
+ + +
+ (ALArea *)indiana
+ + +
+
+
+ +

+ iowa +

+ +
+
+ +
+ + +
+ (ALArea *)iowa
+ + +
+
+
+ +

+ kansas +

+ +
+
+ +
+ + +
+ (ALArea *)kansas
+ + +
+
+
+ +

+ kentucky +

+ +
+
+ +
+ + +
+ (ALArea *)kentucky
+ + +
+
+
+ +

+ louisiana +

+ +
+
+ +
+ + +
+ (ALArea *)louisiana
+ + +
+
+
+ +

+ maine +

+ +
+
+ +
+ + +
+ (ALArea *)maine
+ + +
+
+
+ +

+ maryland +

+ +
+
+ +
+ + +
+ (ALArea *)maryland
+ + +
+
+
+ +

+ massachusetts +

+ +
+
+ +
+ + +
+ (ALArea *)massachusetts
+ + +
+
+
+ +

+ michigan +

+ +
+
+ +
+ + +
+ (ALArea *)michigan
+ + +
+
+
+ +

+ minnesota +

+ +
+
+ +
+ + +
+ (ALArea *)minnesota
+ + +
+
+
+ +

+ mississippi +

+ +
+
+ +
+ + +
+ (ALArea *)mississippi
+ + +
+
+
+ +

+ missouri +

+ +
+
+ +
+ + +
+ (ALArea *)missouri
+ + +
+
+
+ +

+ montana +

+ +
+
+ +
+ + +
+ (ALArea *)montana
+ + +
+
+
+ +

+ nebraska +

+ +
+
+ +
+ + +
+ (ALArea *)nebraska
+ + +
+
+
+ +

+ nevada +

+ +
+
+ +
+ + +
+ (ALArea *)nevada
+ + +
+
+
+ +

+ newHampshire +

+ +
+
+ +
+ + +
+ (ALArea *)newHampshire
+ + +
+
+
+ +

+ newJersey +

+ +
+
+ +
+ + +
+ (ALArea *)newJersey
+ + +
+
+
+ +

+ newMexico +

+ +
+
+ +
+ + +
+ (ALArea *)newMexico
+ + +
+
+
+ +

+ newYork +

+ +
+
+ +
+ + +
+ (ALArea *)newYork
+ + +
+
+
+ +

+ northCarolina +

+ +
+
+ +
+ + +
+ (ALArea *)northCarolina
+ + +
+
+
+ +

+ northDakota +

+ +
+
+ +
+ + +
+ (ALArea *)northDakota
+ + +
+
+
+ +

+ ohio +

+ +
+
+ +
+ + +
+ (ALArea *)ohio
+ + +
+
+
+ +

+ oklahoma +

+ +
+
+ +
+ + +
+ (ALArea *)oklahoma
+ + +
+
+
+ +

+ oregon +

+ +
+
+ +
+ + +
+ (ALArea *)oregon
+ + +
+
+
+ +

+ pennsylvania +

+ +
+
+ +
+ + +
+ (ALArea *)pennsylvania
+ + +
+
+
+ +

+ puertoRico +

+ +
+
+ +
+ + +
+ (ALArea *)puertoRico
+ + +
+
+
+ +

+ rhodeIsland +

+ +
+
+ +
+ + +
+ (ALArea *)rhodeIsland
+ + +
+
+
+ +

+ southCarolina +

+ +
+
+ +
+ + +
+ (ALArea *)southCarolina
+ + +
+
+
+ +

+ southDakota +

+ +
+
+ +
+ + +
+ (ALArea *)southDakota
+ + +
+
+
+ +

+ tennessee +

+ +
+
+ +
+ + +
+ (ALArea *)tennessee
+ + +
+
+
+ +

+ texas +

+ +
+
+ +
+ + +
+ (ALArea *)texas
+ + +
+
+
+ +

+ utah +

+ +
+
+ +
+ + +
+ (ALArea *)utah
+ + +
+
+
+ +

+ vermont +

+ +
+
+ +
+ + +
+ (ALArea *)vermont
+ + +
+
+
+ +

+ virginia +

+ +
+
+ +
+ + +
+ (ALArea *)virginia
+ + +
+
+
+ +

+ washington +

+ +
+
+ +
+ + +
+ (ALArea *)washington
+ + +
+
+
+ +

+ westVirginia +

+ +
+
+ +
+ + +
+ (ALArea *)westVirginia
+ + +
+
+
+ +

+ wisconsin +

+ +
+
+ +
+ + +
+ (ALArea *)wisconsin
+ + +
+
+
+ +

+ wyoming +

+ +
+
+ +
+ + +
+ (ALArea *)wyoming
+ + +
+
+
+
+ +
+ + + + + + +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/Documentation/html/Classes/ALAssetContext.html b/Documentation/html/Classes/ALAssetContext.html index e40b96122..2facd4f19 100644 --- a/Documentation/html/Classes/ALAssetContext.html +++ b/Documentation/html/Classes/ALAssetContext.html @@ -43,6 +43,8 @@

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-

ALAssetController Class Reference

- - -
- - - - - - - -
Inherits fromNSObject
Declared inALAssetController.h
ALAssetController.mm
- - - - - - -
- - - - -

Other Methods

- -
-
- -

– dealloc -

- -
-
- -
- - -
- (void)dealloc
- - -
-
-
- -

– initWithContext:delegate: -

- -
-
- -
- - -
- (instancetype)initWithContext:(ALAssetContext *)context delegate:(NSObject<ALAssetDelegate> *)delegate
- - -
-
-
- -

– initWithContext: -

- -
-
- -
- - -
- (instancetype)initWithContext:(ALAssetContext *)context
- - -
-
-
- -

– setAssetContext: -

- -
-
- -
- - -
- (void)setAssetContext:(ALAssetContext *)assetContext
- - -
-
-
- -

– setAssetDelegate: -

- -
-
- -
- - -
- (void)setAssetDelegate:(NSObject<ALAssetDelegate> *)assetDelegate
- - -
-
-
- -

– setupAssetUpdateWithContext:delegate: -

- -
-
- -
- - -
-

Sets up the AssetController with a context to the Trainer project and a delegate to handle -callbacks. After this method is called, the AssetController is considered ‘active’.

-
- - - -
- (void)setupAssetUpdateWithContext:(nonnull ALAssetContext *)context delegate:(nullable NSObject<ALAssetDelegate> *)delegate
- - - -
-

Parameters

- - - - - - - - - - - - -
context

ALAssetContext

delegate

ALAssetDelegate

-
- - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.mm

-
- - -
-
-
- -

– resetAssetUpdate -

- -
-
- -
- - -
-

Resets the asset update functionality. After this is called, -{@link #setupAssetUpdate(AssetContext, AssetDelegate)} must be called again

-
- - - -
- (void)resetAssetUpdate
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.mm

-
- - -
-
-
- -

– path -

- -
-
- -
- - -
- (NSString *)path
- - -
-
-
- -

– backupPath -

- -
-
- -
- - -
- (NSString *)backupPath
- - -
-
-
- -

– areLocalAssetsAvailable -

- -
-
- -
- - -
-

Whether any assets have been downloaded. If this returns NO, you should either check -for updates and download the updates, or not use an asset context.

-
- - - -
- (BOOL)areLocalAssetsAvailable
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.h

-
- - -
-
-
- -

– deleteLocalAssets -

- -
-
- -
- - -
-

Deletes any assets that have been downloaded. After doing this, you should either check -for updates and download the updates, or not use an asset context.

-
- - - -
- (void)deleteLocalAssets
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.h

-
- - -
-
-
- -

– assetFiles -

- -
-
- -
- - -
- (NSArray<NSString*> *)assetFiles
- - -
-
-
- -

– projectID -

- -
-
- -
- - -
-

Gets the project ID.

-
- - - -
- (NSString *)projectID
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.mm

-
- - -
-
-
- -

– assetID -

- -
-
- -
- - -
-

-Gets the asset ID. -

-
- - - -
- (NSString *)assetID
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.mm

-
- - -
-
-
- -

– isActive -

- -
-
- -
- - -
-

-Returns true if the AssetController if ‘SetupAssetUpdate’ was called. -Returns false if ‘ResetAssetUpdate’ was called or ‘SetupAssetUpdate’ has not been called. -

-
- - - -
- (BOOL)isActive
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.mm

-
- - -
-
-
- -

– checkForUpdates -

- -
-
- -
- - -
-

Checks whether asset updates are available

-
- - - -
- (void)checkForUpdates
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.mm

-
- - -
-
-
- -

– updateAssets -

- -
-
- -
- - -
-

Updates the assets, only after {@link #checkForUpdates()} was successfully called

-
- - - -
- (void)updateAssets
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.mm

-
- - -
-
-
- -

– cancel -

- -
-
- -
- - -
-

Cancels the asset update process.

-
- - - -
- (void)cancel
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.h

-
- - -
-
-
- -

– isAssetUpdateCanceled -

- -
-
- -
- - -
-

Returns true if ‘cancelUpdate’ was called.

-
- - - -
- (BOOL)isAssetUpdateCanceled
- - - - - - - - - - - - - - - -
-

Declared In

-

ALAssetController.h

-
- - -
-
-
- -

– throwIfNotActive -

- -
-
- -
- - -
- (void)throwIfNotActive
- - -
-
-
- -

– reportingValues -

- -
-
- -
- - -
- (NSString *)reportingValues
- - -
-
-
- -

– createBackup -

- -
-
- -
- - -
- (void)createBackup
- - -
-
-
- -

– restoreFromBackup -

- -
-
- -
- - -
- (void)restoreFromBackup
- - -
-
-
- -

– deleteBackup -

- -
-
- -
- - -
- (void)deleteBackup
- - -
-
-
-
- - - -

Other Methods

- -
-
- -

  assetContext -

- -
-
- -
- - -
@property (nonatomic) ALAssetContext *assetContext
- - -
-
-
-
- - - -

Extension Methods

- -
-
- -

  assetService -

- -
-
- -
- - -
@property (nonatomic) al : : AssetService *assetService
- - -
-
-
- -

  assetDelegate -

- -
-
- -
- - -
@property (nonatomic, strong) NSObject<ALAssetDelegate> *assetDelegate
- - -
-
-
- -

  wrappedDelegate -

- -
-
- -
- - -
@property al : : AssetDelegateWrapper *wrappedDelegate
- - -
-
-
- -

  isCanceled -

- -
-
- -
- - -
@property (nonatomic, assign) BOOL isCanceled
- - -
-
-
- -

  assetServiceQueue -

- -
-
- -
- - -
@property (nullable, nonatomic, strong) dispatch_queue_t assetServiceQueue
- - -
-
-
- -

  fileOpsSerialQueue -

- -
-
- -
- - -
@property (nullable, nonatomic, strong) dispatch_queue_t fileOpsSerialQueue
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Classes/ALAssetControllerFactory.html b/Documentation/html/Classes/ALAssetControllerFactory.html deleted file mode 100644 index a21f9fc45..000000000 --- a/Documentation/html/Classes/ALAssetControllerFactory.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - ALAssetControllerFactory Class Reference - - - - - - -
-
- -

- Anyline SDK -

- -

- Anyline GmbH -

- -
-
- - - -
-
-
-
-

ALAssetControllerFactory Class Reference

- - -
- - - - - - - -
Inherits fromNSObject
Declared inALAssetController.h
ALAssetController.mm
- - - - - - -
- - - - - - -
-
- -

– makeControllerWithAssetContext:assetDelegate: -

- -
-
- -
- - -
- (ALAssetController *)makeControllerWithAssetContext:(ALAssetContext *)assetContext assetDelegate:(id<ALAssetDelegate>)assetDelegate
- - -
-
-
-
- -
- - - - - - -
- - -
-
-
- - - - \ No newline at end of file diff --git a/Documentation/html/Classes/ALAssetUpdateManager.html b/Documentation/html/Classes/ALAssetUpdateManager.html index 0e6d0792a..10cc0163f 100644 --- a/Documentation/html/Classes/ALAssetUpdateManager.html +++ b/Documentation/html/Classes/ALAssetUpdateManager.html @@ -43,6 +43,8 @@

+ + @@ -116,6 +118,14 @@

ALAssetUpdateTask Class Reference

+ +
+ +

Overview

+

An object managing the update of an asset

+
+ + @@ -137,10 +147,35 @@

 &
+ +
+

The asset update delegate

+
+ +
@property (nonatomic, weak) id<ALAssetUpdateDelegate> assetUpdateDelegate
+ + + + + + + + + + + + + +
+

Declared In

+

ALAssetUpdateTask.h

+
+ +
@@ -185,10 +270,35 @@

  id + +
+

ID string of the update task

+
+ +
@property (nonatomic, readonly) NSString *id
+ + + + + + + + + + + + + +
+

Declared In

+

ALAssetUpdateTask.h

+
+ +

@@ -334,7 +711,7 @@

–