From 85e58127b7c997d8725e44357fd0ab446fe8465b Mon Sep 17 00:00:00 2001 From: Madhas Date: Fri, 25 May 2018 15:19:30 +0300 Subject: [PATCH] add SesionManager class some refactor --- LeadKit.xcodeproj/project.pbxproj | 10 +++++ Sources/Classes/Services/NetworkService.swift | 8 ++-- Sources/Classes/Services/SessionManager.swift | 40 +++++++++++++++++++ .../AlamofireManager+Extensions.swift | 27 ++++--------- .../AlamofireRequest+Extensions.swift | 2 +- .../NetworkServiceConfiguration.swift | 7 ++-- 6 files changed, 65 insertions(+), 29 deletions(-) create mode 100644 Sources/Classes/Services/SessionManager.swift diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 99199189..dc47f354 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -551,6 +551,10 @@ B84CB06920B702240090DB91 /* Codable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Codable+Extensions.swift */; }; B84CB06A20B702240090DB91 /* Codable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Codable+Extensions.swift */; }; B84CB06B20B702260090DB91 /* Codable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Codable+Extensions.swift */; }; + B84CB06D20B8325D0090DB91 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB06C20B8325D0090DB91 /* SessionManager.swift */; }; + B84CB06E20B8325D0090DB91 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB06C20B8325D0090DB91 /* SessionManager.swift */; }; + B84CB06F20B8325D0090DB91 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB06C20B8325D0090DB91 /* SessionManager.swift */; }; + B84CB07020B8325D0090DB91 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB06C20B8325D0090DB91 /* SessionManager.swift */; }; B84D64B120A70B7000DD76DA /* NetworkServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84D64B020A70B7000DD76DA /* NetworkServiceTests.swift */; }; B84D64B220A70B7000DD76DA /* NetworkServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84D64B020A70B7000DD76DA /* NetworkServiceTests.swift */; }; B84D64B320A70B7000DD76DA /* NetworkServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84D64B020A70B7000DD76DA /* NetworkServiceTests.swift */; }; @@ -801,6 +805,7 @@ A6F32C071F6EBDAA00AC08EE /* String+LocalizedComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+LocalizedComponent.swift"; sourceTree = ""; }; A6F32C0E1F6EBE8E00AC08EE /* StringExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionTests.swift; sourceTree = ""; }; A854A36EB179651E6D0CC9FB /* Pods_LeadKit_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B84CB06C20B8325D0090DB91 /* SessionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManager.swift; sourceTree = ""; }; B84D64B020A70B7000DD76DA /* NetworkServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkServiceTests.swift; sourceTree = ""; }; B85B766620AC4EA300F837C4 /* Album.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Album.swift; sourceTree = ""; }; B85B766B20AC51BE00F837C4 /* AlbumsContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumsContainer.swift; sourceTree = ""; }; @@ -924,6 +929,7 @@ isa = PBXGroup; children = ( 671461D31EB3396E00EAB194 /* NetworkService.swift */, + B84CB06C20B8325D0090DB91 /* SessionManager.swift */, ); path = Services; sourceTree = ""; @@ -2674,6 +2680,7 @@ 6727476E206CCDDB00725163 /* ViewBackground+Configuration.swift in Sources */, 671463701EB3396E00EAB194 /* ApiRequestParameters.swift in Sources */, 676B22A2206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */, + B84CB06D20B8325D0090DB91 /* SessionManager.swift in Sources */, A658E5501F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift in Sources */, 673564F12068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift in Sources */, 671462EC1EB3396E00EAB194 /* UIImage+Extensions.swift in Sources */, @@ -2842,6 +2849,7 @@ 671462A21EB3396E00EAB194 /* Double+Rounding.swift in Sources */, 67955D54206D216B0021ECD2 /* Singleton.swift in Sources */, 67EB7FF32061682F00BDD9FB /* TotalCountCursorListingResult+DefaultTotalCountCursorListingResult.swift in Sources */, + B84CB06F20B8325D0090DB91 /* SessionManager.swift in Sources */, 67EB7FED2061667900BDD9FB /* DefaultTotalCountCursorListingResult.swift in Sources */, 6714637E1EB3396E00EAB194 /* ImageDrawingOperation.swift in Sources */, 671463361EB3396E00EAB194 /* DrawingOperation.swift in Sources */, @@ -3018,6 +3026,7 @@ 671462531EB3396E00EAB194 /* StaticCursor.swift in Sources */, 6714629F1EB3396E00EAB194 /* CursorType+Slice.swift in Sources */, 6714636B1EB3396E00EAB194 /* ConfigurableView.swift in Sources */, + B84CB07020B8325D0090DB91 /* SessionManager.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3160,6 +3169,7 @@ A676AE561F98112F001F9214 /* ObservableMappable.swift in Sources */, 6737CFA4207220960063E056 /* SeparatorConfiguration+Extensions.swift in Sources */, 67926237206EB0AE00308E62 /* CellSeparatorType.swift in Sources */, + B84CB06E20B8325D0090DB91 /* SessionManager.swift in Sources */, 6774527A206252020024EEEF /* DataLoadingState.swift in Sources */, 6714628D1EB3396E00EAB194 /* CGImage+Alpha.swift in Sources */, 67745269206249360024EEEF /* UITableView+PaginationWrappable.swift in Sources */, diff --git a/Sources/Classes/Services/NetworkService.swift b/Sources/Classes/Services/NetworkService.swift index cf91bffa..04e8b0c8 100644 --- a/Sources/Classes/Services/NetworkService.swift +++ b/Sources/Classes/Services/NetworkService.swift @@ -36,7 +36,7 @@ open class NetworkService { private var disposeBag = DisposeBag() public let configuration: NetworkServiceConfiguration - public let sessionManager: Alamofire.SessionManager + public let sessionManager: SessionManager var requestCount: Driver { return requestCountRelay.asDriver() @@ -64,8 +64,7 @@ open class NetworkService { -> Observable<(response: HTTPURLResponse, model: T)> { return sessionManager.rx.responseObservableModel(requestParameters: parameters, - decoder: decoder, - acceptableStatusCodes: configuration.acceptableStatusCodes) + decoder: decoder) .counterTracking(for: self) } @@ -78,8 +77,7 @@ open class NetworkService { -> Observable<(response: HTTPURLResponse, model: T)> { return sessionManager.rx.responseModel(requestParameters: parameters, - decoder: decoder, - acceptableStatusCodes: configuration.acceptableStatusCodes) + decoder: decoder) .counterTracking(for: self) } diff --git a/Sources/Classes/Services/SessionManager.swift b/Sources/Classes/Services/SessionManager.swift new file mode 100644 index 00000000..b57a70d1 --- /dev/null +++ b/Sources/Classes/Services/SessionManager.swift @@ -0,0 +1,40 @@ +// +// Copyright (c) 2018 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 Alamofire + +open class SessionManager: Alamofire.SessionManager { + + public let acceptableStatusCodes: Set + public let mappingQueue: DispatchQueue + + public init(configuration: URLSessionConfiguration, + serverTrustPolicyManager: ServerTrustPolicyManager, + acceptableStatusCodes: Set, + mappingQueue: DispatchQueue) { + + self.acceptableStatusCodes = acceptableStatusCodes + self.mappingQueue = mappingQueue + + super.init(configuration: configuration, serverTrustPolicyManager: serverTrustPolicyManager) + } +} diff --git a/Sources/Extensions/Alamofire/AlamofireManager+Extensions.swift b/Sources/Extensions/Alamofire/AlamofireManager+Extensions.swift index f25d700f..567f0e23 100644 --- a/Sources/Extensions/Alamofire/AlamofireManager+Extensions.swift +++ b/Sources/Extensions/Alamofire/AlamofireManager+Extensions.swift @@ -24,21 +24,14 @@ import Alamofire import RxSwift import RxAlamofire -public extension Alamofire.SessionManager { - - /// The default acceptable range 200...299 - static let defaultAcceptableStatusCodes = Set(200..<300) - -} - -public extension Reactive where Base: Alamofire.SessionManager { +public extension Reactive where Base: SessionManager { /// Method which executes request with given api parameters /// /// - Parameter requestParameters: api parameters to pass Alamofire /// - Returns: Observable with request func apiRequest(requestParameters: ApiRequestParameters, - acceptableStatusCodes: Set = Base.defaultAcceptableStatusCodes) + acceptableStatusCodes: Set) -> Observable { return request(requestParameters.method, @@ -56,13 +49,11 @@ public extension Reactive where Base: Alamofire.SessionManager { /// - Parameter mappingQueue: The dispatch queue to use for mapping /// - Returns: Observable with HTTP URL Response and target object func responseModel(requestParameters: ApiRequestParameters, - decoder: JSONDecoder, - mappingQueue: DispatchQueue = .global(), - acceptableStatusCodes: Set = Base.defaultAcceptableStatusCodes) + decoder: JSONDecoder) -> Observable<(response: HTTPURLResponse, model: T)> { - return apiRequest(requestParameters: requestParameters, acceptableStatusCodes: acceptableStatusCodes) - .flatMap { $0.rx.apiResponse(mappingQueue: mappingQueue, decoder: decoder) } + return apiRequest(requestParameters: requestParameters, acceptableStatusCodes: base.acceptableStatusCodes) + .flatMap { $0.rx.apiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) } } /// Method that executes request and serializes response into target object @@ -72,13 +63,11 @@ public extension Reactive where Base: Alamofire.SessionManager { /// - Parameter mappingQueue: The dispatch queue to use for mapping /// - Returns: Observable with HTTP URL Response and target object func responseObservableModel(requestParameters: ApiRequestParameters, - decoder: JSONDecoder, - mappingQueue: DispatchQueue = .global(), - acceptableStatusCodes: Set = Base.defaultAcceptableStatusCodes) + decoder: JSONDecoder) -> Observable<(response: HTTPURLResponse, model: T)> { - return apiRequest(requestParameters: requestParameters, acceptableStatusCodes: acceptableStatusCodes) - .flatMap { $0.rx.observableApiResponse(mappingQueue: mappingQueue, decoder: decoder) } + return apiRequest(requestParameters: requestParameters, acceptableStatusCodes: base.acceptableStatusCodes) + .flatMap { $0.rx.observableApiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) } } } diff --git a/Sources/Extensions/Alamofire/AlamofireRequest+Extensions.swift b/Sources/Extensions/Alamofire/AlamofireRequest+Extensions.swift index e46d9703..47eef191 100644 --- a/Sources/Extensions/Alamofire/AlamofireRequest+Extensions.swift +++ b/Sources/Extensions/Alamofire/AlamofireRequest+Extensions.swift @@ -57,7 +57,7 @@ public extension Reactive where Base: DataRequest { } } - func response(onQueue queue: DispatchQueue) -> Observable<(HTTPURLResponse, Data)> { + private func response(onQueue queue: DispatchQueue) -> Observable<(HTTPURLResponse, Data)> { return responseData() .observeOn(SerialDispatchQueueScheduler(queue: queue, internalSerialQueueName: queue.label)) .catchError { diff --git a/Sources/Structures/NetworkService/NetworkServiceConfiguration.swift b/Sources/Structures/NetworkService/NetworkServiceConfiguration.swift index a5c3d03a..0424a985 100644 --- a/Sources/Structures/NetworkService/NetworkServiceConfiguration.swift +++ b/Sources/Structures/NetworkService/NetworkServiceConfiguration.swift @@ -39,9 +39,6 @@ public struct NetworkServiceConfiguration { /// Server trust policies. public var serverTrustPolicies: [String: ServerTrustPolicy] - /// Acceptable status codes for validation - public var acceptableStatusCodes: Set = Alamofire.SessionManager.defaultAcceptableStatusCodes - /// Session configuration for potential fine tuning public var sessionConfiguration: URLSessionConfiguration @@ -69,7 +66,9 @@ public extension NetworkServiceConfiguration { /// SessionManager constructed with given parameters (session configuration and trust policies) var sessionManager: SessionManager { return SessionManager(configuration: sessionConfiguration, - serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)) + serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies), + acceptableStatusCodes: Set(200..<300), + mappingQueue: .global()) } /// Convenient method to create ApiRequestParameters.