Skip to content

Commit

Permalink
Added Anyline 15.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Philipp Müller committed Nov 7, 2019
1 parent ad11306 commit df3fc97
Show file tree
Hide file tree
Showing 212 changed files with 1,550 additions and 590 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#import "ALEnergyBaseViewController.h"

#import "ALNFCScanViewController.h"

NSString * const reuseIdentifier = @"gridCell";
NSString * const viewControllerIdentifier = @"gridViewController";

Expand Down Expand Up @@ -71,6 +73,7 @@ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
label.text = [self.exampleManager titleForSectionIndex:indexPath.section];
label.textColor = [UIColor blackColor];
label.textAlignment = NSTextAlignmentLeft;
//todo: use dynamic type sizes (e.g. [UIFont preferredFontForTextStyle:UIFontTextStyleTitle2] or scaledFontForFont:)
label.font = [UIFont AL_proximaSemiboldWithSize:22];
label.center = CGPointMake(label.center.x, header.center.y);
[header addSubview:label];
Expand Down Expand Up @@ -117,13 +120,39 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
return cell;
}

- (void)showViewController:(ALExample *)example {
ALBaseScanViewController *vc = [[example.viewController alloc] init];
vc.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:vc animated:YES];
}

//todo: share this code with the method in ALBaseScanViewController (in a category on UIViewController?)
- (void)showAlertWithTitle:(NSString *)title message:(NSString *)message {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:dismissAction];
[self.navigationController presentViewController:alertController animated:YES completion:nil];
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
ALExample *example = [self.exampleManager exampleForIndexPath:indexPath];

if ([example.viewController isSubclassOfClass:[ALBaseScanViewController class]] || [example.viewController isSubclassOfClass:[ALEnergyBaseViewController class]]) {
ALBaseScanViewController *vc = [[example.viewController alloc] init];
vc.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:vc animated:YES];
if ([[example viewController] isSubclassOfClass:[ALNFCScanViewController class]]) {
if (@available(iOS 13.0, *)) {
if ([ALNFCDetector readingAvailable]) {
[self showViewController:example];
} else {
[self showAlertWithTitle:@"NFC Not Supported" message:@"NFC passport reading is not supported on this device."];
}
} else {
[self showAlertWithTitle:@"NFC Not Supported" message:@"NFC passport reading is only supported on iOS 13 and later."];
}
} else {
[self showViewController:example];
}
} else if (example.viewController) {
if ([example.viewController isSubclassOfClass:[ALMeterCollectionViewController class]]) {
ALMeterCollectionViewController *vc = (ALMeterCollectionViewController *)[[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"meterGridViewController"];
Expand All @@ -142,7 +171,7 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa
if (vc) {
[self.navigationController pushViewController:vc animated:YES];
}
}
}
}

[self.collectionView deselectItemAtIndexPath:indexPath animated:YES];
Expand All @@ -155,10 +184,6 @@ - (CGSize)collectionView:(UICollectionView *)collectionView
return [self headerSize];
}

- (UIColor *)generateRandomColor {
return [UIColor colorWithRed:(float)rand() / RAND_MAX green:(float)rand() / RAND_MAX blue:(float)rand() / RAND_MAX alpha:1.0f];
}

- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
Expand All @@ -170,6 +195,10 @@ - (CGSize)collectionView:(UICollectionView *)collectionView
}

- (CGSize)headerSize {
//we never actually show the logo if there is more than one section, so we don't need the headers to be as tall as the logo either. Ideally the height should be based on the title height; the 0.16 multiplier is for consistency with the lock icon on the meter reading screen.
if ([self.exampleManager numberOfSections] > 1) {
return CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.width*0.16);
}
return (self.showLogo) ? CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.width*0.25) : CGSizeZero;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@
- (ALExample *)exampleForIndexPath:(NSIndexPath *)indexPath;

@end

extern NSString * const processTitle;
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

#import "ALLicensePlateViewController.h"

NSString * const processTitle = @"Processes";

@interface ALExampleManager ()

@property (nonatomic, strong) NSDictionary *examples;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
#import "ALMeterCollectionViewController.h"
#import "ALGermanIDFrontScanViewController.h"
#import "ALPDF417ScanViewController.h"
#import "ALNFCScanViewController.h"

#import "ALNLDrivingLicenseScanViewController.h"
#import "ALBEDrivingLicenseScanViewController.h"

@interface ALIdentityDocumentsExampleManager ()

@property (nonatomic, strong) NSDictionary *examples;
@property (nonatomic, strong) NSMutableDictionary *examples;

@property (nonatomic, strong) NSArray *sectionNames;

Expand Down Expand Up @@ -58,19 +59,26 @@ - (void)initExampleData {
image:[UIImage imageNamed:@"PDF417"]
viewController:[ALPDF417ScanViewController class]];

ALExample *nfcScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"Passport NFC", nil)
image:[UIImage imageNamed:@"icon_nfc"]
viewController:[ALNFCScanViewController class]];

ALExample *beDriverLicenseScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"BE Driving License", nil)
image:[UIImage imageNamed:@"be_driving_license"]
viewController:[ALBEDrivingLicenseScanViewController class]];

ALExample *nlDriverLicenseScanning = [[ALExample alloc] initWithName:NSLocalizedString(@"NL Driving License", nil)
image:[UIImage imageNamed:@"nl_driving_license"]
viewController:[ALNLDrivingLicenseScanViewController class]];

self.sectionNames = @[@"Identity Documents"];
self.examples = [@{
self.sectionNames[0] : @[mrzScanning,driverLicenseScanning,germanIDScanning,pdf417Scanning]
} mutableCopy];


self.sectionNames = @[@"Identity Documents",];
self.examples = @{
self.sectionNames[0] : @[mrzScanning,driverLicenseScanning,germanIDScanning,pdf417Scanning,],
};
//we could check [ALNFCDetector readingAvailable]) here and only show the NFC tile if it returns true, but for clarity we will always show it, and just show an alert about why it's not supported when it's tapped on.
self.sectionNames = [self.sectionNames arrayByAddingObject:processTitle];
self.examples[self.sectionNames[1]] = @[nfcScanning];
}

@end
10 changes: 8 additions & 2 deletions AnylineExamples/Anyline Demo App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A0000002471001</string>
</array>
<key>NFCReaderUsageDescription</key>
<string>Please allow NFC access to read passports</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
Expand All @@ -17,11 +23,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>14</string>
<string>15.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>271</string>
<string>184</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

typedef void (^CompletionBlock)(void);

NSString * const ALDataPrivacyFileLink = @"https://anylinesdk.blob.core.windows.net/downloads/Anyline_Privacy_Policy_Store_App_English.html";
NSString * const ALDataPrivacyFileLink = @"https://anyline.com/wp-content/uploads/2019/04/PrivacyPolicy_April19.pdf";

@interface ALPrivacyViewController () <MFMailComposeViewControllerDelegate>

Expand Down Expand Up @@ -46,6 +46,12 @@ - (void)viewDidLoad {

self.title = @"Data Privacy Consent";
self.view.backgroundColor = [UIColor whiteColor];
if (@available(iOS 13.0, *)) {
//in light mode this is a slightly lighter colour than lightGrayColor, but it still looks okay
self.view.backgroundColor = [UIColor secondarySystemBackgroundColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
self.navigationItem.hidesBackButton = NO;

CGFloat top = 0;
Expand Down Expand Up @@ -94,6 +100,12 @@ - (void)viewDidLoad {
self.cbox.center = CGPointMake(self.view.center.x, self.cbox.center.y);
self.cbox.isChecked = wasAccepted;

if (@available(iOS 13.0, *)) {
self.cbox.labelTextColor = [UIColor labelColor];
} else {
self.cbox.labelTextColor = [UIColor blackColor];
}

[self.cbox addTarget:self action:@selector(checkAction:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:self.cbox];
Expand All @@ -117,6 +129,7 @@ - (void)viewDidLoad {
[webView loadRequest:urlRequest];

[self.view addSubview:webView];
[self.view bringSubviewToFront:self.cbox];

//TODO: add hard copy fallback; (no internet/file not found)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ - (void)viewDidLoad {
self.view.backgroundColor = [UIColor blackColor];
self.title = @"Horizontal Shipping Container";
// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
CGRect frame = [[UIScreen mainScreen] bounds];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);

ALContainerConfig *config = [[ALContainerConfig alloc] init];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ typedef enum : NSUInteger {
ALScanHistoryGermanIDFront = 27,
ALScanHistoryCattleTag = 28,
ALScanHistoryTIN = 29,
ALScanHistoryNFC = 30,
} ALScanHistoryType;

extern NSString * _Nonnull const ALScanHistoryType_toString[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
[ALScanHistoryGermanIDFront] = @"German ID Front",
[ALScanHistoryCattleTag] = @"Cattle Tag",
[ALScanHistoryTIN] = @"TIN Scanner",
[ALScanHistoryNFC] = @"NFC Reader",
};

@implementation ScanHistory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ - (void)viewDidLoad {
self.title = @"MRZ";

// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
CGRect frame = [[UIScreen mainScreen] bounds];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);

ALMRZConfig *mrzConfig = [[ALMRZConfig alloc] init];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuse

{
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 280, 40)];
label.textColor = [UIColor blackColor];
if (@available(iOS 13.0, *)) {
label.textColor = [UIColor labelColor];
} else {
label.textColor = [UIColor blackColor];
}
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont AL_proximaBoldWithSize:16];
label.backgroundColor = [UIColor clearColor];
Expand All @@ -62,7 +66,11 @@ -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuse

{
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 220, 20)];
label.textColor = [UIColor blackColor];
if (@available(iOS 13.0, *)) {
label.textColor = [UIColor labelColor];
} else {
label.textColor = [UIColor blackColor];
}
label.textAlignment = NSTextAlignmentRight;
label.font = [UIFont AL_proximaRegularWithSize:13];
[label setText:@"Barcode:"];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ @interface ALNFCScanViewController () <ALNFCDetectorDelegate, ALIDPluginDelegate
@property (nonatomic, strong) ALNFCDetector *nfcDetector;
@property (nullable, nonatomic, strong) 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;

@end

@implementation ALNFCScanViewController
Expand Down Expand Up @@ -119,7 +124,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 startMRZScanning];
}

- (void)updateHintPosition:(CGFloat)newPosition {
Expand All @@ -138,11 +143,8 @@ - (void)anylineScanViewPlugin:(ALAbstractScanViewPlugin *)anylineScanViewPlugin
50];
}

/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.mrzScanViewPlugin stopAndReturnError:nil];
[self stopMRZScanning];
}


Expand All @@ -153,9 +155,25 @@ 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 {
- (void)startMRZScanning {
[self startPlugin:self.mrzScanViewPlugin];
self.startTime = CACurrentMediaTime();
self.hintView.hidden = NO;
}

/*
Cancel scanning to allow the module to clean up
*/
- (void)stopMRZScanning {
[self.mrzScanViewPlugin stopAndReturnError:nil];
self.hintView.hidden = YES;
}

- (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];
}

#pragma mark -- ALIDPluginDelegate
Expand All @@ -177,12 +195,12 @@ - (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin didFindResult:
[passportNumberForNFC appendString:@"<"];
}
}
[self.mrzScanViewPlugin stopAndReturnError:nil];
[self stopMRZScanning];
self.passportNumberForNFC = passportNumberForNFC;
self.dateOfBirth = dateOfBirth;
self.dateOfExpiry = dateOfExpiry;
dispatch_async(dispatch_get_main_queue(), ^{
/*
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:passportNumberForNFC dateOfBirth:dateOfBirth expirationDate:dateOfExpiry];
[self readNFCChip];
});
}

Expand All @@ -193,7 +211,17 @@ - (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin didFindResult:
- (void)nfcSucceededWithResult:(ALNFCResult * _Nonnull)nfcResult API_AVAILABLE(ios(13.0)){
dispatch_async(dispatch_get_main_queue(), ^{

[super anylineDidFindResult:@"" barcodeResult:@"" image:nfcResult.dataGroup2.faceImage scanPlugin:nil viewPlugin:nil completion:^{
NSMutableString *nfcResultString = [NSMutableString string];
[nfcResultString appendString:[NSString stringWithFormat:@"Issuing State Code: %@\n", nfcResult.dataGroup1.issuingStateCode]];
[nfcResultString appendString:[NSString stringWithFormat:@"Document Number: %@\n", nfcResult.dataGroup1.documentNumber]];
[nfcResultString appendString:[NSString stringWithFormat:@"Date of Expiry: %@\n", [self stringForDate:nfcResult.dataGroup1.dateOfExpiry]]];
[nfcResultString appendString:[NSString stringWithFormat:@"Gender: %@\n", nfcResult.dataGroup1.gender]];
[nfcResultString appendString:[NSString stringWithFormat:@"Nationality: %@\n", nfcResult.dataGroup1.nationality]];
[nfcResultString appendString:[NSString stringWithFormat:@"Last Name: %@\n", nfcResult.dataGroup1.lastName]];
[nfcResultString appendString:[NSString stringWithFormat:@"First Name: %@\n", nfcResult.dataGroup1.firstName]];
[nfcResultString appendString:[NSString stringWithFormat:@"Date of Birth: %@", [self stringForDate:nfcResult.dataGroup1.dateOfBirth]]];

[super anylineDidFindResult:nfcResultString barcodeResult:@"" image:nfcResult.dataGroup2.faceImage scanPlugin:nil viewPlugin:nil completion:^{
NSMutableArray <ALResultEntry*> *resultData = [[NSMutableArray alloc] init];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Issuing State Code" value:nfcResult.dataGroup1.issuingStateCode]];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Document Number" value:nfcResult.dataGroup1.documentNumber]];
Expand All @@ -217,7 +245,14 @@ - (void)nfcFailedWithError:(NSError * _Nonnull)error {
if (error.code == ALNFCTagErrorNFCNotSupported) {
[self showAlertWithTitle:@"NFC Not Supported" message:@"NFC passport reading is not supported on this device."];
}
[self startAnyline]; //run the MRZ scanner so we can try again.
//error ALNFCTagErrorResponseError can mean the MRZ key was wrong
if (error.code == ALNFCTagErrorResponseError) {
[self startMRZScanning]; //run the MRZ scanner so we can try again.
} else {
//the MRZ details are correct; they might have just moved the phone away from the passport
[self readNFCChip];

}
});
}

Expand Down
Loading

0 comments on commit df3fc97

Please sign in to comment.