Merge pull request #54 from TouchInstinct/feature/passCodeCount
Feature/pass code count
This commit is contained in:
commit
9b5c16b7da
|
|
@ -1,5 +1,11 @@
|
|||
# Changelog
|
||||
|
||||
### 0.3.6
|
||||
|
||||
- **Update**: PassCodeError, now emmit `tooManyAttempts` in any operation (*create* / *change* / *enter*) type.
|
||||
- **Update**: Rename `PassCodeControllerType` to `PassCodeOperationType`.
|
||||
- **Update**: `showBiometricsRequestIfNeeded` method become public.
|
||||
|
||||
### 0.3.5
|
||||
|
||||
- **Update**: Migrate to Swift 4.2 & Xcode 10. Update dependencies.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = "LeadKitAdditions"
|
||||
s.version = "0.3.5"
|
||||
s.version = "0.3.6"
|
||||
s.summary = "iOS framework with a bunch of tools for rapid development"
|
||||
s.homepage = "https://github.com/TouchInstinct/LeadKitAdditions"
|
||||
s.license = "Apache License, Version 2.0"
|
||||
|
|
|
|||
|
|
@ -21,13 +21,15 @@
|
|||
//
|
||||
|
||||
/// Describes error, which may occur during pass code entering
|
||||
/// - codesNotMatch: Different codes
|
||||
/// - wrongCode: Value is remaining attemps
|
||||
/// - tooManyAttempts: Attempts limit reached
|
||||
public enum PassCodeError: Error {
|
||||
/// Different codes
|
||||
case codesNotMatch
|
||||
case wrongCode(Int)
|
||||
case tooManyAttempts
|
||||
|
||||
/// Value is remaining attemps
|
||||
case wrongCode(attemptsRemaining: Int)
|
||||
|
||||
/// Attempts limit reached (for create, change or enter)
|
||||
case tooManyAttempts(type: PassCodeOperationType)
|
||||
}
|
||||
|
||||
public extension PassCodeError {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public extension PassCodeHolderProtocol {
|
|||
/// Holds information about pass codes during pass code creation process
|
||||
public class PassCodeHolderCreate: PassCodeHolderProtocol {
|
||||
|
||||
public let type: PassCodeControllerType = .create
|
||||
public let type: PassCodeOperationType = .create
|
||||
|
||||
private var firstPassCode: String?
|
||||
private var secondPassCode: String?
|
||||
|
|
@ -95,7 +95,7 @@ public class PassCodeHolderCreate: PassCodeHolderProtocol {
|
|||
/// Holds information about pass code during pass code entering process
|
||||
public class PassCodeHolderEnter: PassCodeHolderProtocol {
|
||||
|
||||
public let type: PassCodeControllerType = .enter
|
||||
public let type: PassCodeOperationType = .enter
|
||||
public let enterStep: PassCodeControllerState = .enter
|
||||
|
||||
public var shouldValidate: Bool {
|
||||
|
|
@ -125,7 +125,7 @@ public class PassCodeHolderEnter: PassCodeHolderProtocol {
|
|||
/// Holds information about pass codes during pass code changing process
|
||||
public class PassCodeHolderChange: PassCodeHolderProtocol {
|
||||
|
||||
public let type: PassCodeControllerType = .change
|
||||
public let type: PassCodeOperationType = .change
|
||||
|
||||
private var oldPassCode: String?
|
||||
private var newFirstPassCode: String?
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
public protocol PassCodeHolderProtocol {
|
||||
|
||||
/// Type of operation with pass code
|
||||
var type: PassCodeControllerType { get }
|
||||
var type: PassCodeOperationType { get }
|
||||
/// Operation step
|
||||
var enterStep: PassCodeControllerState { get }
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ public class PassCodeHolderBuilder {
|
|||
- parameter type: type of pass code controller
|
||||
- returns: pass code information holder, specific by type
|
||||
*/
|
||||
public static func build(with type: PassCodeControllerType) -> PassCodeHolderProtocol {
|
||||
public static func build(with type: PassCodeOperationType) -> PassCodeHolderProtocol {
|
||||
switch type {
|
||||
case .create:
|
||||
return PassCodeHolderCreate()
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public enum PinImageType {
|
|||
}
|
||||
|
||||
/// Pass code operation type
|
||||
public enum PassCodeControllerType {
|
||||
public enum PassCodeOperationType {
|
||||
case create
|
||||
case enter
|
||||
case change
|
||||
|
|
@ -150,16 +150,6 @@ open class BasePassCodeViewController: UIViewController, LegacyConfigurableContr
|
|||
}
|
||||
}
|
||||
|
||||
private func showBiometricsRequestIfNeeded() {
|
||||
guard viewModel.isBiometricsEnabled && viewModel.controllerType == .enter else {
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.authenticateUsingBiometrics(with: biometricsAuthorizationHint,
|
||||
fallback: biometricsFallbackButtonTitle,
|
||||
cancel: biometricsCancelButtonTitle)
|
||||
}
|
||||
|
||||
private func resetUI() {
|
||||
resetDotsUI()
|
||||
viewModel.reset()
|
||||
|
|
@ -251,6 +241,17 @@ open class BasePassCodeViewController: UIViewController, LegacyConfigurableContr
|
|||
fakeTextField.resignFirstResponder()
|
||||
}
|
||||
|
||||
/// Show biometrics system UI if applicable
|
||||
public func showBiometricsRequestIfNeeded() {
|
||||
guard viewModel.isBiometricsEnabled && viewModel.operationType == .enter else {
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.authenticateUsingBiometrics(with: biometricsAuthorizationHint,
|
||||
fallback: biometricsFallbackButtonTitle,
|
||||
cancel: biometricsCancelButtonTitle)
|
||||
}
|
||||
|
||||
// MARK: - ConfigurableController
|
||||
|
||||
open func bindViews() {
|
||||
|
|
@ -288,7 +289,7 @@ open class BasePassCodeViewController: UIViewController, LegacyConfigurableContr
|
|||
|
||||
open func addViews() {}
|
||||
|
||||
open func setAppearance() {}
|
||||
open func configureAppearance() {}
|
||||
|
||||
open func configureBarButtons() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public enum PassCodeAuthType {
|
|||
/// Base view model for passCodeViewController
|
||||
open class BasePassCodeViewModel: BaseViewModel {
|
||||
|
||||
public let controllerType: PassCodeControllerType
|
||||
public let operationType: PassCodeOperationType
|
||||
|
||||
public let disposeBag = DisposeBag()
|
||||
|
||||
|
|
@ -57,10 +57,10 @@ open class BasePassCodeViewModel: BaseViewModel {
|
|||
|
||||
private var attemptsNumber = 0
|
||||
|
||||
private lazy var passCodeHolder: PassCodeHolderProtocol = PassCodeHolderBuilder.build(with: self.controllerType)
|
||||
private lazy var passCodeHolder: PassCodeHolderProtocol = PassCodeHolderBuilder.build(with: self.operationType)
|
||||
|
||||
public init(controllerType: PassCodeControllerType, passCodeConfiguration: PassCodeConfiguration) {
|
||||
self.controllerType = controllerType
|
||||
public init(operationType: PassCodeOperationType, passCodeConfiguration: PassCodeConfiguration) {
|
||||
self.operationType = operationType
|
||||
self.passCodeConfiguration = passCodeConfiguration
|
||||
|
||||
bindViewModel()
|
||||
|
|
@ -95,7 +95,7 @@ open class BasePassCodeViewModel: BaseViewModel {
|
|||
public func reset() {
|
||||
passCodeText.value = nil
|
||||
validationResultHolder.value = nil
|
||||
passCodeControllerStateVariable.value = controllerType == .change ? .oldEnter : .enter
|
||||
passCodeControllerStateVariable.value = operationType == .change ? .oldEnter : .enter
|
||||
attemptsNumber = 0
|
||||
passCodeHolder.reset()
|
||||
}
|
||||
|
|
@ -197,21 +197,32 @@ extension BasePassCodeViewModel {
|
|||
return
|
||||
}
|
||||
|
||||
switch passCodeHolder.type {
|
||||
case .create where passCodeHolder.enterStep == .enter:
|
||||
attemptsNumber += 1
|
||||
case .change where passCodeHolder.enterStep == .enter:
|
||||
attemptsNumber += 1
|
||||
case .enter:
|
||||
attemptsNumber += 1
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
var validationResult = passCodeHolder.validate()
|
||||
|
||||
let passCodeValidationForPassCodeChange = passCodeHolder.type == .change && passCodeHolder.enterStep == .newEnter
|
||||
// if entered (in .enter mode) code is invalid -> .wrongCode
|
||||
if passCodeHolder.type == .enter,
|
||||
let passCode = validationResult.passCode,
|
||||
!isEnteredPassCodeValid(passCode) {
|
||||
|
||||
if passCodeHolder.type == .enter || passCodeValidationForPassCodeChange {
|
||||
attemptsNumber += 1
|
||||
let remainingAttemptsCount = passCodeConfiguration.maxAttemptsNumber - attemptsNumber
|
||||
validationResult = .invalid(.wrongCode(attemptsRemaining: remainingAttemptsCount))
|
||||
}
|
||||
|
||||
if let passCode = validationResult.passCode, !isEnteredPassCodeValid(passCode) {
|
||||
validationResult = .invalid(.wrongCode(passCodeConfiguration.maxAttemptsNumber - attemptsNumber))
|
||||
}
|
||||
|
||||
if (!validationResult.isValid && attemptsNumber == Int(passCodeConfiguration.maxAttemptsNumber)) ||
|
||||
attemptsNumber > Int(passCodeConfiguration.maxAttemptsNumber) {
|
||||
validationResult = .invalid(.tooManyAttempts)
|
||||
}
|
||||
// if entered code (in any mode) is mismatched too many times -> .tooManyAttempts
|
||||
if (!validationResult.isValid && attemptsNumber == passCodeConfiguration.maxAttemptsNumber) ||
|
||||
attemptsNumber > passCodeConfiguration.maxAttemptsNumber {
|
||||
validationResult = .invalid(.tooManyAttempts(type: operationType))
|
||||
}
|
||||
|
||||
if !validationResult.isValid {
|
||||
|
|
|
|||
Loading…
Reference in New Issue