forked from yankodimitrov/SwiftPasscodeLock
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPasscodeLock.swift
More file actions
104 lines (72 loc) · 3.21 KB
/
Copy pathPasscodeLock.swift
File metadata and controls
104 lines (72 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// PasscodeLock.swift
// PasscodeLock
//
// Created by Yanko Dimitrov on 8/28/15.
// Copyright © 2015 Yanko Dimitrov. All rights reserved.
//
import UIKit
import LocalAuthentication
open class PasscodeLock: PasscodeLockType {
open weak var delegate: PasscodeLockTypeDelegate?
public let configuration: PasscodeLockConfigurationType
open var repository: PasscodeRepositoryType {
return configuration.repository
}
open var state: PasscodeLockStateType {
return lockState
}
open var isTouchIDAllowed: Bool {
return isTouchIDEnabled() && configuration.isTouchIDAllowed && lockState.isTouchIDAllowed
}
open var isPincodeEmpty: Bool {
return passcode.isEmpty
}
fileprivate var lockState: PasscodeLockStateType
fileprivate lazy var passcode = [String]()
public init(state: PasscodeLockStateType, configuration: PasscodeLockConfigurationType) {
precondition(configuration.passcodeLength > 0, "Passcode length sould be greather than zero.")
self.lockState = state
self.configuration = configuration
}
open func addSign(_ sign: String, stringsToBeDisplayed: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) {
passcode.append(sign)
delegate?.passcodeLock(self, addedSignAtIndex: passcode.count - 1)
if (passcode.count >= configuration.passcodeLength) {
self.lockState.acceptPasscode(self.passcode, fromLock: self, stringsToShow: stringsToBeDisplayed, tintColor: tintColor, font: font)
self.passcode.removeAll(keepingCapacity: true)
}
}
open func removeSign() {
guard passcode.count > 0 else { return }
passcode.removeLast()
delegate?.passcodeLock(self, removedSignAtIndex: passcode.count)
}
open func changeStateTo(_ state: PasscodeLockStateType) {
DispatchQueue.main.async {
self.lockState = state
self.delegate?.passcodeLockDidChangeState(self)
}
}
open func authenticateWithBiometrics(_ stringsToShow: StringsToBeDisplayed?) {
guard isTouchIDAllowed else { return }
let context = LAContext()
let reason = (stringsToShow?.passcodeLockTouchIDReason ?? localizedStringFor("PasscodeLockTouchIDReason", comment: "TouchID authentication reason"))
context.localizedFallbackTitle = (stringsToShow?.passcodeLockTouchIDButton ?? localizedStringFor("PasscodeLockTouchIDButton", comment: "TouchID authentication fallback button"))
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) {
success, error in
self.handleTouchIDResult(success)
}
}
fileprivate func handleTouchIDResult(_ success: Bool) {
DispatchQueue.main.async {
if success {
self.delegate?.passcodeLockDidSucceed(self)
}
}
}
fileprivate func isTouchIDEnabled() -> Bool {
let context = LAContext()
return context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
}
}