From 596f25ccc05dae363fb3bc91baaece39828ad0ae Mon Sep 17 00:00:00 2001 From: Alexey Gerasimov Date: Wed, 24 May 2017 19:09:58 +0300 Subject: [PATCH] Comments added --- .../Sources/Classes/ApiResponse.swift | 7 +++++++ .../Sources/Classes/BaseDateFormatter.swift | 11 +++++++++- .../Sources/Classes/LoadingBarButton.swift | 17 ++++++++++++++++ .../Model/PassCodeConfiguration.swift | 5 +++++ .../PassCode/Model/PassCodeError.swift | 1 + .../PassCode/Model/PassCodeHolder.swift | 3 +++ .../Model/PassCodeHolderProtocol.swift | 15 ++++++++++++++ .../Model/PassCodeValidationResult.swift | 1 + .../View/BasePassCodeViewController.swift | 19 +++++++++++++----- .../ViewModel/BasePassCodeViewModel.swift | 8 ++++++++ LeadKitAdditions/Sources/Enums/ApiError.swift | 4 ++-- .../Sources/Enums/ApiErrorProtocol.swift | 2 ++ .../Sources/Enums/ConnectionError.swift | 1 + .../Extensions/Observable+Extensions.swift | 20 +++++++++++++++++++ .../UIBarButtonItem+Extensions.swift | 1 + .../Extensions/UserDefaults+UserService.swift | 4 +++- .../Services/BasePassCodeService.swift | 7 +++++++ .../Sources/Services/BaseUserService.swift | 5 +++++ .../Services/Network/ApiNetworkService.swift | 3 +++ .../Network/DefaultNetworkService.swift | 6 ++++++ .../Sources/Services/TouchIDService.swift | 9 +++++++++ 21 files changed, 140 insertions(+), 9 deletions(-) diff --git a/LeadKitAdditions/Sources/Classes/ApiResponse.swift b/LeadKitAdditions/Sources/Classes/ApiResponse.swift index bb1f92b..73dfc71 100644 --- a/LeadKitAdditions/Sources/Classes/ApiResponse.swift +++ b/LeadKitAdditions/Sources/Classes/ApiResponse.swift @@ -22,10 +22,14 @@ import ObjectMapper +/// Class describes typical response from server, which designed by TouchInstinct public class ApiResponse: ApiResponseProtocol, ImmutableMappable { + /// nil in case of error, result of request otherwise public let result: Any? + /// In case of error contains error code, 0 (zero) otherwise public let errorCode: Int + /// nil in case of success, error description otherwise public let errorMessage: String? public required init(map: Map) throws { @@ -36,9 +40,12 @@ public class ApiResponse: ApiResponseProtocol, ImmutableMappable { } +/// Describes error, which received from server designed by TouchInstinct public protocol ApiResponseProtocol: ImmutableMappable { + /// Error code var errorCode: Int { get } + /// Error description var errorMessage: String? { get } } diff --git a/LeadKitAdditions/Sources/Classes/BaseDateFormatter.swift b/LeadKitAdditions/Sources/Classes/BaseDateFormatter.swift index 0748a37..3bdf9ae 100644 --- a/LeadKitAdditions/Sources/Classes/BaseDateFormatter.swift +++ b/LeadKitAdditions/Sources/Classes/BaseDateFormatter.swift @@ -23,6 +23,7 @@ import Foundation import ObjectMapper +/// Base date formatter class, contains most frequently used formats, including RFC3339 open class BaseDateFormatter { private static let apiDateTimeFormat = "yyyy-MM-dd'T'HH:mm:ssZ" @@ -61,37 +62,44 @@ open class BaseDateFormatter { return dateFormater }() - // MARK: Public interface + // MARK: - Public interface + /// DateFormatter's locale can be overriden open class var usedLocale: Locale { return .current } + /// Parse date from string with format: yyyy-MM-dd'T'HH:mm:ssZ public static func backendDate(fromStrDate strDate: String) -> Date? { apiFormatter.locale = usedLocale return apiFormatter.date(from: strDate) } + /// Serialize date into string with format: yyyy-MM-dd'T'HH:mm:ssZ public static func backendStrDate(withDate date: Date) -> String { apiFormatter.locale = usedLocale return apiFormatter.string(from: date) } + /// Serialize date into string with format: yyyy-MM-dd'T'Z public static func backendDateWithoutTime(withDate date: Date) -> String { apiDateWithoutTimeFormatter.locale = usedLocale return apiDateWithoutTimeFormatter.string(from: date) } + /// Serialize date into string with format: HH:mm public static func hourAndMinuteStrDate(withDate date: Date) -> String { hourAndMinuteFormatter.locale = usedLocale return hourAndMinuteFormatter.string(from: date) } + /// Serialize date into string with format: dd MMM public static func dayAndMonthStrDate(withDate date: Date) -> String { hourAndMinuteFormatter.locale = usedLocale return dayAndMonthFormatter.string(from: date) } + /// Serialize date into string with format: dd.MM.yyyy public static func dayMonthYearStrDate(withDate date: Date) -> String { hourAndMinuteFormatter.locale = usedLocale return dayMonthYearFormatter.string(from: date) @@ -99,6 +107,7 @@ open class BaseDateFormatter { // MARK: - Transformers + /// Transformer to workaround with dates in Mappable (ObjectMapper) objects public static var transformFromStringToDate: TransformOf { return TransformOf(fromJSON: { (stringValue) -> Date? in if let stringValue = stringValue { diff --git a/LeadKitAdditions/Sources/Classes/LoadingBarButton.swift b/LeadKitAdditions/Sources/Classes/LoadingBarButton.swift index 4056510..2f79f44 100644 --- a/LeadKitAdditions/Sources/Classes/LoadingBarButton.swift +++ b/LeadKitAdditions/Sources/Classes/LoadingBarButton.swift @@ -24,11 +24,13 @@ import UIKit import RxSwift import RxCocoa +/// Side to which ativity indicator applied public enum LoadingBarButtonSide { case left case right } +/// Workaround with navigationBarButton, that can change state (UI) into activity indicator public class LoadingBarButton { fileprivate weak var navigationItem: UINavigationItem? @@ -54,6 +56,13 @@ public class LoadingBarButton { } } + /** + Create an instance of LoadingBarButton + + - Parameters: + - navigationItem: item to which apply changes + - side: side where navigationItem would be placed + */ public init(navigationItem: UINavigationItem, side: LoadingBarButtonSide) { self.navigationItem = navigationItem self.side = side @@ -74,6 +83,14 @@ public class LoadingBarButton { extension Observable { + /** + Reactive extension for LoadingBarButton + Apply transformations on subscribe and on dispose events + + - Parameters: + - barButton: LoadingBarButton instance to which transformations would applied + - Returns: + */ public func changeLoadingUI(using barButton: LoadingBarButton) -> Observable { return observeOn(MainScheduler.instance) .do(onSubscribe: { diff --git a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeConfiguration.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeConfiguration.swift index 2635d02..d48d8e5 100644 --- a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeConfiguration.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeConfiguration.swift @@ -20,11 +20,15 @@ // THE SOFTWARE. // +/// Configuration container for BasePassCodeViewController public struct PassCodeConfiguration { + /// Pass code length public var passCodeCharactersNumber: UInt = 4 + /// Incorrect pass code attempts count public var maxAttemptsLoginNumber: UInt = 5 + /// Clear input progress when application goes to background public var shouldResetWhenGoBackground: Bool = true private init() {} @@ -37,6 +41,7 @@ public struct PassCodeConfiguration { self.passCodeCharactersNumber = passCodeCharactersNumber } + /// Returns configuration with default values public static var defaultConfiguration: PassCodeConfiguration { return PassCodeConfiguration() } diff --git a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeError.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeError.swift index 6fbcc8a..372a2cb 100644 --- a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeError.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeError.swift @@ -20,6 +20,7 @@ // THE SOFTWARE. // +/// Describes error, which may occures during pass code entering public enum PassCodeError: Error { case codesNotMatch case wrongCode diff --git a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolder.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolder.swift index 4a118a5..4dae8fc 100644 --- a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolder.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolder.swift @@ -38,6 +38,7 @@ extension PassCodeHolderProtocol { } } +/// Holds information about pass codes during pass code creation process public class PassCodeHolderCreate: PassCodeHolderProtocol { public let type: PassCodeControllerType = .create @@ -91,6 +92,7 @@ public class PassCodeHolderCreate: PassCodeHolderProtocol { } +/// Holds information about pass code during pass code entering process public class PassCodeHolderEnter: PassCodeHolderProtocol { public let type: PassCodeControllerType = .enter @@ -120,6 +122,7 @@ public class PassCodeHolderEnter: PassCodeHolderProtocol { } +/// Holds information about pass codes during pass code changing process public class PassCodeHolderChange: PassCodeHolderProtocol { public let type: PassCodeControllerType = .change diff --git a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolderProtocol.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolderProtocol.swift index e281642..b4a031d 100644 --- a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolderProtocol.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolderProtocol.swift @@ -20,17 +20,26 @@ // THE SOFTWARE. // +/// Holds information about enter type (create, change, etc), step +/// Also describes interface to manipulate with entered pass code public protocol PassCodeHolderProtocol { + /// Type of operation with pass code var type: PassCodeControllerType { get } + /// Operation step var enterStep: PassCodeControllerState { get } + /// Add pass code for current step func add(passCode: String) + /// Reset all progress func reset() + /// Should been pass code validated var shouldValidate: Bool { get } + /// Current pass code var passCode: String? { get } + /// Returns passCode or error if pass code is invalid func validate() -> PassCodeValidationResult } @@ -39,6 +48,12 @@ public class PassCodeHolderBuilder { private init() {} + /** + Creates holder by type (create, change, etc) + + - parameter type: type of pass code controller + - returns: pass code information holder, specific by type + */ public static func build(with type: PassCodeControllerType) -> PassCodeHolderProtocol { switch type { case .create: diff --git a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeValidationResult.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeValidationResult.swift index 33bdd9b..41bdbd1 100644 --- a/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeValidationResult.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeValidationResult.swift @@ -20,6 +20,7 @@ // THE SOFTWARE. // +/// Result of pass code validation public enum PassCodeValidationResult { case valid(String) diff --git a/LeadKitAdditions/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift b/LeadKitAdditions/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift index c6ec92e..11591ce 100644 --- a/LeadKitAdditions/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift @@ -25,17 +25,20 @@ import RxSwift import RxCocoa import LeadKit +/// Describes pin image public enum PinImageType { case entered case clear } +/// Pass code operation type public enum PassCodeControllerType { case create case enter case change } +/// Pass code operation state public enum PassCodeControllerState { case enter case repeatEnter @@ -43,6 +46,7 @@ public enum PassCodeControllerState { case newEnter } +/// Base view controller that operates with pass code open class BasePassCodeViewController: UIViewController { public var viewModel: BasePassCodeViewModel! @@ -157,41 +161,44 @@ open class BasePassCodeViewController: UIViewController { // MARK: - HAVE TO OVERRIDE + /// Returns prompt that appears on touch id system alert open var touchIdHint: String { assertionFailure("You should override this var: touchIdHint") return "" } - // override to change Images + /// Override to point certain images open func imageFor(type: PinImageType) -> UIImage { assertionFailure("You should override this method: imageFor(type: PinImageType)") return UIImage() } - // override to change error text + /// Override to change error description open func errorDescription(for error: PassCodeError) -> String { assertionFailure("You should override this method: errorDescription(for error: PassCodeError)") return "" } - // override to change action title text + /// Override to change action title text open func actionTitle(for passCodeControllerState: PassCodeControllerState) -> String { assertionFailure("You should override this method: actionTitle(for passCodeControllerState: PassCodeControllerState)") return "" } - // MARK: - Functions that can you can override to castomise your controller + // MARK: - Functions that you can override to customize your controller + /// Call to show error open func showError(for error: PassCodeError) { errorLabel?.text = errorDescription(for: error) errorLabel?.isHidden = false } + /// Call to disappear error label open func hideError() { errorLabel?.isHidden = true } - // override to change UI for state + /// Override to change UI for state open func configureUI(for passCodeControllerState: PassCodeControllerState) { resetDotsUI() titleLabel?.text = actionTitle(for: passCodeControllerState) @@ -199,6 +206,7 @@ open class BasePassCodeViewController: UIViewController { } +// MARK: - ConfigurableController // We need to implement all functions of ConfigurableController protocol to give ability to override them. extension BasePassCodeViewController: ConfigurableController { @@ -242,6 +250,7 @@ extension BasePassCodeViewController: ConfigurableController { } +// MARK: - UITextFieldDelegate extension BasePassCodeViewController: UITextFieldDelegate { public func textField(_ textField: UITextField, diff --git a/LeadKitAdditions/Sources/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift b/LeadKitAdditions/Sources/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift index 5582931..0679755 100644 --- a/LeadKitAdditions/Sources/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift @@ -24,18 +24,22 @@ import LeadKit import RxSwift import RxCocoa +/// Describes types of authentication public enum PassCodeAuthType { case passCode(String) case touchId } +/// Base view model for passCodeViewController open class BasePassCodeViewModel: BaseViewModel { public let controllerType: PassCodeControllerType public let disposeBag = DisposeBag() + /// TouchId service, which can answer if user is authorized by finger public let touchIdService: TouchIDService? + /// Contains configuration for pass code operations public let passCodeConfiguration: PassCodeConfiguration fileprivate let validationResultHolder = Variable(nil) @@ -114,21 +118,25 @@ open class BasePassCodeViewModel: BaseViewModel { // MARK: - HAVE TO OVERRIDE + /// Override to check if entered pass code is equal to stored open func isEnteredPassCodeValid(_ passCode: String) -> Bool { assertionFailure("You should override this method: isEnteredPassCodeValid(_ passCode: String)") return false } + /// Handler called after successful authentication open func authSucceed(_ type: PassCodeAuthType) { assertionFailure("You should override this method: authSucceed(_ type: PassCodeAuthType)") } // MARK: - Functions that can you can override to use TouchId + /// Override to be able use touchId during authentication open var isTouchIdEnabled: Bool { return false } + /// You should save user choice about authenticate by touchId open func activateTouchIdForUser() { assertionFailure("You should override this method: activateTouchIdForUser()") } diff --git a/LeadKitAdditions/Sources/Enums/ApiError.swift b/LeadKitAdditions/Sources/Enums/ApiError.swift index 1aadac7..bb4533e 100644 --- a/LeadKitAdditions/Sources/Enums/ApiError.swift +++ b/LeadKitAdditions/Sources/Enums/ApiError.swift @@ -20,8 +20,7 @@ // THE SOFTWARE. // -import Foundation - +/// Describes possible error, received from back-end public enum ApiError: Error { case error(code: Int, message: String) @@ -29,6 +28,7 @@ public enum ApiError: Error { } +// MARK: - LocalizedError extension ApiError: LocalizedError { public init(apiResponse: ApiResponseProtocol) { diff --git a/LeadKitAdditions/Sources/Enums/ApiErrorProtocol.swift b/LeadKitAdditions/Sources/Enums/ApiErrorProtocol.swift index e71b6ae..31b0113 100644 --- a/LeadKitAdditions/Sources/Enums/ApiErrorProtocol.swift +++ b/LeadKitAdditions/Sources/Enums/ApiErrorProtocol.swift @@ -20,10 +20,12 @@ // THE SOFTWARE. // +/// Describes error by raw value (more likely - Int code), received from back-end public protocol ApiErrorProtocol: RawRepresentable {} extension Error { + /// Method indicates that error is back-end error public func isApiError(_ apiErrorType: T) -> Bool where T.RawValue == Int { if let error = self as? ApiError, case let .error(code: code, message: _) = error, diff --git a/LeadKitAdditions/Sources/Enums/ConnectionError.swift b/LeadKitAdditions/Sources/Enums/ConnectionError.swift index 9cad52e..f6980c4 100644 --- a/LeadKitAdditions/Sources/Enums/ConnectionError.swift +++ b/LeadKitAdditions/Sources/Enums/ConnectionError.swift @@ -22,6 +22,7 @@ import Foundation +/// Describes "no connection to server" error public enum ConnectionError: LocalizedError { case noConnection diff --git a/LeadKitAdditions/Sources/Extensions/Observable+Extensions.swift b/LeadKitAdditions/Sources/Extensions/Observable+Extensions.swift index 4a9eec8..7c67157 100644 --- a/LeadKitAdditions/Sources/Extensions/Observable+Extensions.swift +++ b/LeadKitAdditions/Sources/Extensions/Observable+Extensions.swift @@ -28,6 +28,7 @@ public typealias VoidBlock = () -> Void public extension Observable { + /// Handles connection errors during request public func handleConnectionErrors() -> Observable { return observeOn(CurrentThreadScheduler.instance) @@ -52,6 +53,13 @@ public extension Observable { }) } + /** + Allow to configure request to restart if error occured + + - parameters: + - errorTypes: list of error types, which triggers request restart + - retryLimit: how many times request can restarts + */ public func retryWithinErrors(_ errorTypes: [Error.Type] = [ConnectionError.self], retryLimit: Int = DefaultNetworkService.retryLimit) -> Observable { @@ -66,6 +74,13 @@ public extension Observable { } } + /** + Add block that executes, when error, described by ApiErrorProtocol, occured during request + + - parameters: + - apiErrorType: type of errors, received frim server + - handler: block, that executes, when error occured + */ public func handleApiError(_ apiErrorType: T, handler: @escaping () -> Void) -> Observable where T.RawValue == Int { @@ -78,6 +93,11 @@ public extension Observable { }) } + /** + Add ability to monitor request status + + - parameter isLoading: subject, request state bind to + */ public func changeLoadingBehaviour(isLoading: PublishSubject) -> Observable { return observeOn(CurrentThreadScheduler.instance) .do(onNext: { _ in diff --git a/LeadKitAdditions/Sources/Extensions/UIBarButtonItem+Extensions.swift b/LeadKitAdditions/Sources/Extensions/UIBarButtonItem+Extensions.swift index 51c2d56..ef3eaf7 100644 --- a/LeadKitAdditions/Sources/Extensions/UIBarButtonItem+Extensions.swift +++ b/LeadKitAdditions/Sources/Extensions/UIBarButtonItem+Extensions.swift @@ -24,6 +24,7 @@ import UIKit extension UIBarButtonItem { + /// Creates activity indicator view and bar button item (based on activity indicator) public static var activityIndicator: (barButton: UIBarButtonItem, activityIndicator: UIActivityIndicatorView) { let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .white) let indicatorBar = UIBarButtonItem(customView: indicatorView) diff --git a/LeadKitAdditions/Sources/Extensions/UserDefaults+UserService.swift b/LeadKitAdditions/Sources/Extensions/UserDefaults+UserService.swift index eb6e8f3..4015847 100644 --- a/LeadKitAdditions/Sources/Extensions/UserDefaults+UserService.swift +++ b/LeadKitAdditions/Sources/Extensions/UserDefaults+UserService.swift @@ -22,13 +22,14 @@ import Foundation -fileprivate enum Keys { +private enum Keys { static let sessionId = "sessionId" static let userLogin = "userLogin" } public extension UserDefaults { + /// Default place to store session id public var sessionId: String? { get { return string(forKey: Keys.sessionId) @@ -38,6 +39,7 @@ public extension UserDefaults { } } + /// Default place to store userLogin public var userLogin: String? { get { return string(forKey: Keys.userLogin) diff --git a/LeadKitAdditions/Sources/Services/BasePassCodeService.swift b/LeadKitAdditions/Sources/Services/BasePassCodeService.swift index ab9740f..f772dcc 100644 --- a/LeadKitAdditions/Sources/Services/BasePassCodeService.swift +++ b/LeadKitAdditions/Sources/Services/BasePassCodeService.swift @@ -24,8 +24,10 @@ import KeychainAccess import CocoaLumberjack import IDZSwiftCommonCrypto +/// Represents base pass code service which encapsulates pass code storing open class BasePassCodeService { + /// Override to set specific keychain service name open class var keychainService: String { return Bundle.main.bundleIdentifier ?? "" } @@ -63,10 +65,12 @@ open class BasePassCodeService { extension BasePassCodeService { + /// Indicates is pass code already saved on this device public var isPassCodeSaved: Bool { return keychain[Keys.passCodeHash] != nil } + /// Indicates is it possible to authenticate on this device via touch id public var isTouchIdEnabled: Bool { get { return keychain[Keys.isTouchIdEnabled] == Values.touchIdEnabled @@ -76,6 +80,7 @@ extension BasePassCodeService { } } + /// Saves new pass code public func save(passCode: String?) { if let passCode = passCode { keychain[Keys.passCodeHash] = sha256(passCode) @@ -84,10 +89,12 @@ extension BasePassCodeService { } } + /// Check if pass code is correct public func check(passCode: String) -> Bool { return sha256(passCode) == passCodeHash } + /// Reset pass code settings public func reset() { save(passCode: nil) isTouchIdEnabled = false diff --git a/LeadKitAdditions/Sources/Services/BaseUserService.swift b/LeadKitAdditions/Sources/Services/BaseUserService.swift index 8923c7f..b5a7125 100644 --- a/LeadKitAdditions/Sources/Services/BaseUserService.swift +++ b/LeadKitAdditions/Sources/Services/BaseUserService.swift @@ -23,12 +23,14 @@ import RxSwift import LeadKit +/// Represents service that store basic user information open class BaseUserService { public init() { // Can be overrided } + /// Returns user login open var userLogin: String { guard let defaultsLogin = UserDefaults.standard.userLogin else { assertionFailure("userLogin is nil. Use isLoggedIn before read userLogin") @@ -38,6 +40,7 @@ open class BaseUserService { return defaultsLogin } + /// Returns session id open var sessionId: String { guard let defaultsSessionId = UserDefaults.standard.sessionId else { assertionFailure("sessionId is nil. Use isLoggedIn before read sessionId") @@ -46,10 +49,12 @@ open class BaseUserService { return defaultsSessionId } + /// Indicates if user is logged in open var isLoggedIn: Bool { return UserDefaults.standard.sessionId != nil } + /// Reset user information open class func clearData() { UserDefaults.standard.sessionId = nil UserDefaults.standard.userLogin = nil diff --git a/LeadKitAdditions/Sources/Services/Network/ApiNetworkService.swift b/LeadKitAdditions/Sources/Services/Network/ApiNetworkService.swift index d588926..762a737 100644 --- a/LeadKitAdditions/Sources/Services/Network/ApiNetworkService.swift +++ b/LeadKitAdditions/Sources/Services/Network/ApiNetworkService.swift @@ -25,8 +25,10 @@ import Alamofire import ObjectMapper import RxSwift +/// Base network service implementation for back-end designed by TouchInstinct open class ApiNetworkService: DefaultNetworkService { + /// Returns observable for ImmutableMappable response model by parameters open func request(with parameters: ApiRequestParameters) -> Observable { let apiResponseRequest = rxRequest(with: parameters) as Observable<(response: HTTPURLResponse, model: ApiResponse)> @@ -41,6 +43,7 @@ open class ApiNetworkService: DefaultNetworkService { } } + /// Returns observable for boolean response by parameters open func requestForResult(with parameters: ApiRequestParameters) -> Observable { let apiResponseRequest = rxRequest(with: parameters) as Observable<(response: HTTPURLResponse, model: ApiResponse)> diff --git a/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService.swift b/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService.swift index d7a128a..53a76e6 100644 --- a/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService.swift +++ b/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService.swift @@ -25,16 +25,19 @@ import LeadKit import ObjectMapper import RxSwift +/// Default implementation of network service, which trust any server and uses default timeout interval open class DefaultNetworkService: NetworkService { static let retryLimit = 3 private let disposeBag = DisposeBag() + /// Override to set base server url open class var baseUrl: String { fatalError("You should override this var: baseUrl") } + /// Override to change timeout interval default value open class var defaultTimeoutInterval: TimeInterval { return 20.0 } @@ -47,12 +50,14 @@ open class DefaultNetworkService: NetworkService { // MARK: - Default Values + /// Override to change server trust policies open class var serverTrustPolicies: [String: ServerTrustPolicy] { return [ baseUrl: .disableEvaluation ] } + /// Override to change default urlSession configuration open class var configuration: URLSessionConfiguration { let configuration = URLSessionConfiguration.default configuration.timeoutIntervalForRequest = defaultTimeoutInterval @@ -60,6 +65,7 @@ open class DefaultNetworkService: NetworkService { return configuration } + /// Override to configure alamofire session manager open class var sessionManager: SessionManager { let sessionManager = SessionManager(configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)) diff --git a/LeadKitAdditions/Sources/Services/TouchIDService.swift b/LeadKitAdditions/Sources/Services/TouchIDService.swift index 394186d..4dfaab2 100644 --- a/LeadKitAdditions/Sources/Services/TouchIDService.swift +++ b/LeadKitAdditions/Sources/Services/TouchIDService.swift @@ -24,6 +24,7 @@ import LocalAuthentication public typealias TouchIDServiceAuthHandler = (Bool) -> Void +/// Represents service that provides access to authentication via touch id public class TouchIDService { private lazy var laContext: LAContext = { @@ -32,10 +33,18 @@ public class TouchIDService { public init() {} + /// Indicates is it possible to authenticate on this device via touch id public var canAuthenticateByTouchId: Bool { return laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) } + /** + Initiates system touch id authentication process + + - parameters: + - description: prompt on the system alert that describes what for user should attach finger to device + - authHandler: callback, with parameter, indicates if user authenticate successfuly + */ public func authenticateByTouchId(description: String, authHandler: @escaping TouchIDServiceAuthHandler) { laContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: description) { success, _ in