diff --git a/LeadKitAdditions.podspec b/LeadKitAdditions.podspec index e34ed15..e3efa75 100644 --- a/LeadKitAdditions.podspec +++ b/LeadKitAdditions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKitAdditions" - s.version = "0.0.18" + s.version = "0.0.16" 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" @@ -19,8 +19,6 @@ Pod::Spec.new do |s| ss.dependency "LeadKit", '0.5.1' ss.dependency "KeychainAccess", '3.0.2' ss.dependency "IDZSwiftCommonCrypto", '0.9.1' - ss.dependency "InputMask", '2.2.5' - ss.dependency "SwiftValidator", '4.0.0' end s.subspec 'Core-iOS-Extension' do |ss| diff --git a/LeadKitAdditions/Sources/Protocols/CellFieldJumpingProtocol.swift b/LeadKitAdditions/Sources/Protocols/CellFieldJumpingProtocol.swift deleted file mode 100644 index 39029f7..0000000 --- a/LeadKitAdditions/Sources/Protocols/CellFieldJumpingProtocol.swift +++ /dev/null @@ -1,38 +0,0 @@ -import RxSwift -import RxCocoa -import UIKit - -typealias ItemSettingsBlock = (UIItem) -> Void where UIItem: UIView - -protocol CellFieldJumpingProtocol: FormCellViewModelProtocol { - - var toolBar: UIToolbar? { get set } - - var shouldGoForward: PublishSubject { get } - - var shouldBecomeFirstResponder: PublishSubject { get } - var shouldResignFirstResponder: PublishSubject { get } - - var returnButtonType: UIReturnKeyType { get set } - -} - -extension CellFieldJumpingProtocol { - - func bind(for textField: UITextField, to disposeBag: DisposeBag) { - shouldResignFirstResponder.asObservable() - .observeOn(MainScheduler.instance) - .subscribe(onNext: { [weak textField] _ in - textField?.resignFirstResponder() - }) - .addDisposableTo(disposeBag) - - shouldBecomeFirstResponder.asObservable() - .observeOn(MainScheduler.instance) - .subscribe(onNext: { [weak textField] _ in - textField?.becomeFirstResponder() - }) - .addDisposableTo(disposeBag) - } - -} diff --git a/LeadKitAdditions/Sources/Protocols/CellFieldMaskProtocol.swift b/LeadKitAdditions/Sources/Protocols/CellFieldMaskProtocol.swift deleted file mode 100644 index e3e9df3..0000000 --- a/LeadKitAdditions/Sources/Protocols/CellFieldMaskProtocol.swift +++ /dev/null @@ -1,14 +0,0 @@ -protocol CellFieldMaskProtocol { - - var haveMask: Bool { get } - var maskFieldTextProxy: MaskFieldTextProxy? { get set } - -} - -extension CellFieldMaskProtocol { - - var haveMask: Bool { - return maskFieldTextProxy != nil - } - -} diff --git a/LeadKitAdditions/Sources/Protocols/CellFieldValidationProtocol.swift b/LeadKitAdditions/Sources/Protocols/CellFieldValidationProtocol.swift deleted file mode 100644 index b294adb..0000000 --- a/LeadKitAdditions/Sources/Protocols/CellFieldValidationProtocol.swift +++ /dev/null @@ -1,5 +0,0 @@ -protocol CellFieldValidationProtocol { - - var validationItem: ValidationItem? { get set } - -} diff --git a/LeadKitAdditions/Sources/Protocols/CellFieldsToolBarProtocol.swift b/LeadKitAdditions/Sources/Protocols/CellFieldsToolBarProtocol.swift deleted file mode 100644 index c2bf138..0000000 --- a/LeadKitAdditions/Sources/Protocols/CellFieldsToolBarProtocol.swift +++ /dev/null @@ -1,16 +0,0 @@ -import UIKit -import RxSwift - -protocol CellFieldsToolBarProtocol: class { - - var needArrows: Bool { get set } - - var canGoForward: Bool { get set } - var canGoBackward: Bool { get set } - - var shouldGoForward: PublishSubject { get } - var shouldGoBackward: PublishSubject { get } - - var shouldEndEditing: PublishSubject { get } - -} diff --git a/LeadKitAdditions/Sources/Protocols/FormCellViewModelProtocol.swift b/LeadKitAdditions/Sources/Protocols/FormCellViewModelProtocol.swift deleted file mode 100644 index 84a85c9..0000000 --- a/LeadKitAdditions/Sources/Protocols/FormCellViewModelProtocol.swift +++ /dev/null @@ -1,15 +0,0 @@ -import RxCocoa -import RxSwift - -protocol FormCellViewModelProtocol: class { - var isActive: Bool { get set } -} - -extension FormCellViewModelProtocol { - - func activate(_ isActive: Bool) -> Self { - self.isActive = isActive - return self - } - -} diff --git a/LeadKitAdditions/Sources/Services/CellFieldsJumpingService.swift b/LeadKitAdditions/Sources/Services/CellFieldsJumpingService.swift deleted file mode 100644 index 692ff28..0000000 --- a/LeadKitAdditions/Sources/Services/CellFieldsJumpingService.swift +++ /dev/null @@ -1,138 +0,0 @@ -import RxSwift -import UIKit - -struct CellFieldsJumpingServiceConfig { - - var toolBarNeedArrows = true - - init() {} - - static var `default`: CellFieldsJumpingServiceConfig { - return CellFieldsJumpingServiceConfig() - } - -} - -class CellFieldsJumpingService { - - private var disposeBag = DisposeBag() - - // MARK: - Private properties - - private var cellFields: [CellFieldJumpingProtocol] = [] - - // MARK: - Public propertries - - var config: CellFieldsJumpingServiceConfig = .default { - didSet { - configure() - } - } - - let didDone = PublishSubject() - - // MARK: - Initialization - - init() {} - - // MARK: - Public - - func removeAll() { - cellFields.removeAll() - disposeBag = DisposeBag() - } - - func add(fieled: CellFieldJumpingProtocol, shouldConfigure: Bool = true) { - add(fieleds: [fieled], shouldConfigure: shouldConfigure) - } - - func add(fieleds: [CellFieldJumpingProtocol], shouldConfigure: Bool = true) { - cellFields += fieleds - - if shouldConfigure { - configure() - } - } - - func configure() { - disposeBag = DisposeBag() - - let cellFields = self.cellFields - - cellFields - .filter { $0.isActive } - .enumerated() - .forEach { offset, field in - field.toolBar = toolBar(for: field, with: offset) - field.returnButtonType = .next - - field.shouldGoForward.asObservable() - .subscribe(onNext: { [weak self] in - self?.shouldGoForwardAction(from: offset) - }) - .addDisposableTo(disposeBag) - } - - cellFields.lastActive?.returnButtonType = .done - } - - private func toolBar(for field: CellFieldJumpingProtocol, with index: Int) -> UIToolbar { - let toolBar = CellTextFieldToolBar() - toolBar.canGoForward = cellFields.nextActive(from: index) != nil - toolBar.canGoBackward = cellFields.previousActive(from: index) != nil - - toolBar.needArrows = config.toolBarNeedArrows - - toolBar.shouldGoForward.asObservable() - .subscribe(onNext: { [weak self] in - self?.shouldGoForwardAction(from: index) - }) - .addDisposableTo(disposeBag) - - toolBar.shouldGoBackward.asObservable() - .subscribe(onNext: { [weak self] in - if let previousActive = self?.cellFields.previousActive(from: index) { - previousActive.shouldBecomeFirstResponder.onNext() - } - }) - .addDisposableTo(disposeBag) - - toolBar.shouldEndEditing.asObservable() - .subscribe(onNext: { - field.shouldResignFirstResponder.onNext() - }) - .addDisposableTo(disposeBag) - - return toolBar - } - - private func shouldGoForwardAction(from index: Int) { - if let nextActive = cellFields.nextActive(from: index) { - nextActive.shouldBecomeFirstResponder.onNext() - } else { - didDone.onNext() - } - } - -} - -extension Array where Element == CellFieldJumpingProtocol { - - var firstActive: CellFieldJumpingProtocol? { - return first { $0.isActive } - } - - var lastActive: CellFieldJumpingProtocol? { - return reversed().first { $0.isActive } - } - - func nextActive(from index: Int) -> CellFieldJumpingProtocol? { - return enumerated().first { $0 > index && $1.isActive }?.element - } - - func previousActive(from index: Int) -> CellFieldJumpingProtocol? { - let reversedIndex = count - index - 1 - return reversed().enumerated().first { $0 > reversedIndex && $1.isActive }?.element - } - -} diff --git a/LeadKitAdditions/Sources/Services/MaskFieldTextProxy.swift b/LeadKitAdditions/Sources/Services/MaskFieldTextProxy.swift deleted file mode 100644 index 0ef05cf..0000000 --- a/LeadKitAdditions/Sources/Services/MaskFieldTextProxy.swift +++ /dev/null @@ -1,59 +0,0 @@ -import InputMask -import RxCocoa -import RxSwift - -class MaskFieldTextProxy: NSObject { - - private var disposeBag = DisposeBag() - - let text = Variable("") - fileprivate let isCompleteHolder = Variable(false) - var isComplete: Bool { - return isCompleteHolder.value - } - var isCompleteObservable: Observable { - return isCompleteHolder.asObservable() - } - - private(set) var field: UITextField? - - private let maskedProxy: PolyMaskTextFieldDelegate - - init(primaryFormat: String, affineFormats: [String] = []) { - maskedProxy = PolyMaskTextFieldDelegate(primaryFormat: primaryFormat, affineFormats: affineFormats) - - super.init() - - maskedProxy.listener = self - } - - func configure(with field: UITextField) { - self.field = field - field.delegate = maskedProxy - } - - private func bindData() { - disposeBag = DisposeBag() - - text.asDriver() - .distinctUntilChanged() - .drive(onNext: { [weak self] value in - guard let textField = self?.field else { - return - } - - self?.maskedDelegate.put(text: value, into: textField) - }) - .addDisposableTo(disposeBag) - } - -} - -extension MaskFieldTextProxy: MaskedTextFieldDelegateListener { - - func textField(_ textField: UITextField, didFillMandatoryCharacters complete: Bool, didExtractValue value: String) { - text.value = value - isCompleteHolder.value = complete - } - -} diff --git a/LeadKitAdditions/Sources/Services/ValidationService/ValidationError.swift b/LeadKitAdditions/Sources/Services/ValidationService/ValidationError.swift deleted file mode 100644 index 69c1ec6..0000000 --- a/LeadKitAdditions/Sources/Services/ValidationService/ValidationError.swift +++ /dev/null @@ -1,15 +0,0 @@ -import SwiftValidator - -struct ValidationError: Error { - - let failedRule: Rule - let errorMessage: String? - let errorHint: String? - - init(failedRule: Rule, errorMessage: String?, errorHint: String? = nil) { - self.failedRule = failedRule - self.errorMessage = errorMessage - self.errorHint = errorHint - } - -} diff --git a/LeadKitAdditions/Sources/Services/ValidationService/ValidationItem.swift b/LeadKitAdditions/Sources/Services/ValidationService/ValidationItem.swift deleted file mode 100644 index 902ac93..0000000 --- a/LeadKitAdditions/Sources/Services/ValidationService/ValidationItem.swift +++ /dev/null @@ -1,96 +0,0 @@ -import SwiftValidator -import RxSwift -import RxCocoa - -enum ValidationItemState { - case initial - case correction(ValidationError) - case error(ValidationError) - case valid -} - -extension ValidationItemState { - - var isInitial: Bool { - switch self { - case .initial: - return true - default: - return false - } - } - - var isValid: Bool { - switch self { - case .valid: - return true - default: - return false - } - } - -} - -class ValidationItem { - - private let disposeBag = DisposeBag() - - private let validationStateHolder = Variable(.initial) - var validationState: ValidationItemState { - return validationStateHolder.value - } - var validationStateObservable: Observable { - return validationStateHolder.asObservable() - } - - let text = Variable(nil) - - private(set) var rules: [Rule] = [] - - init(rules: [Rule]) { - self.rules = rules - bindText() - } - - private func bindText() { - text.asObservable() - .filter { [weak self] _ in !(self?.validationState.isInitial ?? true)} - .subscribe(onNext: { [weak self] value in - self?.validate(text: value) - }) - .addDisposableTo(disposeBag) - } - - @discardableResult - func manualValidate() -> Bool { - return validate(text: text.value, isManual: true) - } - - @discardableResult - private func validate(text: String?, isManual: Bool = false) -> Bool { - let error = rules.filter { - return !$0.validate(text ?? "") - } - .map { rule -> ValidationError in - return ValidationError(failedRule: rule, errorMessage: rule.errorMessage()) - } - .first - - if let validationError = error { - switch validationStateHolder.value { - case .error where !isManual, - .correction where !isManual, - .valid where !isManual: - - validationStateHolder.value = .correction(validationError) - default: - validationStateHolder.value = .error(validationError) - } - } else { - validationStateHolder.value = .valid - } - - return validationStateHolder.value.isValid - } - -} diff --git a/LeadKitAdditions/Sources/Services/ValidationService/ValidationService.swift b/LeadKitAdditions/Sources/Services/ValidationService/ValidationService.swift deleted file mode 100644 index 37e5fbe..0000000 --- a/LeadKitAdditions/Sources/Services/ValidationService/ValidationService.swift +++ /dev/null @@ -1,104 +0,0 @@ -import SwiftValidator -import RxCocoa -import RxSwift - -private enum ValidationServiceStateReactType { - case none - case all - case each -} - -enum ValidationServiceState { - case initial - case valid - case invalid -} - -extension ValidationServiceState { - - var isValid: Bool { - return self == .valid - } - -} - -class ValidationService { - - private var disposeBag = DisposeBag() - - private(set) var validationItems: [ValidationItem] = [] - - private let stateHolder = Variable(.initial) - var state: ValidationServiceState { - return stateHolder.value - } - var stateObservable: Observable { - return stateHolder.asObservable() - } - - private var validationStateReactType: ValidationServiceStateReactType = .none - - func register(item: ValidationItem) { - register(items: [item]) - } - - func register(items: [ValidationItem]) { - validationItems += items - bindItems() - } - - func unregisterAll() { - validationItems.removeAll() - bindItems() - } - - func unregister(item: ValidationItem) { - unregister(items: [item]) - } - - func unregister(items: [ValidationItem]) { - items.forEach { item in - if let removeIndex = validationItems.index(where: { $0 === item }) { - validationItems.remove(at: removeIndex) - } - } - - bindItems() - } - - @discardableResult - func validate() -> Bool { - validationStateReactType = .all - let isValid = validationItems.map { $0.manualValidate() }.reduce(true) { $0 && $1 } - validationStateReactType = .each - - return isValid - } - - private func bindItems() { - disposeBag = DisposeBag() - - let allValidationStateObservables = validationItems.map { $0.validationStateObservable } - - let zipStates = Observable - .zip(allValidationStateObservables) { $0 } - .filter { [weak self] _ in self?.validationStateReactType == .all } - - let combineLatestStates = Observable - .combineLatest(allValidationStateObservables) { $0 } - .filter { [weak self] _ in self?.validationStateReactType == .each } - - let stateObservables = [zipStates, combineLatestStates] - - stateObservables.forEach { observable in - observable - .map { states -> Bool in - return states.map { $0.isValid }.reduce(true) { $0 && $1 } - } - .map { $0 ? ValidationServiceState.valid : .invalid } - .bind(to: stateHolder) - .addDisposableTo(disposeBag) - } - } - -} diff --git a/LeadKitAdditions/Sources/Views/CellTextField/CellTextField.swift b/LeadKitAdditions/Sources/Views/CellTextField/CellTextField.swift deleted file mode 100644 index 4ccf4ac..0000000 --- a/LeadKitAdditions/Sources/Views/CellTextField/CellTextField.swift +++ /dev/null @@ -1,44 +0,0 @@ -import UIKit -import RxCocoa -import RxSwift - -class CellTextField: UITextField { - - private var disposeBag = DisposeBag() - - var viewModel: CellTextFieldViewModel? { - didSet { - configure() - } - } - - // MARK: - Init - - private func configure() { - disposeBag = DisposeBag() - - guard let viewModel = viewModel else { - return - } - - inputAccessoryView = viewModel.toolBar - returnKeyType = viewModel.returnButtonType - - text = viewModel.text.value - placeholder = viewModel.placeholder - viewModel.textFieldSettingsBlock?(self) - - viewModel.bind(for: self, to: disposeBag) - - rx.text.asDriver() - .drive(viewModel.text) - .addDisposableTo(disposeBag) - - rx.controlEvent(.editingDidEndOnExit).asObservable() - .subscribe(onNext: { - viewModel.shouldGoForward.onNext() - }) - .addDisposableTo(disposeBag) - } - -} diff --git a/LeadKitAdditions/Sources/Views/CellTextField/CellTextFieldViewModel.swift b/LeadKitAdditions/Sources/Views/CellTextField/CellTextFieldViewModel.swift deleted file mode 100644 index c154ede..0000000 --- a/LeadKitAdditions/Sources/Views/CellTextField/CellTextFieldViewModel.swift +++ /dev/null @@ -1,30 +0,0 @@ -import UIKit -import RxSwift - -class CellTextFieldViewModel: CellFieldJumpingProtocol { - - let text: Variable - let placeholder: String - - let textFieldSettingsBlock: ItemSettingsBlock? - - // MARK: - CellFieldJumpingProtocol - - var toolBar: UIToolbar? - - let shouldGoForward = PublishSubject() - - let shouldBecomeFirstResponder = PublishSubject() - let shouldResignFirstResponder = PublishSubject() - - var returnButtonType: UIReturnKeyType = .default - - var isActive: Bool = true - - init(initialText: String = "", placeholder: String = "", textFieldSettingsBlock: ItemSettingsBlock? = nil) { - text = Variable(initialText) - self.placeholder = placeholder - self.textFieldSettingsBlock = textFieldSettingsBlock - } - -}