PasscodeLock is the sample project of AppLocker. I took some hours and found how it worked.
Let The App Run
The original project used Carthage to manage the framework. It depended Valet. However, the latest Valet is 4.x but PasscodeLock depends 3.x. So we need to specify the version.
pod 'Valet' , '< 4.0'
I switched Carthage to CocoaPods. So I also had to remove the Carthage part in building phase.
Core

// AppALConstants.swift
// MARK: - Keyboard
@IBAction func keyboardPressed(_ sender: UIButton) {
switch sender.tag {
case ALConstants.button.delete.rawValue:
drawing(isNeedClear: true)
case ALConstants.button.cancel.rawValue:
clearView()
dismiss(animated: true) {
self.onSuccessfulDismiss?(nil)
}
default:
drawing(isNeedClear: false, tag: sender.tag)
}
}
private func drawing(isNeedClear: Bool, tag: Int? = nil) { // Fill or cancel fill for indicators
let results = pinIndicators.filter { $0.isNeedClear == isNeedClear }
let pinView = isNeedClear ? results.last : results.first
pinView?.isNeedClear = !isNeedClear
UIView.animate(withDuration: ALConstants.duration, animations: {
pinView?.backgroundColor = isNeedClear ? .clear : .white
}) { _ in
isNeedClear ? self.pin = String(self.pin.dropLast()) : self.pincodeChecker(tag ?? 0)
}
}
private func pincodeChecker(_ pinNumber: Int) {
if pin.count < ALConstants.maxPinLength {
pin.append("\(pinNumber)")
if pin.count == ALConstants.maxPinLength {
switch mode {
case .create:
createModeAction()
case .change:
changeModeAction()
case .deactive:
deactiveModeAction()
case .validate:
validateModeAction()
}
}
}
}
When a user presses a key, private func drawing(isNeedClear: Bool, tag: Int? = nil) is called.
pinViewis the current indicator. It is set to turn white.- then
func pincodeChecker(_ pinNumber: Int)is called, the result is pin. - when pin.count is 4, the indicators are cleared.