Merge pull request #29 from TouchInstinct/leadkit_update
Leadkit update
This commit is contained in:
commit
9208d41301
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -1,5 +1,15 @@
|
|||
# Changelog
|
||||
|
||||
## 0.1.1
|
||||
|
||||
- **Add**: `acceptableStatusCodes` property in `DefaultNetworkService`.
|
||||
- **Add**: `retry(retryLimit:canRetryClosure:)` to `Observable` extension.
|
||||
- **Removed**: `retryWithinErrors` method from `Observable` extension.
|
||||
- **Update**: LeadKit to `0.6.x` version
|
||||
- **Removed**: `ConnectionError`. (Replaced by `LeadKit.RequestError`)
|
||||
- **Removed**: `handleConnectionErrors` from Observable+Extensions
|
||||
|
||||
|
||||
## 0.1.0
|
||||
|
||||
- **Add**: support for Swift 3.2 / 4
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = "LeadKitAdditions"
|
||||
s.version = "0.1.0"
|
||||
s.version = "0.1.1"
|
||||
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"
|
||||
|
|
@ -16,7 +16,7 @@ Pod::Spec.new do |s|
|
|||
"LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator+Extension.swift",
|
||||
]
|
||||
|
||||
ss.dependency "LeadKit", '0.6.0'
|
||||
ss.dependency "LeadKit", '~> 0.6.0'
|
||||
ss.dependency "KeychainAccess", '3.1.0'
|
||||
ss.dependency "IDZSwiftCommonCrypto", '0.9.1'
|
||||
ss.dependency "InputMask", '3.0.0'
|
||||
|
|
@ -31,7 +31,7 @@ Pod::Spec.new do |s|
|
|||
"LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator.swift",
|
||||
]
|
||||
|
||||
ss.dependency "LeadKit/Core-iOS-Extension", '0.6.0'
|
||||
ss.dependency "LeadKit/Core-iOS-Extension", '~> 0.6.0'
|
||||
ss.dependency "KeychainAccess", '3.1.0'
|
||||
ss.dependency "IDZSwiftCommonCrypto", '0.9.1'
|
||||
ss.dependency "InputMask", '3.0.0'
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@
|
|||
ED0C34181F2906EC00FAE9FD /* ApiError.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E31F2906EC00FAE9FD /* ApiError.swift */; };
|
||||
ED0C34191F2906EC00FAE9FD /* ApiErrorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E41F2906EC00FAE9FD /* ApiErrorProtocol.swift */; };
|
||||
ED0C341A1F2906EC00FAE9FD /* ApiErrorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E41F2906EC00FAE9FD /* ApiErrorProtocol.swift */; };
|
||||
ED0C341B1F2906EC00FAE9FD /* ConnectionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E51F2906EC00FAE9FD /* ConnectionError.swift */; };
|
||||
ED0C341C1F2906EC00FAE9FD /* ConnectionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E51F2906EC00FAE9FD /* ConnectionError.swift */; };
|
||||
ED0C341D1F2906EC00FAE9FD /* Observable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E71F2906EC00FAE9FD /* Observable+Extensions.swift */; };
|
||||
ED0C341E1F2906EC00FAE9FD /* Observable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E71F2906EC00FAE9FD /* Observable+Extensions.swift */; };
|
||||
ED0C341F1F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E81F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift */; };
|
||||
|
|
@ -108,7 +106,6 @@
|
|||
ED0C33E11F2906EC00FAE9FD /* BasePassCodeViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasePassCodeViewModel.swift; sourceTree = "<group>"; };
|
||||
ED0C33E31F2906EC00FAE9FD /* ApiError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiError.swift; sourceTree = "<group>"; };
|
||||
ED0C33E41F2906EC00FAE9FD /* ApiErrorProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiErrorProtocol.swift; sourceTree = "<group>"; };
|
||||
ED0C33E51F2906EC00FAE9FD /* ConnectionError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionError.swift; sourceTree = "<group>"; };
|
||||
ED0C33E71F2906EC00FAE9FD /* Observable+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+Extensions.swift"; sourceTree = "<group>"; };
|
||||
ED0C33E81F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem+Extensions.swift"; sourceTree = "<group>"; };
|
||||
ED0C33E91F2906EC00FAE9FD /* UserDefaults+UserService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserDefaults+UserService.swift"; sourceTree = "<group>"; };
|
||||
|
|
@ -263,7 +260,6 @@
|
|||
children = (
|
||||
ED0C33E31F2906EC00FAE9FD /* ApiError.swift */,
|
||||
ED0C33E41F2906EC00FAE9FD /* ApiErrorProtocol.swift */,
|
||||
ED0C33E51F2906EC00FAE9FD /* ConnectionError.swift */,
|
||||
);
|
||||
path = Enums;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -583,7 +579,6 @@
|
|||
ED0C343D1F2906EC00FAE9FD /* TouchIDService.swift in Sources */,
|
||||
ED0C343F1F2906EC00FAE9FD /* ValidationError.swift in Sources */,
|
||||
ED0C342F1F2906EC00FAE9FD /* BaseUserService.swift in Sources */,
|
||||
ED0C341B1F2906EC00FAE9FD /* ConnectionError.swift in Sources */,
|
||||
ED0C34231F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift in Sources */,
|
||||
ED0C34411F2906EC00FAE9FD /* ValidationItem.swift in Sources */,
|
||||
ED0C341F1F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift in Sources */,
|
||||
|
|
@ -626,7 +621,6 @@
|
|||
ED0C343E1F2906EC00FAE9FD /* TouchIDService.swift in Sources */,
|
||||
ED0C34401F2906EC00FAE9FD /* ValidationError.swift in Sources */,
|
||||
ED0C34301F2906EC00FAE9FD /* BaseUserService.swift in Sources */,
|
||||
ED0C341C1F2906EC00FAE9FD /* ConnectionError.swift in Sources */,
|
||||
ED0C34241F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift in Sources */,
|
||||
ED0C34421F2906EC00FAE9FD /* ValidationItem.swift in Sources */,
|
||||
ED0C34201F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ abstract_target 'LeadKitAdditions' do
|
|||
|
||||
use_frameworks!
|
||||
|
||||
pod "LeadKit", '0.6.0'
|
||||
pod "LeadKit", '~> 0.6.0'
|
||||
end
|
||||
|
||||
target 'LeadKitAdditions iOS Extensions' do
|
||||
|
|
@ -22,7 +22,7 @@ abstract_target 'LeadKitAdditions' do
|
|||
|
||||
use_frameworks!
|
||||
|
||||
pod "LeadKit/Core-iOS-Extension", '0.6.0'
|
||||
pod "LeadKit/Core-iOS-Extension", '~> 0.6.0'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ PODS:
|
|||
- IDZSwiftCommonCrypto (0.10.0)
|
||||
- InputMask (3.0.0)
|
||||
- KeychainAccess (3.1.0)
|
||||
- LeadKit (0.6.0):
|
||||
- LeadKit/Core (= 0.6.0)
|
||||
- LeadKit/Core (0.6.0):
|
||||
- LeadKit (0.6.5):
|
||||
- LeadKit/Core (= 0.6.5)
|
||||
- LeadKit/Core (0.6.5):
|
||||
- CocoaLumberjack/Swift (~> 3.3.0)
|
||||
- ObjectMapper (~> 3.0.0)
|
||||
- RxAlamofire (= 4.0.0)
|
||||
|
|
@ -16,7 +16,7 @@ PODS:
|
|||
- RxSwift (= 4.0.0)
|
||||
- TableKit (~> 2.5.0)
|
||||
- UIScrollView-InfiniteScroll (~> 1.0.0)
|
||||
- LeadKit/Core-iOS-Extension (0.6.0):
|
||||
- LeadKit/Core-iOS-Extension (0.6.5):
|
||||
- CocoaLumberjack/Swift (~> 3.3.0)
|
||||
- ObjectMapper (~> 3.0.0)
|
||||
- RxAlamofire (= 4.0.0)
|
||||
|
|
@ -39,8 +39,8 @@ DEPENDENCIES:
|
|||
- IDZSwiftCommonCrypto
|
||||
- InputMask (= 3.0.0)
|
||||
- KeychainAccess (= 3.1.0)
|
||||
- LeadKit (= 0.6.0)
|
||||
- LeadKit/Core-iOS-Extension (= 0.6.0)
|
||||
- LeadKit (~> 0.6.0)
|
||||
- LeadKit/Core-iOS-Extension (~> 0.6.0)
|
||||
- SwiftValidator (= 5.0.0)
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
|
|
@ -49,7 +49,7 @@ SPEC CHECKSUMS:
|
|||
IDZSwiftCommonCrypto: 4eef2c46e262dfbcbc1fd76365e066336680ad7d
|
||||
InputMask: 37c273bde6705187d80cf0b4240cb42ea92096c3
|
||||
KeychainAccess: 94c5540b32eabf7bc32bfb976a268e8ea05fd6da
|
||||
LeadKit: a8b51716890f6d19e2b4e6e5217883d7834d4185
|
||||
LeadKit: 583c724f25852e40eebad8af5a945e101c282fde
|
||||
ObjectMapper: 92230db59bf8f341a5c3a3cf0b9fbdde3cf0d87f
|
||||
RxAlamofire: 6ea579ac53bf14cb4bc7049a3866e5a769989b1d
|
||||
RxCocoa: d62846ca96495d862fa4c59ea7d87e5031d7340e
|
||||
|
|
@ -58,6 +58,6 @@ SPEC CHECKSUMS:
|
|||
TableKit: 42d4dff2944f273cdeec2ef6352064eb6a9a355b
|
||||
UIScrollView-InfiniteScroll: c132d6d5851daff229ab4a1060ccf70a05a051c9
|
||||
|
||||
PODFILE CHECKSUM: 96dea11fb103a275758c4ef3e731c4cce206746d
|
||||
PODFILE CHECKSUM: 9ba64f509b50aaf860b0df0c12cca7969aa50842
|
||||
|
||||
COCOAPODS: 1.3.1
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2017 Touch Instinct
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the Software), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Describes "no connection to server" error
|
||||
public enum ConnectionError: LocalizedError {
|
||||
|
||||
case noConnection
|
||||
|
||||
}
|
||||
|
|
@ -23,53 +23,29 @@
|
|||
import RxSwift
|
||||
import Alamofire
|
||||
import CocoaLumberjack
|
||||
import LeadKit
|
||||
|
||||
public typealias VoidBlock = () -> Void
|
||||
|
||||
public extension Observable {
|
||||
|
||||
/// Handles connection errors during request
|
||||
func handleConnectionErrors() -> Observable<Observable.E> {
|
||||
return observeOn(CurrentThreadScheduler.instance)
|
||||
/// A closure that checks for "retryable" error
|
||||
typealias CanRetryClosure = (Error) -> Bool
|
||||
|
||||
// handle no internet connection
|
||||
.do(onError: { error in
|
||||
if let urlError = error as? URLError,
|
||||
urlError.code == .notConnectedToInternet ||
|
||||
urlError.code == .timedOut {
|
||||
DDLogError("Error: No Connection")
|
||||
throw ConnectionError.noConnection
|
||||
}
|
||||
})
|
||||
|
||||
// handle unacceptable http status code like "500 Internal Server Error" and others
|
||||
.do(onError: { error in
|
||||
if let afError = error as? AFError,
|
||||
case let .responseValidationFailed(reason: reason) = afError,
|
||||
case let .unacceptableStatusCode(code: statusCode) = reason {
|
||||
DDLogError("Error: Unacceptable HTTP Status Code - \(statusCode)")
|
||||
throw ConnectionError.noConnection
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
*/
|
||||
func retryWithinErrors(_ errorTypes: [Error.Type] = [ConnectionError.self],
|
||||
retryLimit: UInt = DefaultNetworkService.retryLimit)
|
||||
-> Observable<Observable.E> {
|
||||
/// Allow to configure request to restart if error occured
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - retryLimit: how many times request can restarts
|
||||
/// - canRetryClosure: a closure that checks for "retryable" error
|
||||
/// - Returns: An observable sequence producing the elements of the given sequence repeatedly
|
||||
/// until it terminates successfully or is notified to error or complete.
|
||||
func retry(retryLimit: UInt = DefaultNetworkService.retryLimit,
|
||||
canRetryClosure: @escaping CanRetryClosure) -> Observable<Observable.E> {
|
||||
|
||||
return observeOn(CurrentThreadScheduler.instance)
|
||||
.retryWhen { errors -> Observable<Observable.E> in
|
||||
return errors.enumerated().flatMap { attempt, error -> Observable<Observable.E> in
|
||||
let canRetry = errorTypes.contains { type(of: error) == $0 }
|
||||
|
||||
return (canRetry && attempt < retryLimit - 1) ? self : .error(error)
|
||||
.retryWhen { errorsObservable -> Observable<Observable.E> in
|
||||
return errorsObservable.enumerated().flatMap {
|
||||
(canRetryClosure($1) && $0 < retryLimit - 1) ? self : .error($1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ open class ApiNetworkService: DefaultNetworkService {
|
|||
let apiResponseRequest = rxRequest(with: parameters) as Observable<(response: HTTPURLResponse, model: ApiResponse)>
|
||||
|
||||
return apiResponseRequest
|
||||
.handleConnectionErrors()
|
||||
.map {
|
||||
if $0.model.errorCode == 0 {
|
||||
return try T(JSON: try cast($0.model.result) as [String: Any])
|
||||
|
|
@ -48,7 +47,6 @@ open class ApiNetworkService: DefaultNetworkService {
|
|||
let apiResponseRequest = rxRequest(with: parameters) as Observable<(response: HTTPURLResponse, model: ApiResponse)>
|
||||
|
||||
return apiResponseRequest
|
||||
.handleConnectionErrors()
|
||||
.map {
|
||||
if $0.model.errorCode == 0,
|
||||
let result = $0.model.result as? Bool {
|
||||
|
|
|
|||
|
|
@ -43,10 +43,18 @@ open class DefaultNetworkService: NetworkService {
|
|||
return 20.0
|
||||
}
|
||||
|
||||
public override init(sessionManager: SessionManager) {
|
||||
super.init(sessionManager: sessionManager)
|
||||
/// The default acceptable range 200…299
|
||||
open var acceptableStatusCodes: [Int] {
|
||||
return Alamofire.SessionManager.defaultAcceptableStatusCodes
|
||||
}
|
||||
|
||||
activityIndicatorBinding()?.disposed(by: disposeBag)
|
||||
public init(sessionManager: SessionManager) {
|
||||
super.init(sessionManager: sessionManager, acceptableStatusCodes: acceptableStatusCodes)
|
||||
|
||||
// Fatal error: `drive*` family of methods can be only called from `MainThread`
|
||||
DispatchQueue.main.async {
|
||||
self.activityIndicatorBinding()?.disposed(by: self.disposeBag)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Default Values
|
||||
|
|
|
|||
Loading…
Reference in New Issue