diff --git a/.swift-version b/.swift-version index c0943d3e..9f55b2cc 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -2.3 \ No newline at end of file +3.0 diff --git a/PasscodeLock.xcodeproj/project.pbxproj b/PasscodeLock.xcodeproj/project.pbxproj index 0cf64878..eec2906d 100644 --- a/PasscodeLock.xcodeproj/project.pbxproj +++ b/PasscodeLock.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 281AA9201DB626E000908E23 /* Localize.strings in Resources */ = {isa = PBXBuildFile; fileRef = 281AA9221DB626E000908E23 /* Localize.strings */; }; + 4A57CCF92010A437006A7B80 /* Localize.strings in Resources */ = {isa = PBXBuildFile; fileRef = 281AA9221DB626E000908E23 /* Localize.strings */; }; 8F3B9D031E028815008CF18F /* PasscodeLockImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8F3B9D021E028815008CF18F /* PasscodeLockImages.xcassets */; }; C99EAF431B90B05700D61E1B /* PasscodeLock.h in Headers */ = {isa = PBXBuildFile; fileRef = C99EAF421B90B05700D61E1B /* PasscodeLock.h */; settings = {ATTRIBUTES = (Public, ); }; }; C99EAF4A1B90B05800D61E1B /* PasscodeLock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C99EAF3F1B90B05700D61E1B /* PasscodeLock.framework */; }; @@ -23,15 +24,10 @@ C9D3DF461B91BD0E008561EB /* PasscodeLockConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D3DF451B91BD0E008561EB /* PasscodeLockConfiguration.swift */; }; C9D3DF481B91F099008561EB /* PasscodeLockPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D3DF471B91F099008561EB /* PasscodeLockPresenter.swift */; }; C9DC07D51B90B1F6007A4DD0 /* PasscodeRepositoryType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07D41B90B1F6007A4DD0 /* PasscodeRepositoryType.swift */; }; - C9DC07D61B90B1F6007A4DD0 /* PasscodeRepositoryType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07D41B90B1F6007A4DD0 /* PasscodeRepositoryType.swift */; }; C9DC07D81B90B261007A4DD0 /* PasscodeLockStateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07D71B90B261007A4DD0 /* PasscodeLockStateType.swift */; }; - C9DC07D91B90B261007A4DD0 /* PasscodeLockStateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07D71B90B261007A4DD0 /* PasscodeLockStateType.swift */; }; C9DC07DB1B90B730007A4DD0 /* PasscodeLockConfigurationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07DA1B90B730007A4DD0 /* PasscodeLockConfigurationType.swift */; }; - C9DC07DC1B90B730007A4DD0 /* PasscodeLockConfigurationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07DA1B90B730007A4DD0 /* PasscodeLockConfigurationType.swift */; }; C9DC07DE1B90BA06007A4DD0 /* PasscodeLockType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07DD1B90BA06007A4DD0 /* PasscodeLockType.swift */; }; - C9DC07DF1B90BA06007A4DD0 /* PasscodeLockType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07DD1B90BA06007A4DD0 /* PasscodeLockType.swift */; }; C9DC07E11B90BBFD007A4DD0 /* PasscodeLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07E01B90BBFD007A4DD0 /* PasscodeLock.swift */; }; - C9DC07E21B90BBFD007A4DD0 /* PasscodeLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07E01B90BBFD007A4DD0 /* PasscodeLock.swift */; }; C9DC07E51B90BCF9007A4DD0 /* PasscodeLockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07E41B90BCF9007A4DD0 /* PasscodeLockTests.swift */; }; C9DC07E71B90C382007A4DD0 /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9DC07E61B90C382007A4DD0 /* LocalAuthentication.framework */; }; C9DC07EA1B90C690007A4DD0 /* FakePasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07E91B90C690007A4DD0 /* FakePasscodeState.swift */; }; @@ -39,15 +35,10 @@ C9DC07EE1B90C7CD007A4DD0 /* FakePasscodeLockConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07ED1B90C7CD007A4DD0 /* FakePasscodeLockConfiguration.swift */; }; C9DC07F01B90C8E1007A4DD0 /* FakePasscodeLockDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07EF1B90C8E1007A4DD0 /* FakePasscodeLockDelegate.swift */; }; C9DC07F21B90C9DE007A4DD0 /* EnterPasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07F11B90C9DE007A4DD0 /* EnterPasscodeState.swift */; }; - C9DC07F31B90C9DE007A4DD0 /* EnterPasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07F11B90C9DE007A4DD0 /* EnterPasscodeState.swift */; }; C9DC07F81B90CF29007A4DD0 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07F71B90CF29007A4DD0 /* Functions.swift */; }; - C9DC07F91B90CF29007A4DD0 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07F71B90CF29007A4DD0 /* Functions.swift */; }; C9DC07FF1B90D24A007A4DD0 /* SetPasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07FE1B90D24A007A4DD0 /* SetPasscodeState.swift */; }; - C9DC08001B90D24A007A4DD0 /* SetPasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC07FE1B90D24A007A4DD0 /* SetPasscodeState.swift */; }; C9DC08021B90D2BA007A4DD0 /* ConfirmPasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC08011B90D2BA007A4DD0 /* ConfirmPasscodeState.swift */; }; - C9DC08031B90D2BA007A4DD0 /* ConfirmPasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC08011B90D2BA007A4DD0 /* ConfirmPasscodeState.swift */; }; C9DC08051B90D394007A4DD0 /* ChangePasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC08041B90D394007A4DD0 /* ChangePasscodeState.swift */; }; - C9DC08061B90D394007A4DD0 /* ChangePasscodeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC08041B90D394007A4DD0 /* ChangePasscodeState.swift */; }; C9DC08081B90DAE6007A4DD0 /* EnterPasscodeStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC08071B90DAE6007A4DD0 /* EnterPasscodeStateTests.swift */; }; C9DC080A1B90DB09007A4DD0 /* FakePasscodeLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC08091B90DB09007A4DD0 /* FakePasscodeLock.swift */; }; C9DC080C1B90DC38007A4DD0 /* SetPasscodeStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC080B1B90DC38007A4DD0 /* SetPasscodeStateTests.swift */; }; @@ -456,10 +447,11 @@ TargetAttributes = { C99EAF3E1B90B05700D61E1B = { CreatedOnToolsVersion = 7.0; - LastSwiftMigration = 0800; + LastSwiftMigration = 0830; }; C99EAF481B90B05700D61E1B = { CreatedOnToolsVersion = 7.0; + LastSwiftMigration = 0830; }; C9D3DF0F1B91AD11008561EB = { CreatedOnToolsVersion = 7.0; @@ -525,6 +517,7 @@ C9D3DF1D1B91AD11008561EB /* LaunchScreen.storyboard in Resources */, C9D3DF1A1B91AD11008561EB /* Assets.xcassets in Resources */, C9D3DF181B91AD11008561EB /* Main.storyboard in Resources */, + 4A57CCF92010A437006A7B80 /* Localize.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -571,24 +564,14 @@ buildActionMask = 2147483647; files = ( C9DC07EC1B90C72A007A4DD0 /* FakePasscodeRepository.swift in Sources */, - C9DC08061B90D394007A4DD0 /* ChangePasscodeState.swift in Sources */, C9DC080E1B90DC8F007A4DD0 /* ConfirmPasscodeStateTests.swift in Sources */, C9DC07E51B90BCF9007A4DD0 /* PasscodeLockTests.swift in Sources */, - C9DC08031B90D2BA007A4DD0 /* ConfirmPasscodeState.swift in Sources */, C9DC07F01B90C8E1007A4DD0 /* FakePasscodeLockDelegate.swift in Sources */, - C9DC07D91B90B261007A4DD0 /* PasscodeLockStateType.swift in Sources */, - C9DC07E21B90BBFD007A4DD0 /* PasscodeLock.swift in Sources */, C9DC07EA1B90C690007A4DD0 /* FakePasscodeState.swift in Sources */, C9DC08101B90DD91007A4DD0 /* ChangePasscodeStateTests.swift in Sources */, - C9DC07DC1B90B730007A4DD0 /* PasscodeLockConfigurationType.swift in Sources */, - C9DC07F31B90C9DE007A4DD0 /* EnterPasscodeState.swift in Sources */, - C9DC08001B90D24A007A4DD0 /* SetPasscodeState.swift in Sources */, C9DC07EE1B90C7CD007A4DD0 /* FakePasscodeLockConfiguration.swift in Sources */, C9DC080C1B90DC38007A4DD0 /* SetPasscodeStateTests.swift in Sources */, C9DC08081B90DAE6007A4DD0 /* EnterPasscodeStateTests.swift in Sources */, - C9DC07DF1B90BA06007A4DD0 /* PasscodeLockType.swift in Sources */, - C9DC07D61B90B1F6007A4DD0 /* PasscodeRepositoryType.swift in Sources */, - C9DC07F91B90CF29007A4DD0 /* Functions.swift in Sources */, C9DC080A1B90DB09007A4DD0 /* FakePasscodeLock.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -786,7 +769,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -805,7 +788,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.yankodimitrov.PasscodeLock; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -819,6 +802,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "PasscodeLockTests/PasscodeLockTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -831,6 +815,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.yankodimitrov.PasscodeLockTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "PasscodeLockTests/PasscodeLockTests-Bridging-Header.h"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/PasscodeLock/Base.lproj/Localize.strings b/PasscodeLock/Base.lproj/Localize.strings index 25926802..1c83f62c 100644 --- a/PasscodeLock/Base.lproj/Localize.strings +++ b/PasscodeLock/Base.lproj/Localize.strings @@ -35,3 +35,4 @@ "Cancel" = "Cancel"; "Delete" = "Delete"; "UseTouchId" = "Use TouchID"; +"UseFaceId" = "Use FaceID"; diff --git a/PasscodeLock/Functions.swift b/PasscodeLock/Functions.swift index 6b61c4bd..c7ba7509 100644 --- a/PasscodeLock/Functions.swift +++ b/PasscodeLock/Functions.swift @@ -7,22 +7,23 @@ // import Foundation +import UIKit -func localizedStringFor(key: String, comment: String) -> String { +func localizedStringFor(_ key: String, comment: String) -> String { let name = "Localize" let bundle = bundleForResource(name, ofType: "strings") - - return NSLocalizedString(key, tableName: name, bundle: bundle, comment: comment) + + return NSLocalizedString(key, tableName: name, bundle: bundle, value: "", comment: comment) } -func bundleForResource(name: String, ofType type: String) -> NSBundle { +func bundleForResource(_ name: String, ofType type: String) -> Bundle { - if(NSBundle.mainBundle().pathForResource(name, ofType: type) != nil) { - return NSBundle.mainBundle() + if(Bundle.main.path(forResource: name, ofType: type) != nil) { + return Bundle.main } - return NSBundle(forClass: PasscodeLock.self) + return Bundle(for: PasscodeLock.self) } func defaultCustomColor() -> UIColor { diff --git a/PasscodeLock/PasscodeLock/ChangePasscodeState.swift b/PasscodeLock/PasscodeLock/ChangePasscodeState.swift index 066d990e..a0f35349 100644 --- a/PasscodeLock/PasscodeLock/ChangePasscodeState.swift +++ b/PasscodeLock/PasscodeLock/ChangePasscodeState.swift @@ -7,6 +7,7 @@ // import Foundation +import UIKit struct ChangePasscodeState: PasscodeLockStateType { @@ -24,10 +25,10 @@ struct ChangePasscodeState: PasscodeLockStateType { self.title = (stringsToShow?.passcodeLockChangeTitle ?? localizedStringFor("PasscodeLockChangeTitle", comment: "Change passcode title")) self.description = (stringsToShow?.passcodeLockChangeDescription ?? localizedStringFor("PasscodeLockChangeDescription", comment: "Change passcode description")) self.tintColor = (tintColor ?? defaultColor) - self.font = (font ?? UIFont.systemFontOfSize(16)) + self.font = (font ?? UIFont.systemFont(ofSize: 16)) } - func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { + func acceptPasscode(_ passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { guard let currentPasscode = lock.repository.passcode else { return diff --git a/PasscodeLock/PasscodeLock/ConfirmPasscodeState.swift b/PasscodeLock/PasscodeLock/ConfirmPasscodeState.swift index e676f4a2..2c2c0a62 100644 --- a/PasscodeLock/PasscodeLock/ConfirmPasscodeState.swift +++ b/PasscodeLock/PasscodeLock/ConfirmPasscodeState.swift @@ -7,6 +7,7 @@ // import Foundation +import UIKit struct ConfirmPasscodeState: PasscodeLockStateType { @@ -17,7 +18,7 @@ struct ConfirmPasscodeState: PasscodeLockStateType { var tintColor : UIColor? var font : UIFont? - private var passcodeToConfirm: [String] + fileprivate var passcodeToConfirm: [String] init(passcode: [String], stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { @@ -26,10 +27,10 @@ struct ConfirmPasscodeState: PasscodeLockStateType { self.title = (stringsToShow?.passcodeLockConfirmTitle ?? localizedStringFor("PasscodeLockConfirmTitle", comment: "Confirm passcode title")) self.description = (stringsToShow?.passcodeLockConfirmDescription ?? localizedStringFor("PasscodeLockConfirmDescription", comment: "Confirm passcode description")) self.tintColor = (tintColor ?? defaultColor) - self.font = (font ?? UIFont.systemFontOfSize(16)) + self.font = (font ?? UIFont.systemFont(ofSize: 16)) } - func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { + func acceptPasscode(_ passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { if (passcode == passcodeToConfirm) { lock.repository.savePasscode(passcode) diff --git a/PasscodeLock/PasscodeLock/EnterPasscodeState.swift b/PasscodeLock/PasscodeLock/EnterPasscodeState.swift index 89b611db..fcb3dde8 100644 --- a/PasscodeLock/PasscodeLock/EnterPasscodeState.swift +++ b/PasscodeLock/PasscodeLock/EnterPasscodeState.swift @@ -19,7 +19,7 @@ struct EnterPasscodeState: PasscodeLockStateType { var tintColor : UIColor? var font : UIFont? - private var inccorectPasscodeAttempts = 0 + fileprivate var inccorectPasscodeAttempts = 0 init(allowCancellation: Bool = false, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { @@ -28,10 +28,10 @@ struct EnterPasscodeState: PasscodeLockStateType { self.title = (stringsToShow?.passcodeLockEnterTitle ?? localizedStringFor("PasscodeLockEnterTitle", comment: "Enter passcode title")) self.description = (stringsToShow?.passcodeLockEnterDescription ?? localizedStringFor("PasscodeLockEnterDescription", comment: "Enter passcode description")) self.tintColor = (tintColor ?? defaultColor) - self.font = (font ?? UIFont.systemFontOfSize(16)) + self.font = (font ?? UIFont.systemFont(ofSize: 16)) } - mutating func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { + mutating func acceptPasscode(_ passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { guard let currentPasscode = lock.repository.passcode else { return @@ -51,9 +51,9 @@ struct EnterPasscodeState: PasscodeLockStateType { } } - private mutating func postNotification() { + fileprivate mutating func postNotification() { - let center = NSNotificationCenter.defaultCenter() - center.postNotificationName(PasscodeLockIncorrectPasscodeNotification, object: nil) + let center = NotificationCenter.default + center.post(name: Notification.Name(rawValue: PasscodeLockIncorrectPasscodeNotification), object: nil) } } diff --git a/PasscodeLock/PasscodeLock/PasscodeLock.swift b/PasscodeLock/PasscodeLock/PasscodeLock.swift index 6f9aecd9..e796ab9f 100644 --- a/PasscodeLock/PasscodeLock/PasscodeLock.swift +++ b/PasscodeLock/PasscodeLock/PasscodeLock.swift @@ -9,29 +9,29 @@ import Foundation import LocalAuthentication -public class PasscodeLock: PasscodeLockType { +open class PasscodeLock: PasscodeLockType { - public weak var delegate: PasscodeLockTypeDelegate? - public let configuration: PasscodeLockConfigurationType + open weak var delegate: PasscodeLockTypeDelegate? + open let configuration: PasscodeLockConfigurationType - public var repository: PasscodeRepositoryType { + open var repository: PasscodeRepositoryType { return configuration.repository } - public var state: PasscodeLockStateType { + open var state: PasscodeLockStateType { return lockState } - public var isTouchIDAllowed: Bool { + open var isTouchIDAllowed: Bool { return isTouchIDEnabled() && configuration.isTouchIDAllowed && lockState.isTouchIDAllowed } - public var isPincodeEmpty: Bool { + open var isPincodeEmpty: Bool { return passcode.isEmpty } - private var lockState: PasscodeLockStateType - private lazy var passcode = [String]() + fileprivate var lockState: PasscodeLockStateType + fileprivate lazy var passcode = [String]() public init(state: PasscodeLockStateType, configuration: PasscodeLockConfigurationType) { @@ -41,7 +41,7 @@ public class PasscodeLock: PasscodeLockType { self.configuration = configuration } - public func addSign(sign: String, stringsToBeDisplayed: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { + open func addSign(_ sign: String, stringsToBeDisplayed: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { passcode.append(sign) delegate?.passcodeLock(self, addedSignAtIndex: passcode.count - 1) @@ -49,11 +49,11 @@ public class PasscodeLock: PasscodeLockType { if (passcode.count >= configuration.passcodeLength) { self.lockState.acceptPasscode(self.passcode, fromLock: self, stringsToShow: stringsToBeDisplayed, tintColor: tintColor, font: font) - self.passcode.removeAll(keepCapacity: true) + self.passcode.removeAll(keepingCapacity: true) } } - public func removeSign() { + open func removeSign() { guard passcode.count > 0 else { return } @@ -61,13 +61,13 @@ public class PasscodeLock: PasscodeLockType { delegate?.passcodeLock(self, removedSignAtIndex: passcode.count) } - public func changeStateTo(state: PasscodeLockStateType) { + open func changeStateTo(_ state: PasscodeLockStateType) { lockState = state delegate?.passcodeLockDidChangeState(self) } - public func authenticateWithBiometrics(stringsToShow: StringsToBeDisplayed?) { + open func authenticateWithBiometrics(_ stringsToShow: StringsToBeDisplayed?) { guard isTouchIDAllowed else { return } @@ -76,16 +76,16 @@ public class PasscodeLock: PasscodeLockType { context.localizedFallbackTitle = (stringsToShow?.passcodeLockTouchIDButton ?? localizedStringFor("PasscodeLockTouchIDButton", comment: "TouchID authentication fallback button")) - context.evaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { + context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, error in self.handleTouchIDResult(success) } } - private func handleTouchIDResult(success: Bool) { + fileprivate func handleTouchIDResult(_ success: Bool) { - dispatch_async(dispatch_get_main_queue()) { + DispatchQueue.main.async { if success { @@ -94,10 +94,10 @@ public class PasscodeLock: PasscodeLockType { } } - private func isTouchIDEnabled() -> Bool { + fileprivate func isTouchIDEnabled() -> Bool { let context = LAContext() - return context.canEvaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics, error: nil) + return context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) } } diff --git a/PasscodeLock/PasscodeLock/SetPasscodeState.swift b/PasscodeLock/PasscodeLock/SetPasscodeState.swift index f4853ab4..6024e947 100644 --- a/PasscodeLock/PasscodeLock/SetPasscodeState.swift +++ b/PasscodeLock/PasscodeLock/SetPasscodeState.swift @@ -7,6 +7,7 @@ // import Foundation +import UIKit struct SetPasscodeState: PasscodeLockStateType { @@ -23,7 +24,7 @@ struct SetPasscodeState: PasscodeLockStateType { self.title = title self.description = description self.tintColor = (tintColor ?? defaultColor) - self.font = (font ?? UIFont.systemFontOfSize(16)) + self.font = (font ?? UIFont.systemFont(ofSize: 16)) } init(stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { @@ -32,10 +33,10 @@ struct SetPasscodeState: PasscodeLockStateType { self.title = (stringsToShow?.passcodeLockSetTitle ?? localizedStringFor("PasscodeLockSetTitle", comment: "Set passcode title")) self.description = (stringsToShow?.passcodeLockSetDescription ?? localizedStringFor("PasscodeLockSetDescription", comment: "Set passcode description")) self.tintColor = (tintColor ?? defaultColor) - self.font = (font ?? UIFont.systemFontOfSize(16)) + self.font = (font ?? UIFont.systemFont(ofSize: 16)) } - func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { + func acceptPasscode(_ passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { let nextState = ConfirmPasscodeState(passcode: passcode, stringsToShow: stringsToShow, tintColor: tintColor, font: font) lock.changeStateTo(nextState) diff --git a/PasscodeLock/PasscodeLockPresenter.swift b/PasscodeLock/PasscodeLockPresenter.swift index ce754391..cb7018a2 100644 --- a/PasscodeLock/PasscodeLockPresenter.swift +++ b/PasscodeLock/PasscodeLockPresenter.swift @@ -27,8 +27,9 @@ public struct StringsToBeDisplayed { public var cancel: String? public var delete: String? public var useTouchID: String? + public var useFaceID: String? - public init(passcodeLockEnterTitle: String?, passcodeLockEnterDescription: String?, passcodeLockSetTitle: String?, passcodeLockSetDescription: String?, passcodeLockConfirmTitle: String?, passcodeLockConfirmDescription: String?, passcodeLockChangeTitle: String?, passcodeLockChangeDescription: String?, passcodeLockMismatchTitle: String?, passcodeLockMismatchDescription: String?, passcodeLockTouchIDReason: String?, passcodeLockTouchIDButton: String?, cancel: String?, delete: String?, useTouchID: String?) { + public init(passcodeLockEnterTitle: String?, passcodeLockEnterDescription: String?, passcodeLockSetTitle: String?, passcodeLockSetDescription: String?, passcodeLockConfirmTitle: String?, passcodeLockConfirmDescription: String?, passcodeLockChangeTitle: String?, passcodeLockChangeDescription: String?, passcodeLockMismatchTitle: String?, passcodeLockMismatchDescription: String?, passcodeLockTouchIDReason: String?, passcodeLockTouchIDButton: String?, cancel: String?, delete: String?, useTouchID: String?, useFaceID: String?) { self.passcodeLockEnterTitle = passcodeLockEnterTitle self.passcodeLockEnterDescription = passcodeLockEnterDescription @@ -45,16 +46,17 @@ public struct StringsToBeDisplayed { self.cancel = cancel self.delete = delete self.useTouchID = useTouchID + self.useFaceID = useFaceID } } -public class PasscodeLockPresenter { +open class PasscodeLockPresenter { - private var mainWindow: UIWindow? + fileprivate var mainWindow: UIWindow? - public lazy var passcodeLockWindow: UIWindow = { + open lazy var passcodeLockWindow: UIWindow = { - let window = UIWindow(frame: UIScreen.mainScreen().bounds) + let window = UIWindow(frame: UIScreen.main.bounds) window.windowLevel = 0 window.makeKeyAndVisible() @@ -62,40 +64,38 @@ public class PasscodeLockPresenter { return window }() - private let passcodeConfiguration: PasscodeLockConfigurationType - public var isPasscodePresented = false - public let passcodeLockVC: PasscodeLockViewController - public var stringsToBeDisplayed: StringsToBeDisplayed? + fileprivate let passcodeConfiguration: PasscodeLockConfigurationType + open var isPasscodePresented = false + open let passcodeLockVC: PasscodeLockViewController + open var stringsToBeDisplayed: StringsToBeDisplayed? public init(mainWindow window: UIWindow?, configuration: PasscodeLockConfigurationType, viewController: PasscodeLockViewController) { mainWindow = window - mainWindow?.windowLevel = 1 passcodeConfiguration = configuration passcodeLockVC = viewController } public convenience init(mainWindow window: UIWindow?, configuration: PasscodeLockConfigurationType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { - let passcodeLockVC = PasscodeLockViewController(state: .EnterPasscode, configuration: configuration, stringsToShow: stringsToShow, tintColor: tintColor, font: font) + let passcodeLockVC = PasscodeLockViewController(state: .enterPasscode, configuration: configuration, stringsToShow: stringsToShow, tintColor: tintColor, font: font) self.init(mainWindow: window, configuration: configuration, viewController: passcodeLockVC) } - public func presentPasscodeLock(withImage image: UIImage? = nil, configuration config: PasscodeLockConfigurationType? = nil, andStrings stringsToShow: StringsToBeDisplayed? = nil, tintColor: UIColor?, font: UIFont?, dismissCompletionBlock: (() -> Void)? = nil) { + open func presentPasscodeLock(withImage image: UIImage? = nil, configuration config: PasscodeLockConfigurationType? = nil, andStrings stringsToShow: StringsToBeDisplayed? = nil, tintColor: UIColor?, font: UIFont?, dismissCompletionBlock: (() -> Void)? = nil) { guard passcodeConfiguration.repository.hasPasscode else { return } guard !isPasscodePresented else { return } isPasscodePresented = true - passcodeLockWindow.windowLevel = 2 - passcodeLockWindow.hidden = false + passcodeLockWindow.windowLevel = UIWindowLevelStatusBar + passcodeLockWindow.isHidden = false - mainWindow?.windowLevel = 1 mainWindow?.endEditing(true) - let passcodeLockVC = PasscodeLockViewController(state: .EnterPasscode, configuration: (config ?? passcodeConfiguration), stringsToShow: stringsToShow, tintColor: tintColor, font: font) + let passcodeLockVC = PasscodeLockViewController(state: .enterPasscode, configuration: (config ?? passcodeConfiguration), stringsToShow: stringsToShow, tintColor: tintColor, font: font) if (image != nil) { passcodeLockVC.customImage = image } @@ -111,10 +111,9 @@ public class PasscodeLockPresenter { passcodeLockWindow.rootViewController = passcodeLockVC } - public func dismissPasscodeLock(animated animated: Bool = true) { + open func dismissPasscodeLock(animated: Bool = true) { isPasscodePresented = false - mainWindow?.windowLevel = 1 mainWindow?.makeKeyAndVisible() if animated { @@ -130,12 +129,12 @@ public class PasscodeLockPresenter { internal func animatePasscodeLockDismissal() { - UIView.animateWithDuration( - 0.5, + UIView.animate( + withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, - options: [.CurveEaseInOut], + options: UIViewAnimationOptions(), animations: { [weak self] in self?.passcodeLockWindow.alpha = 0 diff --git a/PasscodeLock/PasscodeLockViewController.swift b/PasscodeLock/PasscodeLockViewController.swift index 25e826df..7fdf570b 100644 --- a/PasscodeLock/PasscodeLockViewController.swift +++ b/PasscodeLock/PasscodeLockViewController.swift @@ -7,50 +7,51 @@ // import UIKit +import LocalAuthentication -public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDelegate { +open class PasscodeLockViewController: UIViewController, PasscodeLockTypeDelegate { public enum LockState { - case EnterPasscode - case SetPasscode - case ChangePasscode - case RemovePasscode + case enterPasscode + case setPasscode + case changePasscode + case removePasscode - func getState(stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) -> PasscodeLockStateType { + func getState(_ stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) -> PasscodeLockStateType { switch self { - case .EnterPasscode: return EnterPasscodeState(stringsToShow: stringsToShow, tintColor: tintColor, font: font) - case .SetPasscode: return SetPasscodeState(stringsToShow: stringsToShow, tintColor: tintColor, font: font) - case .ChangePasscode: return ChangePasscodeState(stringsToShow: stringsToShow, tintColor: tintColor, font: font) - case .RemovePasscode: return EnterPasscodeState(allowCancellation: true, stringsToShow: stringsToShow, tintColor: tintColor, font: font) + case .enterPasscode: return EnterPasscodeState(stringsToShow: stringsToShow, tintColor: tintColor, font: font) + case .setPasscode: return SetPasscodeState(stringsToShow: stringsToShow, tintColor: tintColor, font: font) + case .changePasscode: return ChangePasscodeState(stringsToShow: stringsToShow, tintColor: tintColor, font: font) + case .removePasscode: return EnterPasscodeState(allowCancellation: true, stringsToShow: stringsToShow, tintColor: tintColor, font: font) } } } - @IBOutlet public var passcodeButtons : [PasscodeSignButton]? - @IBOutlet public weak var titleLabel : UILabel? - @IBOutlet public weak var customImageView : UIImageView? - @IBOutlet public weak var descriptionLabel : UILabel? - @IBOutlet public var placeholders : [PasscodeSignPlaceholderView] = [PasscodeSignPlaceholderView]() - @IBOutlet public weak var cancelDeleteButton : UIButton? - @IBOutlet public weak var touchIDButton : UIButton? - @IBOutlet public weak var placeholdersX : NSLayoutConstraint? - - public var successCallback : ((lock: PasscodeLockType) -> Void)? - public var customImage : UIImage? - public var dismissCompletionCallback : (()->Void)? - public var animateOnDismiss : Bool - public var notificationCenter : NSNotificationCenter? - public var stringsToShow : StringsToBeDisplayed? - public var closingView : Bool = false + @IBOutlet open var passcodeButtons : [PasscodeSignButton]? + @IBOutlet open weak var titleLabel : UILabel? + @IBOutlet open weak var customImageView : UIImageView? + @IBOutlet open weak var descriptionLabel : UILabel? + @IBOutlet open var placeholders : [PasscodeSignPlaceholderView] = [PasscodeSignPlaceholderView]() + @IBOutlet open weak var cancelDeleteButton : UIButton? + @IBOutlet open weak var touchIDButton : UIButton? + @IBOutlet open weak var placeholdersX : NSLayoutConstraint? + + open var successCallback : ((_ lock: PasscodeLockType) -> Void)? + open var customImage : UIImage? + open var dismissCompletionCallback : (()->Void)? + open var animateOnDismiss : Bool + open var notificationCenter : NotificationCenter? + open var stringsToShow : StringsToBeDisplayed? + open var closingView : Bool = false internal let passcodeConfiguration : PasscodeLockConfigurationType - internal let passcodeLock : PasscodeLockType + internal var passcodeLock : PasscodeLockType internal var isPlaceholdersAnimationCompleted = true - private var shouldTryToAuthenticateWithBiometrics = true - private var customTintColor : UIColor? - private var font : UIFont? + fileprivate var shouldTryToAuthenticateWithBiometrics = true + fileprivate var customTintColor : UIColor? + fileprivate var font : UIFont? // MARK: - Initializers @@ -58,16 +59,16 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg self.stringsToShow = stringToShow self.animateOnDismiss = animateOnDismiss - self.font = (font ?? UIFont.systemFontOfSize(16)) + self.font = (font ?? UIFont.systemFont(ofSize: 16)) self.customTintColor = (tintColor ?? UIColor(red: 0, green: 100/255, blue: 165/255, alpha: 1)) passcodeConfiguration = configuration passcodeLock = PasscodeLock(state: state, configuration: configuration) let nibName = "PasscodeLockView" - let bundle: NSBundle = bundleForResource(nibName, ofType: "nib") + let bundle: Bundle = bundleForResource(nibName, ofType: "nib") super.init(nibName: nibName, bundle: bundle) passcodeLock.delegate = self - notificationCenter = NSNotificationCenter.defaultCenter() + notificationCenter = NotificationCenter.default } public convenience init(state: LockState, configuration: PasscodeLockConfigurationType, animateOnDismiss: Bool = true, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { @@ -85,7 +86,7 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg // MARK: - View - public override func viewDidLoad() { + open override func viewDidLoad() { super.viewDidLoad() self.configurePasscodeButtons() @@ -93,7 +94,7 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg self.setupEvents() } - private func configurePasscodeButtons() { + fileprivate func configurePasscodeButtons() { self.placeholders.forEach { (passcodePlaceHolder: PasscodeSignPlaceholderView) in if let _customTintColor = self.customTintColor { @@ -103,7 +104,7 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg } } - public override func viewDidAppear(animated: Bool) { + open override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if shouldTryToAuthenticateWithBiometrics { @@ -111,50 +112,62 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg } } - internal func updatePasscodeView() { + internal func updatePasscodeView() { self.customImageView?.image = self.customImage - self.titleLabel?.text = passcodeLock.state.title + self.titleLabel?.text = passcodeLock.state.title self.titleLabel?.font = self.font self.titleLabel?.textColor = self.customTintColor - self.descriptionLabel?.text = passcodeLock.state.description - self.touchIDButton?.hidden = !passcodeLock.isTouchIDAllowed - self.touchIDButton?.setTitle((self.stringsToShow?.useTouchID ?? localizedStringFor("UseTouchId", comment: "")), forState: .Normal) - self.touchIDButton?.setTitleColor(self.customTintColor, forState: .Normal) + self.descriptionLabel?.text = passcodeLock.state.description + self.touchIDButton?.isHidden = !passcodeLock.isTouchIDAllowed + + var useBiometrics: String = localizedStringFor("UseTouchId", comment: "") + var useBiomatricsToShow: String? = self.stringsToShow?.useTouchID + if #available(iOS 11.0, *) { + let context = LAContext() + context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) + let bioType = context.biometryType + if (bioType == .faceID) { + useBiometrics = localizedStringFor("UseFaceId", comment: "") + useBiomatricsToShow = self.stringsToShow?.useFaceID + } + } + + self.touchIDButton?.setTitle((useBiomatricsToShow ?? useBiometrics), for: UIControlState()) self.passcodeButtons?.forEach({ (passcodeButton: PasscodeSignButton) in passcodeButton.tintColor = self.customTintColor }) self.cancelDeleteButtonSetup() - } + } // MARK: - Events - private func setupEvents() { + fileprivate func setupEvents() { - notificationCenter?.addObserver(self, selector: #selector(self.appWillEnterForegroundHandler(_:)), name: UIApplicationWillEnterForegroundNotification, object: nil) - notificationCenter?.addObserver(self, selector: #selector(PasscodeLockViewController.appDidEnterBackgroundHandler(_:)), name: UIApplicationDidEnterBackgroundNotification, object: nil) + notificationCenter?.addObserver(self, selector: #selector(self.appWillEnterForegroundHandler(_:)), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil) + notificationCenter?.addObserver(self, selector: #selector(PasscodeLockViewController.appDidEnterBackgroundHandler(_:)), name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil) } - private func clearEvents() { + fileprivate func clearEvents() { - notificationCenter?.removeObserver(self, name: UIApplicationWillEnterForegroundNotification, object: nil) - notificationCenter?.removeObserver(self, name: UIApplicationDidEnterBackgroundNotification, object: nil) + notificationCenter?.removeObserver(self, name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil) + notificationCenter?.removeObserver(self, name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil) } - public func appWillEnterForegroundHandler(notification: NSNotification) { + open func appWillEnterForegroundHandler(_ notification: Notification) { authenticateWithBiometrics() } - public func appDidEnterBackgroundHandler(notification: NSNotification) { + open func appDidEnterBackgroundHandler(_ notification: Notification) { shouldTryToAuthenticateWithBiometrics = false } // MARK: - Actions - @IBAction func passcodeSignButtonTap(sender: PasscodeSignButton) { + @IBAction func passcodeSignButtonTap(_ sender: PasscodeSignButton) { guard isPlaceholdersAnimationCompleted else { return @@ -163,12 +176,12 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg passcodeLock.addSign(sender.passcodeSign, stringsToBeDisplayed: self.stringsToShow, tintColor: customTintColor, font: font) } - @IBAction func cancelButtonTap(sender: UIButton) { + @IBAction func cancelButtonTap(_ sender: UIButton) { dismissPasscodeLock(passcodeLock) } - @IBAction func deleteSignButtonTap(sender: UIButton) { + @IBAction func deleteSignButtonTap(_ sender: UIButton) { if (passcodeLock.isPincodeEmpty == true && passcodeLock.state.isCancellableAction == true) { dismissPasscodeLock(passcodeLock) @@ -178,24 +191,24 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg } } - @IBAction func touchIDButtonTap(sender: UIButton) { + @IBAction func touchIDButtonTap(_ sender: UIButton) { passcodeLock.authenticateWithBiometrics(self.stringsToShow) } - private func authenticateWithBiometrics() { + fileprivate func authenticateWithBiometrics() { if (passcodeConfiguration.shouldRequestTouchIDImmediately == true && passcodeLock.isTouchIDAllowed == true) { passcodeLock.authenticateWithBiometrics(self.stringsToShow) } } - internal func dismissPasscodeLock(lock: PasscodeLockType, completionHandler: (() -> Void)? = nil) { + internal func dismissPasscodeLock(_ lock: PasscodeLockType, completionHandler: (() -> Void)? = nil) { // if presented as modal if (presentingViewController?.presentedViewController == self) { - dismissViewControllerAnimated(animateOnDismiss, completion: { [weak self] _ in + dismiss(animated: animateOnDismiss, completion: { [weak self] _ in self?.dismissCompletionCallback?() completionHandler?() }) @@ -204,7 +217,7 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg // if pushed in a navigation controller } else if navigationController != nil { - navigationController?.popViewControllerAnimated(animateOnDismiss) + navigationController?.popViewController(animated: animateOnDismiss) } dismissCompletionCallback?() @@ -218,29 +231,29 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg self.cancelDeleteButtonSetup() isPlaceholdersAnimationCompleted = false - animatePlaceholders(placeholders, toState: .Error) + animatePlaceholders(placeholders, toState: .error) placeholdersX?.constant = -40 view.layoutIfNeeded() - UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 0, options: [], animations: { + UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 0, options: [], animations: { self.placeholdersX?.constant = 0 self.view.layoutIfNeeded() }, completion: { completed in self.isPlaceholdersAnimationCompleted = true - self.animatePlaceholders(self.placeholders, toState: .Inactive) + self.animatePlaceholders(self.placeholders, toState: .inactive) }) } - internal func animatePlaceholders(placeholders: [PasscodeSignPlaceholderView], toState state: PasscodeSignPlaceholderView.State) { + internal func animatePlaceholders(_ placeholders: [PasscodeSignPlaceholderView], toState state: PasscodeSignPlaceholderView.State) { for placeholder in placeholders { placeholder.animateState(state) } } - private func animatePlacehodlerAtIndex(index: Int, toState state: PasscodeSignPlaceholderView.State) { + fileprivate func animatePlacehodlerAtIndex(_ index: Int, toState state: PasscodeSignPlaceholderView.State) { guard (index < placeholders.count && index >= 0) else { return @@ -251,55 +264,55 @@ public class PasscodeLockViewController: UIViewController, PasscodeLockTypeDeleg // MARK: - PasscodeLockDelegate - public func passcodeLockDidSucceed(lock: PasscodeLockType) { + open func passcodeLockDidSucceed(_ lock: PasscodeLockType) { self.cancelDeleteButtonSetup() - animatePlaceholders(placeholders, toState: .Inactive) + animatePlaceholders(placeholders, toState: .inactive) dismissPasscodeLock(lock, completionHandler: { [weak self] _ in - self?.successCallback?(lock: lock) + self?.successCallback?(lock) }) } - public func passcodeLockDidFail(lock: PasscodeLockType) { + open func passcodeLockDidFail(_ lock: PasscodeLockType) { animateWrongPassword() } - public func passcodeLockDidChangeState(lock: PasscodeLockType) { + open func passcodeLockDidChangeState(_ lock: PasscodeLockType) { updatePasscodeView() - animatePlaceholders(placeholders, toState: .Inactive) + animatePlaceholders(placeholders, toState: .inactive) self.cancelDeleteButtonSetup() } - public func passcodeLock(lock: PasscodeLockType, addedSignAtIndex index: Int) { + open func passcodeLock(_ lock: PasscodeLockType, addedSignAtIndex index: Int) { - animatePlacehodlerAtIndex(index, toState: .Active) + animatePlacehodlerAtIndex(index, toState: .active) self.cancelDeleteButtonSetup() } - public func passcodeLock(lock: PasscodeLockType, removedSignAtIndex index: Int) { + open func passcodeLock(_ lock: PasscodeLockType, removedSignAtIndex index: Int) { - animatePlacehodlerAtIndex(index, toState: .Inactive) + animatePlacehodlerAtIndex(index, toState: .inactive) if (index == 0) { self.cancelDeleteButtonSetup() } } - public func cancelDeleteButtonSetup() { + open func cancelDeleteButtonSetup() { let cancelButton = ((self.passcodeLock.isPincodeEmpty == true) ? (self.stringsToShow?.cancel ?? localizedStringFor("Cancel", comment: "")) : (self.stringsToShow?.delete ?? localizedStringFor("Delete", comment: ""))) let titleForButton = ((self.passcodeLock.state.isCancellableAction == true) ? cancelButton : (self.stringsToShow?.delete ?? localizedStringFor("Delete", comment: ""))) - self.cancelDeleteButton?.setTitle(titleForButton, forState: .Normal) - self.cancelDeleteButton?.setTitleColor(self.customTintColor, forState: .Normal) - self.cancelDeleteButton?.setTitleColor(self.customTintColor?.colorWithAlphaComponent(0.5), forState: .Disabled) + self.cancelDeleteButton?.setTitle(titleForButton, for: UIControlState()) + self.cancelDeleteButton?.setTitleColor(self.customTintColor, for: UIControlState()) + self.cancelDeleteButton?.setTitleColor(self.customTintColor?.withAlphaComponent(0.5), for: .disabled) self.cancelDeleteButton?.titleLabel?.font = self.font if (self.passcodeLock.isPincodeEmpty == true && self.passcodeLock.state.isCancellableAction == false) { - self.cancelDeleteButton?.enabled = false + self.cancelDeleteButton?.isEnabled = false } else { - self.cancelDeleteButton?.enabled = true + self.cancelDeleteButton?.isEnabled = true } } } diff --git a/PasscodeLock/Protocols/PasscodeLockStateType.swift b/PasscodeLock/Protocols/PasscodeLockStateType.swift index 59c07353..c933bc82 100644 --- a/PasscodeLock/Protocols/PasscodeLockStateType.swift +++ b/PasscodeLock/Protocols/PasscodeLockStateType.swift @@ -16,5 +16,5 @@ public protocol PasscodeLockStateType { var isTouchIDAllowed : Bool {get} var tintColor : UIColor? {get} - mutating func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) + mutating func acceptPasscode(_ passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) } diff --git a/PasscodeLock/Protocols/PasscodeLockType.swift b/PasscodeLock/Protocols/PasscodeLockType.swift index 257d005e..ba1ff638 100644 --- a/PasscodeLock/Protocols/PasscodeLockType.swift +++ b/PasscodeLock/Protocols/PasscodeLockType.swift @@ -7,6 +7,7 @@ // import Foundation +import UIKit public protocol PasscodeLockType { @@ -17,17 +18,17 @@ public protocol PasscodeLockType { var isTouchIDAllowed: Bool {get} var isPincodeEmpty: Bool {get} - func addSign(sign: String, stringsToBeDisplayed: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) + func addSign(_ sign: String, stringsToBeDisplayed: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) func removeSign() - func changeStateTo(state: PasscodeLockStateType) - func authenticateWithBiometrics(stringsToShow: StringsToBeDisplayed?) + func changeStateTo(_ state: PasscodeLockStateType) + func authenticateWithBiometrics(_ stringsToShow: StringsToBeDisplayed?) } public protocol PasscodeLockTypeDelegate: class { - func passcodeLockDidSucceed(lock: PasscodeLockType) - func passcodeLockDidFail(lock: PasscodeLockType) - func passcodeLockDidChangeState(lock: PasscodeLockType) - func passcodeLock(lock: PasscodeLockType, addedSignAtIndex index: Int) - func passcodeLock(lock: PasscodeLockType, removedSignAtIndex index: Int) + func passcodeLockDidSucceed(_ lock: PasscodeLockType) + func passcodeLockDidFail(_ lock: PasscodeLockType) + func passcodeLockDidChangeState(_ lock: PasscodeLockType) + func passcodeLock(_ lock: PasscodeLockType, addedSignAtIndex index: Int) + func passcodeLock(_ lock: PasscodeLockType, removedSignAtIndex index: Int) } diff --git a/PasscodeLock/Protocols/PasscodeRepositoryType.swift b/PasscodeLock/Protocols/PasscodeRepositoryType.swift index 19272379..79475434 100644 --- a/PasscodeLock/Protocols/PasscodeRepositoryType.swift +++ b/PasscodeLock/Protocols/PasscodeRepositoryType.swift @@ -13,6 +13,6 @@ public protocol PasscodeRepositoryType { var hasPasscode: Bool {get} var passcode: [String]? {get} - func savePasscode(passcode: [String]) + func savePasscode(_ passcode: [String]) func deletePasscode() } diff --git a/PasscodeLock/Views/PasscodeLockView.xib b/PasscodeLock/Views/PasscodeLockView.xib index 694aaf33..339d3782 100644 --- a/PasscodeLock/Views/PasscodeLockView.xib +++ b/PasscodeLock/Views/PasscodeLockView.xib @@ -1,5 +1,5 @@ - + @@ -328,23 +328,33 @@ - + + + + + + + + + + + @@ -355,7 +365,7 @@ - + @@ -387,10 +397,10 @@ + - @@ -402,6 +412,7 @@ + diff --git a/PasscodeLock/Views/PasscodeSignButton.swift b/PasscodeLock/Views/PasscodeSignButton.swift index ceb08817..7dfd2e10 100644 --- a/PasscodeLock/Views/PasscodeSignButton.swift +++ b/PasscodeLock/Views/PasscodeSignButton.swift @@ -8,12 +8,12 @@ import UIKit -public class PasscodeSignButton: UIButton { +open class PasscodeSignButton: UIButton { - public var passcodeSign: String = "1" - public var customTintColor: UIColor? = UIColor(red: 0, green: 100/255, blue: 165/255, alpha: 1) + open var passcodeSign: String = "1" + open var customTintColor: UIColor? = UIColor(red: 0, green: 100/255, blue: 165/255, alpha: 1) - public override func awakeFromNib() { + open override func awakeFromNib() { super.awakeFromNib() self.tintColor = customTintColor diff --git a/PasscodeLock/Views/PasscodeSignPlaceholderView.swift b/PasscodeLock/Views/PasscodeSignPlaceholderView.swift index b769d230..c6c30d56 100644 --- a/PasscodeLock/Views/PasscodeSignPlaceholderView.swift +++ b/PasscodeLock/Views/PasscodeSignPlaceholderView.swift @@ -9,30 +9,30 @@ import UIKit @IBDesignable -public class PasscodeSignPlaceholderView: UIView { +open class PasscodeSignPlaceholderView: UIView { public enum State { - case Inactive - case Active - case Error + case inactive + case active + case error } @IBInspectable - public var inactiveColor: UIColor = UIColor.whiteColor() { + open var inactiveColor: UIColor = UIColor.white { didSet { self.setupView() } } @IBInspectable - public var activeColor: UIColor = UIColor.grayColor() { + open var activeColor: UIColor = UIColor.gray { didSet { self.setupView() } } @IBInspectable - public var errorColor: UIColor = UIColor.redColor() { + open var errorColor: UIColor = UIColor.red { didSet { self.setupView() } @@ -50,35 +50,35 @@ public class PasscodeSignPlaceholderView: UIView { super.init(coder: aDecoder) } - public override func intrinsicContentSize() -> CGSize { + open override var intrinsicContentSize : CGSize { - return CGSizeMake(16, 16) + return CGSize(width: 16, height: 16) } func setupView() { layer.cornerRadius = 7 layer.borderWidth = 1 - layer.borderColor = activeColor.CGColor + layer.borderColor = activeColor.cgColor backgroundColor = inactiveColor } - private func colorsForState(state: State) -> (backgroundColor: UIColor, borderColor: UIColor) { + fileprivate func colorsForState(_ state: State) -> (backgroundColor: UIColor, borderColor: UIColor) { switch state { - case .Inactive: return (inactiveColor, activeColor) - case .Active: return (activeColor, activeColor) - case .Error: return (errorColor, errorColor) + case .inactive: return (inactiveColor, activeColor) + case .active: return (activeColor, activeColor) + case .error: return (errorColor, errorColor) } } - public func animateState(state: State, completion: (() -> Void)? = nil) { + open func animateState(_ state: State, completion: (() -> Void)? = nil) { let colors = colorsForState(state) - UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [], animations: { [weak self] in + UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [], animations: { [weak self] in self?.backgroundColor = colors.backgroundColor - self?.layer.borderColor = colors.borderColor.CGColor + self?.layer.borderColor = colors.borderColor.cgColor }, completion: nil) } diff --git a/PasscodeLock/de.lproj/Localize.strings b/PasscodeLock/de.lproj/Localize.strings index d0d12f90..a5f13fae 100644 --- a/PasscodeLock/de.lproj/Localize.strings +++ b/PasscodeLock/de.lproj/Localize.strings @@ -35,3 +35,4 @@ "Cancel" = "Abbrechen"; "Delete" = "Löschen"; "UseTouchId" = "TouchID verwenden"; +"UseFaceId" = "FaceID verwenden"; diff --git a/PasscodeLock/en.lproj/Localize.strings b/PasscodeLock/en.lproj/Localize.strings new file mode 100644 index 00000000..1c83f62c --- /dev/null +++ b/PasscodeLock/en.lproj/Localize.strings @@ -0,0 +1,38 @@ +/* + Localize.strings + PasscodeLock + + Created by Ramiro Ramirez on 18/10/16. + Copyright © 2016 Yanko Dimitrov. All rights reserved. +*/ + +/* Enter Passcode State */ +"PasscodeLockEnterTitle" = "Enter Passcode"; +"PasscodeLockEnterDescription" = "Enter your passcode to proceed."; + +/* Set Passcode State */ +"PasscodeLockSetTitle" = "Enter a Passcode"; +"PasscodeLockSetDescription" = "Choose your passcode."; + +/* Confirm Passcode State */ +"PasscodeLockConfirmTitle" = "Confirm Passcode"; +"PasscodeLockConfirmDescription" = "Enter the passcode again."; + +/* Change Passcode State */ +"PasscodeLockChangeTitle" = "Enter Old Passcode"; +"PasscodeLockChangeDescription" = "Enter your old passcode."; + +/* Passcode Mismatch State */ +"PasscodeLockMismatchTitle" = "Try again"; +"PasscodeLockMismatchDescription" = "Passcodes didn\'t match."; + +/* Touch ID Reason */ +"PasscodeLockTouchIDReason" = "Authentication required to proceed"; + +/* Touch ID Fallback Button */ +"PasscodeLockTouchIDButton" = "Enter Passcode"; + +"Cancel" = "Cancel"; +"Delete" = "Delete"; +"UseTouchId" = "Use TouchID"; +"UseFaceId" = "Use FaceID"; diff --git a/PasscodeLockTests/Fakes/FakePasscodeLock.swift b/PasscodeLockTests/Fakes/FakePasscodeLock.swift index 518710e3..0f5ba9fa 100644 --- a/PasscodeLockTests/Fakes/FakePasscodeLock.swift +++ b/PasscodeLockTests/Fakes/FakePasscodeLock.swift @@ -7,15 +7,17 @@ // import Foundation +import PasscodeLock class FakePasscodeLock: PasscodeLockType { - + weak var delegate: PasscodeLockTypeDelegate? let configuration: PasscodeLockConfigurationType var repository: PasscodeRepositoryType { return configuration.repository } var state: PasscodeLockStateType { return lockState } let isTouchIDAllowed = false var lockState: PasscodeLockStateType + var isPincodeEmpty: Bool = false var changeStateCalled = false @@ -25,7 +27,7 @@ class FakePasscodeLock: PasscodeLockType { self.configuration = configuration } - func addSign(sign: String) { + func addSign(_ sign: String, stringsToBeDisplayed: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { } @@ -33,14 +35,14 @@ class FakePasscodeLock: PasscodeLockType { } - func changeStateTo(state: PasscodeLockStateType) { + func changeStateTo(_ state: PasscodeLockStateType) { lockState = state changeStateCalled = true delegate?.passcodeLockDidChangeState(self) } - - func authenticateWithBiometrics() { + + func authenticateWithBiometrics(_ stringsToShow: StringsToBeDisplayed?) { } } diff --git a/PasscodeLockTests/Fakes/FakePasscodeLockConfiguration.swift b/PasscodeLockTests/Fakes/FakePasscodeLockConfiguration.swift index 1cae5788..25fd6534 100644 --- a/PasscodeLockTests/Fakes/FakePasscodeLockConfiguration.swift +++ b/PasscodeLockTests/Fakes/FakePasscodeLockConfiguration.swift @@ -7,6 +7,7 @@ // import Foundation +import PasscodeLock class FakePasscodeLockConfiguration: PasscodeLockConfigurationType { diff --git a/PasscodeLockTests/Fakes/FakePasscodeLockDelegate.swift b/PasscodeLockTests/Fakes/FakePasscodeLockDelegate.swift index 3d82b9bf..c2de9915 100644 --- a/PasscodeLockTests/Fakes/FakePasscodeLockDelegate.swift +++ b/PasscodeLockTests/Fakes/FakePasscodeLockDelegate.swift @@ -7,12 +7,13 @@ // import Foundation +import PasscodeLock class FakePasscodeLockDelegate: PasscodeLockTypeDelegate { - func passcodeLockDidSucceed(lock: PasscodeLockType) {} - func passcodeLockDidFail(lock: PasscodeLockType) {} - func passcodeLockDidChangeState(lock: PasscodeLockType) {} - func passcodeLock(lock: PasscodeLockType, addedSignAtIndex index: Int) {} - func passcodeLock(lock: PasscodeLockType, removedSignAtIndex index: Int) {} + func passcodeLockDidSucceed(_ lock: PasscodeLockType) {} + func passcodeLockDidFail(_ lock: PasscodeLockType) {} + func passcodeLockDidChangeState(_ lock: PasscodeLockType) {} + func passcodeLock(_ lock: PasscodeLockType, addedSignAtIndex index: Int) {} + func passcodeLock(_ lock: PasscodeLockType, removedSignAtIndex index: Int) {} } diff --git a/PasscodeLockTests/Fakes/FakePasscodeRepository.swift b/PasscodeLockTests/Fakes/FakePasscodeRepository.swift index 657b67fc..788a2856 100644 --- a/PasscodeLockTests/Fakes/FakePasscodeRepository.swift +++ b/PasscodeLockTests/Fakes/FakePasscodeRepository.swift @@ -7,6 +7,7 @@ // import Foundation +import PasscodeLock class FakePasscodeRepository: PasscodeRepositoryType { @@ -18,7 +19,7 @@ class FakePasscodeRepository: PasscodeRepositoryType { var savePasscodeCalled = false var savedPasscode = [String]() - func savePasscode(passcode: [String]) { + func savePasscode(_ passcode: [String]) { savePasscodeCalled = true savedPasscode = passcode diff --git a/PasscodeLockTests/Fakes/FakePasscodeState.swift b/PasscodeLockTests/Fakes/FakePasscodeState.swift index 61bc3e3c..e6c9d42c 100644 --- a/PasscodeLockTests/Fakes/FakePasscodeState.swift +++ b/PasscodeLockTests/Fakes/FakePasscodeState.swift @@ -7,24 +7,25 @@ // import Foundation +import PasscodeLock class FakePasscodeState: PasscodeLockStateType { - + var title = "A" var description = "B" var isCancellableAction = true var isTouchIDAllowed = true - + var tintColor: UIColor? + var acceptPaccodeCalled = false var acceptedPasscode = [String]() var numberOfAcceptedPasscodes = 0 - + init() {} - - func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType) { - - acceptedPasscode = passcode - acceptPaccodeCalled = true - numberOfAcceptedPasscodes += 1 - } + + func acceptPasscode(_ passcode: [String], fromLock lock: PasscodeLockType, stringsToShow: StringsToBeDisplayed?, tintColor: UIColor?, font: UIFont?) { + acceptedPasscode = passcode + acceptPaccodeCalled = true + numberOfAcceptedPasscodes += 1 + } } diff --git a/PasscodeLockTests/PasscodeLock/ChangePasscodeStateTests.swift b/PasscodeLockTests/PasscodeLock/ChangePasscodeStateTests.swift index eade20ca..80a8cf9b 100644 --- a/PasscodeLockTests/PasscodeLock/ChangePasscodeStateTests.swift +++ b/PasscodeLockTests/PasscodeLock/ChangePasscodeStateTests.swift @@ -7,6 +7,7 @@ // import XCTest +@testable import PasscodeLock class ChangePasscodeStateTests: XCTestCase { @@ -21,7 +22,7 @@ class ChangePasscodeStateTests: XCTestCase { let config = FakePasscodeLockConfiguration(repository: repository) - passcodeState = ChangePasscodeState() + passcodeState = ChangePasscodeState(stringsToShow: nil, tintColor: nil, font: nil) passcodeLock = FakePasscodeLock(state: passcodeState, configuration: config) } @@ -31,7 +32,7 @@ class ChangePasscodeStateTests: XCTestCase { var didChangedState = false - override func passcodeLockDidChangeState(lock: PasscodeLockType) { + override func passcodeLockDidChangeState(_ lock: PasscodeLockType) { didChangedState = true } @@ -40,7 +41,7 @@ class ChangePasscodeStateTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeState.acceptPasscode(repository.fakePasscode, fromLock: passcodeLock) + passcodeState.acceptPasscode(repository.fakePasscode, fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssert(passcodeLock.state is SetPasscodeState, "Should change the state to SetPasscodeState") XCTAssertEqual(delegate.didChangedState, true, "Should call the delegate when the passcode is correct") @@ -52,7 +53,7 @@ class ChangePasscodeStateTests: XCTestCase { var called = false - override func passcodeLockDidFail(lock: PasscodeLockType) { + override func passcodeLockDidFail(_ lock: PasscodeLockType) { called = true } @@ -61,7 +62,7 @@ class ChangePasscodeStateTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeState.acceptPasscode(["0", "0", "0", "0"], fromLock: passcodeLock) + passcodeState.acceptPasscode(["0", "0", "0", "0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssertEqual(delegate.called, true, "Should call the delegate when the passcode is incorrect") } diff --git a/PasscodeLockTests/PasscodeLock/ConfirmPasscodeStateTests.swift b/PasscodeLockTests/PasscodeLock/ConfirmPasscodeStateTests.swift index f122f702..ee1eb383 100644 --- a/PasscodeLockTests/PasscodeLock/ConfirmPasscodeStateTests.swift +++ b/PasscodeLockTests/PasscodeLock/ConfirmPasscodeStateTests.swift @@ -7,6 +7,7 @@ // import XCTest +@testable import PasscodeLock class ConfirmPasscodeStateTests: XCTestCase { @@ -22,7 +23,7 @@ class ConfirmPasscodeStateTests: XCTestCase { let config = FakePasscodeLockConfiguration(repository: repository) - passcodeState = ConfirmPasscodeState(passcode: passcodeToConfirm) + passcodeState = ConfirmPasscodeState(passcode: passcodeToConfirm, stringsToShow: nil, tintColor: nil, font: nil) passcodeLock = FakePasscodeLock(state: passcodeState, configuration: config) } @@ -32,7 +33,7 @@ class ConfirmPasscodeStateTests: XCTestCase { var called = false - override func passcodeLockDidSucceed(lock: PasscodeLockType) { + override func passcodeLockDidSucceed(_ lock: PasscodeLockType) { called = true } @@ -41,14 +42,14 @@ class ConfirmPasscodeStateTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeState.acceptPasscode(passcodeToConfirm, fromLock: passcodeLock) + passcodeState.acceptPasscode(passcodeToConfirm, fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssertEqual(delegate.called, true, "Should call the delegate when the passcode is correct") } func testAcceptCorrectPasscodeWillSaveThePasscode() { - passcodeState.acceptPasscode(passcodeToConfirm, fromLock: passcodeLock) + passcodeState.acceptPasscode(passcodeToConfirm, fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssertEqual(repository.savePasscodeCalled, true, "Should call the repository to save the new passcode") XCTAssertEqual(repository.savedPasscode, passcodeToConfirm, "Should save the confirmed passcode") @@ -61,12 +62,12 @@ class ConfirmPasscodeStateTests: XCTestCase { var didFailed = false var didChangedState = false - override func passcodeLockDidFail(lock: PasscodeLockType) { + override func passcodeLockDidFail(_ lock: PasscodeLockType) { didFailed = true } - override func passcodeLockDidChangeState(lock: PasscodeLockType) { + override func passcodeLockDidChangeState(_ lock: PasscodeLockType) { didChangedState = true } @@ -75,7 +76,7 @@ class ConfirmPasscodeStateTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeState.acceptPasscode(["1", "2"], fromLock: passcodeLock) + passcodeState.acceptPasscode(["1", "2"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssertEqual(passcodeLock.changeStateCalled, true, "Should change the state") XCTAssert(passcodeLock.state is SetPasscodeState, "Should change the state to SetPasscodeState") diff --git a/PasscodeLockTests/PasscodeLock/EnterPasscodeStateTests.swift b/PasscodeLockTests/PasscodeLock/EnterPasscodeStateTests.swift index 2e4dcf94..6c850947 100644 --- a/PasscodeLockTests/PasscodeLock/EnterPasscodeStateTests.swift +++ b/PasscodeLockTests/PasscodeLock/EnterPasscodeStateTests.swift @@ -7,20 +7,21 @@ // import XCTest +@testable import PasscodeLock class NotificaionObserver: NSObject { var called = false var callCounter = 0 - func observe(notification: String) { + func observe(_ notification: String) { - let center = NSNotificationCenter.defaultCenter() + let center = NotificationCenter.default - center.addObserver(self, selector: "handle:", name: notification, object: nil) + center.addObserver(self, selector: #selector(NotificaionObserver.handle(_:)), name: NSNotification.Name(rawValue: notification), object: nil) } - func handle(notification: NSNotification) { + func handle(_ notification: Notification) { called = true callCounter += 1 @@ -40,7 +41,7 @@ class EnterPasscodeStateTests: XCTestCase { let config = FakePasscodeLockConfiguration(repository: repository) - passcodeState = EnterPasscodeState() + passcodeState = EnterPasscodeState(stringsToShow: nil, tintColor: nil, font: nil) passcodeLock = FakePasscodeLock(state: passcodeState, configuration: config) } @@ -50,7 +51,7 @@ class EnterPasscodeStateTests: XCTestCase { var called = false - override func passcodeLockDidSucceed(lock: PasscodeLockType) { + override func passcodeLockDidSucceed(_ lock: PasscodeLockType) { called = true } @@ -59,7 +60,7 @@ class EnterPasscodeStateTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeState.acceptPasscode(repository.fakePasscode, fromLock: passcodeLock) + passcodeState.acceptPasscode(repository.fakePasscode, fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssertEqual(delegate.called, true, "Should call the delegate when the passcode is correct") } @@ -70,7 +71,7 @@ class EnterPasscodeStateTests: XCTestCase { var called = false - override func passcodeLockDidFail(lock: PasscodeLockType) { + override func passcodeLockDidFail(_ lock: PasscodeLockType) { called = true } @@ -79,7 +80,7 @@ class EnterPasscodeStateTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeState.acceptPasscode(["0", "0", "0", "0"], fromLock: passcodeLock) + passcodeState.acceptPasscode(["0", "0", "0", "0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssertEqual(delegate.called, true, "Should call the delegate when the passcode is incorrect") } @@ -90,9 +91,9 @@ class EnterPasscodeStateTests: XCTestCase { observer.observe(PasscodeLockIncorrectPasscodeNotification) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssertEqual(observer.called, true, "Should send a notificaiton when the maximum number of incorrect attempts is reached") } @@ -103,13 +104,13 @@ class EnterPasscodeStateTests: XCTestCase { observer.observe(PasscodeLockIncorrectPasscodeNotification) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) - passcodeState.acceptPasscode(["0"], fromLock: passcodeLock) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) + passcodeState.acceptPasscode(["0"], fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssertEqual(observer.callCounter, 1, "Should send the notification only once") } diff --git a/PasscodeLockTests/PasscodeLock/PasscodeLockTests.swift b/PasscodeLockTests/PasscodeLock/PasscodeLockTests.swift index efb192a3..a3044d30 100644 --- a/PasscodeLockTests/PasscodeLock/PasscodeLockTests.swift +++ b/PasscodeLockTests/PasscodeLock/PasscodeLockTests.swift @@ -7,6 +7,7 @@ // import XCTest +@testable import PasscodeLock class PasscodeLockTests: XCTestCase { @@ -29,7 +30,7 @@ class PasscodeLockTests: XCTestCase { var called = false - override func passcodeLockDidChangeState(lock: PasscodeLockType) { + override func passcodeLockDidChangeState(_ lock: PasscodeLockType) { called = true } @@ -51,7 +52,7 @@ class PasscodeLockTests: XCTestCase { var called = false var signIndex = 0 - override func passcodeLock(lock: PasscodeLockType, addedSignAtIndex index: Int) { + override func passcodeLock(_ lock: PasscodeLockType, addedSignAtIndex index: Int) { called = true signIndex = index @@ -61,12 +62,12 @@ class PasscodeLockTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeLock.addSign("1") + passcodeLock.addSign("1", stringsToBeDisplayed: nil, tintColor: nil, font: nil) XCTAssertEqual(delegate.called, true, "Should inform the delegate for added sign at index") XCTAssertEqual(delegate.signIndex, 0, "Should return the added sign index") - passcodeLock.addSign("2") + passcodeLock.addSign("2", stringsToBeDisplayed: nil, tintColor: nil, font: nil) XCTAssertEqual(delegate.signIndex, 1, "Should return the added sign index") } @@ -78,7 +79,7 @@ class PasscodeLockTests: XCTestCase { var called = false var signIndex = 0 - override func passcodeLock(lock: PasscodeLockType, removedSignAtIndex index: Int) { + override func passcodeLock(_ lock: PasscodeLockType, removedSignAtIndex index: Int) { called = true signIndex = index @@ -88,8 +89,8 @@ class PasscodeLockTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeLock.addSign("1") - passcodeLock.addSign("2") + passcodeLock.addSign("1", stringsToBeDisplayed: nil, tintColor: nil, font: nil) + passcodeLock.addSign("2", stringsToBeDisplayed: nil, tintColor: nil, font: nil) passcodeLock.removeSign() @@ -106,7 +107,7 @@ class PasscodeLockTests: XCTestCase { for sign in passcode { - passcodeLock.addSign(sign) + passcodeLock.addSign(sign, stringsToBeDisplayed: nil, tintColor: nil, font: nil) } XCTAssertEqual(initialState.acceptPaccodeCalled, true, "When the passcode length is reached should call the current state to accept the entered passcode") @@ -121,12 +122,12 @@ class PasscodeLockTests: XCTestCase { for sign in passcodeOne { - passcodeLock.addSign(sign) + passcodeLock.addSign(sign, stringsToBeDisplayed: nil, tintColor: nil, font: nil) } for sign in passcodeTwo { - passcodeLock.addSign(sign) + passcodeLock.addSign(sign, stringsToBeDisplayed: nil, tintColor: nil, font: nil) } XCTAssertEqual(initialState.numberOfAcceptedPasscodes, 2, "Should call the accept passcode twice") diff --git a/PasscodeLockTests/PasscodeLock/SetPasscodeStateTests.swift b/PasscodeLockTests/PasscodeLock/SetPasscodeStateTests.swift index 20ef1214..1748af63 100644 --- a/PasscodeLockTests/PasscodeLock/SetPasscodeStateTests.swift +++ b/PasscodeLockTests/PasscodeLock/SetPasscodeStateTests.swift @@ -7,6 +7,7 @@ // import XCTest +@testable import PasscodeLock class SetPasscodeStateTests: XCTestCase { @@ -21,7 +22,7 @@ class SetPasscodeStateTests: XCTestCase { let config = FakePasscodeLockConfiguration(repository: repository) - passcodeState = SetPasscodeState() + passcodeState = SetPasscodeState(stringsToShow: nil, tintColor: nil, font: nil) passcodeLock = FakePasscodeLock(state: passcodeState, configuration: config) } @@ -31,7 +32,7 @@ class SetPasscodeStateTests: XCTestCase { var didChangedState = false - override func passcodeLockDidChangeState(lock: PasscodeLockType) { + override func passcodeLockDidChangeState(_ lock: PasscodeLockType) { didChangedState = true } @@ -40,7 +41,7 @@ class SetPasscodeStateTests: XCTestCase { let delegate = MockDelegate() passcodeLock.delegate = delegate - passcodeState.acceptPasscode(repository.fakePasscode, fromLock: passcodeLock) + passcodeState.acceptPasscode(repository.fakePasscode, fromLock: passcodeLock, stringsToShow: nil, tintColor: nil, font: nil) XCTAssert(passcodeLock.state is ConfirmPasscodeState, "Should change the state to ConfirmPasscodeState") XCTAssertEqual(delegate.didChangedState, true, "Should inform the delegate for the state change") diff --git a/SMFPasscodeLock.podspec b/SMFPasscodeLock.podspec index c21044d9..803339c9 100755 --- a/SMFPasscodeLock.podspec +++ b/SMFPasscodeLock.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'SMFPasscodeLock' - s.version = '1.0.10' + s.version = '2.0.1' s.license = { :type => "MIT", :file => 'LICENSE.txt' } s.summary = 'SMF Fork of PasscodeLock: An iOS passcode lock with Touch ID authentication written in Swift.' s.homepage = 'https://github.com/smartmobilefactory/SwiftPasscodeLock'