Skip to content

Commit 3049027

Browse files
committed
Added provisions for Face ID
1 parent bf2e010 commit 3049027

File tree

9 files changed

+67
-9
lines changed

9 files changed

+67
-9
lines changed

TOPasscodeViewController/Supporting/TOPasscodeViewControllerConstants.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,23 @@ typedef NS_ENUM(NSInteger, TOPasscodeType) {
4949
TOPasscodeTypeCustomAlphanumeric // Any length of characters
5050
};
5151

52+
/* The type of biometrics this controller can handle */
53+
typedef NS_ENUM(NSInteger, TOPasscodeBiometryType) {
54+
TOPasscodeBiometryTypeTouchID,
55+
TOPasscodeBiometryTypeFaceID
56+
};
57+
5258
static inline BOOL TOPasscodeViewStyleIsTranslucent(TOPasscodeViewStyle style) {
5359
return style <= TOPasscodeViewStyleTranslucentLight;
5460
}
5561

5662
static inline BOOL TOPasscodeViewStyleIsDark(TOPasscodeViewStyle style) {
5763
return style < TOPasscodeViewStyleTranslucentLight || style == TOPasscodeViewStyleOpaqueDark;
5864
}
65+
66+
static inline NSString *TOPasscodeBiometryTitleForType(TOPasscodeBiometryType type) {
67+
switch (type) {
68+
case TOPasscodeBiometryTypeFaceID: return @"Face ID";
69+
default: return @"Touch ID";
70+
}
71+
}

TOPasscodeViewController/TOPasscodeViewController.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,13 @@ NS_ASSUME_NONNULL_BEGIN
7979
/** The type of passcode that is expected to be entered. */
8080
@property (nonatomic, readonly) TOPasscodeType passcodeType;
8181

82-
/** Will show a 'Touch ID' button for that the user can tap to initiate Touch ID verification. (Default is NO) */
82+
/** Will show a 'Touch ID' or 'Face ID' (depending on `biometricType`) button if the user is allowed to log in that way. (Default is NO) */
8383
@property (nonatomic, assign) BOOL allowBiometricValidation;
8484

85-
/** If Touch ID is available, automatically ask for it upon presentation (Default is NO) */
85+
/** Set the type of biometrics for this device to update the title of the biometrics button properly. */
86+
@property (nonatomic, assign) TOPasscodeBiometryType biometryType;
87+
88+
/** If biometrics are available, automatically ask for it upon presentation (Default is NO) */
8689
@property (nonatomic, assign) BOOL automaticallyPromptForBiometricValidation;
8790

8891
/** Optionally change the color of the title text label. */

TOPasscodeViewController/TOPasscodeViewController.m

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ - (void)setUpAccessoryButtons
155155

156156
if (!self.leftAccessoryButton && self.allowBiometricValidation && !self.biometricButton) {
157157
self.biometricButton = [UIButton buttonWithType:UIButtonTypeSystem];
158-
[self.biometricButton setTitle:@"Touch ID" forState:UIControlStateNormal];
158+
[self.biometricButton setTitle:TOPasscodeBiometryTitleForType(self.biometryType) forState:UIControlStateNormal];
159159
[self.biometricButton addTarget:self action:@selector(accessoryButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
160160

161161
if (isPad) {
@@ -617,6 +617,17 @@ - (void)setAccessoryButtonTintColor:(UIColor *)accessoryButtonTintColor
617617
[self applyThemeForStyle:self.style];
618618
}
619619

620+
- (void)setBiometryType:(TOPasscodeBiometryType)biometryType
621+
{
622+
if (_biometryType == biometryType) { return; }
623+
624+
_biometryType = biometryType;
625+
626+
if (self.biometricButton) {
627+
[self.biometricButton setTitle:TOPasscodeBiometryTitleForType(_biometryType) forState:UIControlStateNormal];
628+
}
629+
}
630+
620631
- (void)setContentHidden:(BOOL)contentHidden
621632
{
622633
[self setContentHidden:contentHidden animated:NO];

TOPasscodeViewController/Views/Settings/TOPasscodeSettingsKeypadView.m

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#import "TOSettingsKeypadImage.h"
2727
const CGFloat kTOPasscodeSettingsKeypadButtonInnerSpacing = 7.0f;
2828
const CGFloat kTOPasscodeSettingsKeypadButtonOuterSpacing = 7.0f;
29-
const CGFloat kTOPasscodeSettingsKeypadCornderRadius = 10.0f;
29+
const CGFloat kTOPasscodeSettingsKeypadCornderRadius = 12.0f;
3030

3131
@interface TOPasscodeSettingsKeypadView ()
3232

@@ -208,6 +208,11 @@ - (void)layoutSubviews
208208

209209
viewSize.width -= (outerSpacing * 2.0f);
210210
viewSize.height -= (outerSpacing * 2.0f);
211+
212+
// Pull the buttons up to avoid overlapping the home indicator on iPhone X
213+
if (@available(iOS 11.0, *)) {
214+
viewSize.height -= self.safeAreaInsets.bottom;
215+
}
211216

212217
// Four rows of three buttons
213218
buttonSize.width = floorf((viewSize.width - (innerSpacing * 2.0f)) / 3.0f);
@@ -233,6 +238,12 @@ - (void)layoutSubviews
233238

234239
//Layout delete button
235240
CGSize boundsSize = self.bounds.size;
241+
242+
// Adjust for home indicator on iPhone X
243+
if (@available(iOS 11.0, *)) {
244+
boundsSize.height -= self.safeAreaInsets.bottom;
245+
}
246+
236247
CGRect frame = self.deleteButton.frame;
237248
frame.size = buttonSize;
238249
frame.origin.x = boundsSize.width - (outerSpacing + buttonSize.width * 0.5f);

TOPasscodeViewControllerExample.xcodeproj/project.pbxproj

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
22D361391EDCC1D7002E5D35 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 22D361301EDCC1D7002E5D35 /* main.m */; };
3434
22D3613A1EDCC1D7002E5D35 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22D361321EDCC1D7002E5D35 /* ViewController.m */; };
3535
22D3613B1EDCC1D7002E5D35 /* wallpaper.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 22D361331EDCC1D7002E5D35 /* wallpaper.jpg */; };
36-
22D3613F1EDCC1EA002E5D35 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 22D3613D1EDCC1EA002E5D35 /* Info.plist */; };
3736
22D361401EDCC1EA002E5D35 /* TOPasscodeViewControllerExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 22D3613E1EDCC1EA002E5D35 /* TOPasscodeViewControllerExampleTests.m */; };
3837
22D5C81A1EE9F99600745F9A /* TOPasscodeSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22D5C8191EE9F99600745F9A /* TOPasscodeSettingsViewController.m */; };
3938
22EAD9DA1EFA4CEF00D0C408 /* TOSettingsKeypadImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 22EAD9D91EFA4CEF00D0C408 /* TOSettingsKeypadImage.m */; };
@@ -321,7 +320,7 @@
321320
22F8069B1ECABB3D0053C94E /* Project object */ = {
322321
isa = PBXProject;
323322
attributes = {
324-
LastUpgradeCheck = 0830;
323+
LastUpgradeCheck = 0920;
325324
ORGANIZATIONNAME = "Timothy Oliver";
326325
TargetAttributes = {
327326
22F806A21ECABB3D0053C94E = {
@@ -372,7 +371,6 @@
372371
isa = PBXResourcesBuildPhase;
373372
buildActionMask = 2147483647;
374373
files = (
375-
22D3613F1EDCC1EA002E5D35 /* Info.plist in Resources */,
376374
);
377375
runOnlyForDeploymentPostprocessing = 0;
378376
};
@@ -473,15 +471,21 @@
473471
CLANG_CXX_LIBRARY = "libc++";
474472
CLANG_ENABLE_MODULES = YES;
475473
CLANG_ENABLE_OBJC_ARC = YES;
474+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
476475
CLANG_WARN_BOOL_CONVERSION = YES;
476+
CLANG_WARN_COMMA = YES;
477477
CLANG_WARN_CONSTANT_CONVERSION = YES;
478478
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
479479
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
480480
CLANG_WARN_EMPTY_BODY = YES;
481481
CLANG_WARN_ENUM_CONVERSION = YES;
482482
CLANG_WARN_INFINITE_RECURSION = YES;
483483
CLANG_WARN_INT_CONVERSION = YES;
484+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
485+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
484486
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
487+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
488+
CLANG_WARN_STRICT_PROTOTYPES = YES;
485489
CLANG_WARN_SUSPICIOUS_MOVE = YES;
486490
CLANG_WARN_UNREACHABLE_CODE = YES;
487491
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -522,15 +526,21 @@
522526
CLANG_CXX_LIBRARY = "libc++";
523527
CLANG_ENABLE_MODULES = YES;
524528
CLANG_ENABLE_OBJC_ARC = YES;
529+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
525530
CLANG_WARN_BOOL_CONVERSION = YES;
531+
CLANG_WARN_COMMA = YES;
526532
CLANG_WARN_CONSTANT_CONVERSION = YES;
527533
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
528534
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
529535
CLANG_WARN_EMPTY_BODY = YES;
530536
CLANG_WARN_ENUM_CONVERSION = YES;
531537
CLANG_WARN_INFINITE_RECURSION = YES;
532538
CLANG_WARN_INT_CONVERSION = YES;
539+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
540+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
533541
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
542+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
543+
CLANG_WARN_STRICT_PROTOTYPES = YES;
534544
CLANG_WARN_SUSPICIOUS_MOVE = YES;
535545
CLANG_WARN_UNREACHABLE_CODE = YES;
536546
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;

TOPasscodeViewControllerExample.xcodeproj/xcshareddata/xcschemes/TOPasscodeViewControllerExample.xcscheme

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0830"
3+
LastUpgradeVersion = "0920"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
2626
buildConfiguration = "Debug"
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
language = ""
2930
shouldUseLaunchSchemeArgsEnv = "YES">
3031
<Testables>
3132
</Testables>
@@ -45,6 +46,7 @@
4546
buildConfiguration = "Debug"
4647
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
4748
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
49+
language = ""
4850
launchStyle = "0"
4951
useCustomWorkingDirectory = "NO"
5052
ignoresPersistentStateOnLaunch = "NO"

TOPasscodeViewControllerExample.xcodeproj/xcshareddata/xcschemes/TOPasscodeViewControllerExampleTests.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0830"
3+
LastUpgradeVersion = "0920"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

TOPasscodeViewControllerExample/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,7 @@
4545
<string>UIInterfaceOrientationLandscapeLeft</string>
4646
<string>UIInterfaceOrientationLandscapeRight</string>
4747
</array>
48+
<key>NSFaceIDUsageDescription</key>
49+
<string>Use Face ID to unlock this demo app of TOPasscodeViewController</string>
4850
</dict>
4951
</plist>

TOPasscodeViewControllerExample/ViewController.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ @interface ViewController () <TOPasscodeViewControllerDelegate>
2222

2323
@property (nonatomic, strong) LAContext *authContext;
2424
@property (nonatomic, assign) BOOL biometricsAvailable;
25+
@property (nonatomic, assign) BOOL faceIDAvailable;
2526

2627
@end
2728

@@ -38,13 +39,18 @@ - (void)viewDidLoad {
3839
// Show 'Touch ID' button if it's available
3940
self.authContext = [[LAContext alloc] init];
4041
self.biometricsAvailable = [self.authContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil];
42+
43+
if (@available(iOS 11.0, *)) {
44+
self.faceIDAvailable = (self.authContext.biometryType == LABiometryTypeFaceID);
45+
}
4146
}
4247

4348
- (IBAction)showButtonTapped:(id)sender
4449
{
4550
TOPasscodeViewController *passcodeViewController = [[TOPasscodeViewController alloc] initWithStyle:self.style passcodeType:self.type];
4651
passcodeViewController.delegate = self;
4752
passcodeViewController.allowBiometricValidation = self.biometricsAvailable;
53+
passcodeViewController.biometryType = self.faceIDAvailable ? TOPasscodeBiometryTypeFaceID : TOPasscodeBiometryTypeTouchID;
4854
[self presentViewController:passcodeViewController animated:YES completion:nil];
4955
}
5056

0 commit comments

Comments
 (0)