From a53dad977780e054a856fdcb6c7da6bdd4e769be Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Wed, 6 Mar 2019 14:39:37 +0300 Subject: [PATCH 01/36] Add validStatusCodes pararmeter to request methods --- CHANGELOG.md | 4 +++ LeadKit.podspec | 2 +- Sources/Classes/Services/NetworkService.swift | 27 ++++++++++----- .../Alamofire/SessionManager+Extensions.swift | 34 ++++++++++++------- Sources/Info-iOS.plist | 2 +- Sources/Info-tvOS.plist | 2 +- Sources/Info-watchOS.plist | 2 +- 7 files changed, 49 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abfac830..240e0cf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### 0.9.9 +- **Add**: `validStatusCodes` parameter to request methods in `NetworkService` class, that expands valid status codes for request. +- **Add**: `validStatusCodes` parameter to response methods in `SessionManager` extension, that expands valid status codes for request. + ### 0.9.8 - **Add**: `rxDataRequest` method to `NetworkService` class, that performs reactive request to get data and http response. - **Add**: `responseData` method to `SessionManager` extension, that executes request and returns data. diff --git a/LeadKit.podspec b/LeadKit.podspec index ed665e75..935c3e96 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.9.8" + s.version = "0.9.9" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/Sources/Classes/Services/NetworkService.swift b/Sources/Classes/Services/NetworkService.swift index 08879f45..7c8e6c38 100644 --- a/Sources/Classes/Services/NetworkService.swift +++ b/Sources/Classes/Services/NetworkService.swift @@ -55,39 +55,50 @@ open class NetworkService { /// Perform reactive request to get mapped ObservableMappable model and http response /// - /// - Parameter parameters: api parameters to pass Alamofire - /// - Parameter decoder: json decoder to decode response data + /// - Parameters: + /// - parameters: api parameters to pass Alamofire + /// - validStatusCodes: set of additional valid status codes + /// - decoder: json decoder to decode response data /// - Returns: Observable of tuple containing (HTTPURLResponse, ObservableMappable) public func rxObservableRequest(with parameters: ApiRequestParameters, + validStatusCodes: Set = [], decoder: JSONDecoder = JSONDecoder()) -> Observable> { return sessionManager.rx.responseObservableModel(requestParameters: parameters, + validStatusCodes: validStatusCodes, decoder: decoder) .counterTracking(for: self) } /// Perform reactive request to get mapped ImmutableMappable model and http response /// - /// - Parameter parameters: api parameters to pass Alamofire - /// - Parameter decoder: json decoder to decode response data + /// - Parameters: + /// - parameters: api parameters to pass Alamofire + /// - validStatusCodes: set of additional valid status codes + /// - decoder: json decoder to decode response data /// - Returns: Observable of tuple containing (HTTPURLResponse, ImmutableMappable) - public func rxRequest(with parameters: ApiRequestParameters, decoder: JSONDecoder = JSONDecoder()) + public func rxRequest(with parameters: ApiRequestParameters, + validStatusCodes: Set = [], + decoder: JSONDecoder = JSONDecoder()) -> Observable> { return sessionManager.rx.responseModel(requestParameters: parameters, + validStatusCodes: validStatusCodes, decoder: decoder) .counterTracking(for: self) } /// Perform reactive request to get data and http response /// - /// - Parameter parameters: api parameters to pass Alamofire + /// - Parameters: + /// - parameters: api parameters to pass Alamofire + /// - validStatusCodes: set of additional valid status codes /// - Returns: Observable of tuple containing (HTTPURLResponse, Data) - public func rxDataRequest(with parameters: ApiRequestParameters) + public func rxDataRequest(with parameters: ApiRequestParameters, validStatusCodes: Set = []) -> Observable { - return sessionManager.rx.responseData(requestParameters: parameters) + return sessionManager.rx.responseData(requestParameters: parameters, validStatusCodes: validStatusCodes) .counterTracking(for: self) } } diff --git a/Sources/Extensions/Alamofire/SessionManager+Extensions.swift b/Sources/Extensions/Alamofire/SessionManager+Extensions.swift index 161230ba..52399baf 100644 --- a/Sources/Extensions/Alamofire/SessionManager+Extensions.swift +++ b/Sources/Extensions/Alamofire/SessionManager+Extensions.swift @@ -68,9 +68,11 @@ public extension Reactive where Base: SessionManager { /// Method which executes request with given api parameters /// - /// - Parameter requestParameters: api parameters to pass Alamofire + /// - Parameters: + /// - requestParameters: api parameters to pass Alamofire + /// - validStatusCodes: set of additional valid status codes /// - Returns: Observable with request - func apiRequest(requestParameters: ApiRequestParameters) + func apiRequest(requestParameters: ApiRequestParameters, validStatusCodes: Set) -> Observable { let requestObservable: Observable @@ -104,20 +106,23 @@ public extension Reactive where Base: SessionManager { } return requestObservable - .map { $0.validate(statusCode: self.base.acceptableStatusCodes) } + .map { $0.validate(statusCode: self.base.acceptableStatusCodes.union(validStatusCodes)) } .catchAsRequestError() } /// Method that executes request and serializes response into target object /// - /// - Parameter requestParameters: api parameters to pass Alamofire - /// - Parameter decoder: json decoder to decode response data + /// - Parameters: + /// - requestParameters: api parameters to pass Alamofire + /// - validStatusCodes: set of additional valid status codes + /// - decoder: json decoder to decode response data /// - Returns: Observable with HTTP URL Response and target object func responseModel(requestParameters: ApiRequestParameters, + validStatusCodes: Set, decoder: JSONDecoder) -> Observable> { - return apiRequest(requestParameters: requestParameters) + return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) .flatMap { $0.rx.apiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) .catchAsRequestError(with: $0) @@ -126,14 +131,17 @@ public extension Reactive where Base: SessionManager { /// Method that executes request and serializes response into target object /// - /// - Parameter requestParameters: api parameters to pass Alamofire - /// - Parameter decoder: json decoder to decode response data + /// - Parameters: + /// - requestParameters: api parameters to pass Alamofire + /// - validStatusCodes: set of additional valid status codes + /// - decoder: json decoder to decode response data /// - Returns: Observable with HTTP URL Response and target object func responseObservableModel(requestParameters: ApiRequestParameters, + validStatusCodes: Set, decoder: JSONDecoder) -> Observable> { - return apiRequest(requestParameters: requestParameters) + return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) .flatMap { $0.rx.observableApiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) .catchAsRequestError(with: $0) @@ -142,12 +150,14 @@ public extension Reactive where Base: SessionManager { /// Method that executes request and returns data /// - /// - Parameter requestParameters: api parameters to pass Alamofire + /// - Parameters: + /// - requestParameters: api parameters to pass Alamofire + /// - validStatusCodes: set of additional valid status codes /// - Returns: Observable with HTTP URL Response and Data - func responseData(requestParameters: ApiRequestParameters) + func responseData(requestParameters: ApiRequestParameters, validStatusCodes: Set) -> Observable { - return apiRequest(requestParameters: requestParameters) + return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) .flatMap { $0.rx.responseResult(queue: self.base.mappingQueue, responseSerializer: DataRequest.dataResponseSerializer()) diff --git a/Sources/Info-iOS.plist b/Sources/Info-iOS.plist index 1d137243..dd711d9f 100644 --- a/Sources/Info-iOS.plist +++ b/Sources/Info-iOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.7 + 0.9.9 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist index 1d137243..dd711d9f 100644 --- a/Sources/Info-tvOS.plist +++ b/Sources/Info-tvOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.7 + 0.9.9 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist index 1d137243..dd711d9f 100644 --- a/Sources/Info-watchOS.plist +++ b/Sources/Info-watchOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.7 + 0.9.9 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass From 95202a4ff18a6d64a55f86d74fe629b489435328 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Wed, 6 Mar 2019 16:42:26 +0300 Subject: [PATCH 02/36] Fixed documentation --- Sources/Classes/Services/NetworkService.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Classes/Services/NetworkService.swift b/Sources/Classes/Services/NetworkService.swift index 7c8e6c38..5205ce0c 100644 --- a/Sources/Classes/Services/NetworkService.swift +++ b/Sources/Classes/Services/NetworkService.swift @@ -56,7 +56,7 @@ open class NetworkService { /// Perform reactive request to get mapped ObservableMappable model and http response /// /// - Parameters: - /// - parameters: api parameters to pass Alamofire + /// - parameters: api parameters to pass to Alamofire /// - validStatusCodes: set of additional valid status codes /// - decoder: json decoder to decode response data /// - Returns: Observable of tuple containing (HTTPURLResponse, ObservableMappable) @@ -74,7 +74,7 @@ open class NetworkService { /// Perform reactive request to get mapped ImmutableMappable model and http response /// /// - Parameters: - /// - parameters: api parameters to pass Alamofire + /// - parameters: api parameters to pass to Alamofire /// - validStatusCodes: set of additional valid status codes /// - decoder: json decoder to decode response data /// - Returns: Observable of tuple containing (HTTPURLResponse, ImmutableMappable) @@ -92,7 +92,7 @@ open class NetworkService { /// Perform reactive request to get data and http response /// /// - Parameters: - /// - parameters: api parameters to pass Alamofire + /// - parameters: api parameters to pass to Alamofire /// - validStatusCodes: set of additional valid status codes /// - Returns: Observable of tuple containing (HTTPURLResponse, Data) public func rxDataRequest(with parameters: ApiRequestParameters, validStatusCodes: Set = []) From 1c97a22a6f456dc674d3b8b988cceaf1fc5042a7 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Wed, 6 Mar 2019 18:49:10 +0300 Subject: [PATCH 03/36] Fixed cartfile --- Cartfile | 5 +++-- Cartfile.resolved | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cartfile b/Cartfile index 94e96bd5..a662e7b8 100644 --- a/Cartfile +++ b/Cartfile @@ -1,5 +1,6 @@ -binary "https://raw.github.com/petropavel13/CarthageBinaries/master/SwiftDate/SwiftDate.json" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/SwiftDate/SwiftDate.json" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/Alamofire/Alamofire.json" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxAlamofire/RxAlamofire.json" github "ReactiveX/RxSwift" -binary "https://raw.github.com/petropavel13/CarthageBinaries/master/RxAlamofire/RxAlamofire.json" github "maxsokolov/TableKit" github "pronebird/UIScrollView-InfiniteScroll" \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index ba371d3c..e2b432b6 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,6 +1,5 @@ -github "Alamofire/Alamofire" "4.8.1" -github "ReactiveX/RxSwift" "4.4.0" -github "RxSwiftCommunity/RxAlamofire" "4.3.0" -github "malcommac/SwiftDate" "5.1.0" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxAlamofire/RxAlamofire.json" "4.3.0" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/SwiftDate/SwiftDate.json" "5.1.0" +github "ReactiveX/RxSwift" "4.4.1" github "maxsokolov/TableKit" "2.8.1" github "pronebird/UIScrollView-InfiniteScroll" "1.1.0" From caa93bfd1fbd9897714f92e1aff6df123a2b41c3 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Wed, 13 Mar 2019 14:11:00 +0500 Subject: [PATCH 04/36] Scheme updated. Libs updated --- Cartfile.resolved | 3 +- LeadKit.xcodeproj/project.pbxproj | 174 ++++++++++++++++++ .../xcschemes/LeadKit iOS Extensions.xcscheme | 99 ---------- Podfile | 14 -- Podfile.lock | 4 +- 5 files changed, 178 insertions(+), 116 deletions(-) delete mode 100644 LeadKit.xcodeproj/xcshareddata/xcschemes/LeadKit iOS Extensions.xcscheme diff --git a/Cartfile.resolved b/Cartfile.resolved index e2b432b6..c9c2dbe3 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,5 +1,6 @@ +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/Alamofire/Alamofire.json" "4.8.1" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxAlamofire/RxAlamofire.json" "4.3.0" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/SwiftDate/SwiftDate.json" "5.1.0" -github "ReactiveX/RxSwift" "4.4.1" +github "ReactiveX/RxSwift" "4.4.2" github "maxsokolov/TableKit" "2.8.1" github "pronebird/UIScrollView-InfiniteScroll" "1.1.0" diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index bb5d61e7..55011f8b 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -7,13 +7,16 @@ objects = { /* Begin PBXBuildFile section */ + 21A3B105772E876EA9F3B332 /* Pods_LeadKit_LeadKit_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30DABA466214FE9ABDE2E685 /* Pods_LeadKit_LeadKit_tvOS.framework */; }; 36977763200CF12100ED9C6E /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36DAAF502007CC920090BE0D /* UITableView+Extensions.swift */; }; 36DAAF512007CC920090BE0D /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36DAAF502007CC920090BE0D /* UITableView+Extensions.swift */; }; 36FE777020F669E300284C09 /* String+ConvertToHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */; }; 36FE777220F669E300284C09 /* String+ConvertToHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */; }; 36FE777320F669E300284C09 /* String+ConvertToHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */; }; + 4098E82DE6429EF5B01B43D7 /* Pods_LeadKit_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94DC826707A87C30CD4DB157 /* Pods_LeadKit_tvOSTests.framework */; }; 40F118471F8FEF97004AADAF /* AppearanceConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */; }; 40F118491F8FF223004AADAF /* TableRow+AppearanceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118481F8FF223004AADAF /* TableRow+AppearanceExtension.swift */; }; + 5F9DF5361ADE4207C1032252 /* Pods_LeadKit_LeadKit_watchOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48C5033AB9D51F5BA39AAAFC /* Pods_LeadKit_LeadKit_watchOS.framework */; }; 67051ADB1EBC7C36008EADC0 /* SpinnerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67051ADA1EBC7C36008EADC0 /* SpinnerView.swift */; }; 67051ADD1EBC7C36008EADC0 /* SpinnerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67051ADA1EBC7C36008EADC0 /* SpinnerView.swift */; }; 6713C23720AF0C4D00875921 /* NetworkOperationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6713C23620AF0C4D00875921 /* NetworkOperationState.swift */; }; @@ -522,6 +525,7 @@ A6F32C0C1F6EBE5C00AC08EE /* String+LocalizedComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C071F6EBDAA00AC08EE /* String+LocalizedComponent.swift */; }; A6F32C101F6EBE9600AC08EE /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C0E1F6EBE8E00AC08EE /* StringExtensionTests.swift */; }; A6F32C121F6EBE9800AC08EE /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C0E1F6EBE8E00AC08EE /* StringExtensionTests.swift */; }; + A916FFFB6784C37DCD2217D1 /* Pods_LeadKit_LeadKit_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D75C8B2B1AE880554CF104E /* Pods_LeadKit_LeadKit_iOS.framework */; }; B84CB06A20B702240090DB91 /* Encodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */; }; B84CB06B20B702260090DB91 /* Encodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */; }; B84CB06D20B8325D0090DB91 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB06C20B8325D0090DB91 /* SessionManager.swift */; }; @@ -547,6 +551,7 @@ EFBE57D31EC35EF20040E00A /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57CF1EC35EF20040E00A /* Array+Extensions.swift */; }; EFBE57DB1EC361620040E00A /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57DA1EC361620040E00A /* UIView+Layout.swift */; }; EFBE57DE1EC361620040E00A /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57DA1EC361620040E00A /* UIView+Layout.swift */; }; + F9D8CB4031C3AFFF70F4B040 /* Pods_LeadKit_iOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98DD36236D8020BB8F15D803 /* Pods_LeadKit_iOSTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -567,10 +572,16 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 1D98F1F1E572E6B0AFA5D6DD /* Pods-LeadKit-LeadKit watchOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit watchOS.release.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit watchOS/Pods-LeadKit-LeadKit watchOS.release.xcconfig"; sourceTree = ""; }; + 2D48ED6E97C783C9AB880754 /* Pods-LeadKit-LeadKit tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit tvOS.release.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit tvOS/Pods-LeadKit-LeadKit tvOS.release.xcconfig"; sourceTree = ""; }; + 30DABA466214FE9ABDE2E685 /* Pods_LeadKit_LeadKit_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_LeadKit_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 36DAAF502007CC920090BE0D /* UITableView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+Extensions.swift"; sourceTree = ""; }; 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ConvertToHost.swift"; sourceTree = ""; }; + 3EB2AD073C7659E7B3AD592B /* Pods-LeadKit tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit tvOSTests/Pods-LeadKit tvOSTests.debug.xcconfig"; sourceTree = ""; }; 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceConfigurable.swift; sourceTree = ""; }; 40F118481F8FF223004AADAF /* TableRow+AppearanceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TableRow+AppearanceExtension.swift"; sourceTree = ""; }; + 48C5033AB9D51F5BA39AAAFC /* Pods_LeadKit_LeadKit_watchOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_LeadKit_watchOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5D75C8B2B1AE880554CF104E /* Pods_LeadKit_LeadKit_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_LeadKit_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 67051ADA1EBC7C36008EADC0 /* SpinnerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinnerView.swift; sourceTree = ""; }; 6713C23620AF0C4D00875921 /* NetworkOperationState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkOperationState.swift; sourceTree = ""; }; 6713C23B20AF0D5900875921 /* NetworkOperationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkOperationModel.swift; sourceTree = ""; }; @@ -790,6 +801,10 @@ 820CAD8320B43B080033EF94 /* PaginationWrapperDelegate+DefaultImplementation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PaginationWrapperDelegate+DefaultImplementation.swift"; sourceTree = ""; }; 825F8F2720B3384C00594857 /* PaginationWrapperUIDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationWrapperUIDelegate.swift; sourceTree = ""; }; 82F8BB171F5DDED100C1061B /* Single+DeferredJust.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Single+DeferredJust.swift"; sourceTree = ""; }; + 90DA5FD2982B6AB31C3E8336 /* Pods-LeadKit iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit iOSTests.release.xcconfig"; path = "Target Support Files/Pods-LeadKit iOSTests/Pods-LeadKit iOSTests.release.xcconfig"; sourceTree = ""; }; + 94DC826707A87C30CD4DB157 /* Pods_LeadKit_tvOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_tvOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 98DD36236D8020BB8F15D803 /* Pods_LeadKit_iOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_iOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A29A396D649FAF4088CA5294 /* Pods-LeadKit iOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit iOSTests.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit iOSTests/Pods-LeadKit iOSTests.debug.xcconfig"; sourceTree = ""; }; A658E54C1F8CD7790093527A /* TableRow+SeparatorsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TableRow+SeparatorsExtensions.swift"; sourceTree = ""; }; A658E54F1F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+SeparatorRowBoxExtensions.swift"; sourceTree = ""; }; A66428A61F8A653600C6308D /* SeparatorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorCell.swift; sourceTree = ""; }; @@ -809,10 +824,15 @@ B85B766620AC4EA300F837C4 /* Album.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Album.swift; sourceTree = ""; }; B85B766B20AC51BE00F837C4 /* AlbumsContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumsContainer.swift; sourceTree = ""; }; B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Encodable+Extensions.swift"; sourceTree = ""; }; + CC02AE0FB1F711D5C498A8A6 /* Pods-LeadKit-LeadKit tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit tvOS.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit tvOS/Pods-LeadKit-LeadKit tvOS.debug.xcconfig"; sourceTree = ""; }; + D4922783EEF858FE8CF8C482 /* Pods-LeadKit tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-LeadKit tvOSTests/Pods-LeadKit tvOSTests.release.xcconfig"; sourceTree = ""; }; D93221ED20A44896003799D5 /* Double+RoundingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+RoundingTests.swift"; sourceTree = ""; }; + E53A1E9E9F77B0F30940382F /* Pods-LeadKit-LeadKit watchOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit watchOS.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit watchOS/Pods-LeadKit-LeadKit watchOS.debug.xcconfig"; sourceTree = ""; }; EF2421392076D5BD00FA9BE6 /* NetworkServiceConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkServiceConfiguration.swift; sourceTree = ""; }; EFBE57CF1EC35EF20040E00A /* Array+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Extensions.swift"; sourceTree = ""; }; EFBE57DA1EC361620040E00A /* UIView+Layout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Layout.swift"; sourceTree = ""; }; + FAE7BAF0ADEBBEFA10959BD0 /* Pods-LeadKit-LeadKit iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit iOS.release.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit iOS/Pods-LeadKit-LeadKit iOS.release.xcconfig"; sourceTree = ""; }; + FC5D19C857C04F205661E12E /* Pods-LeadKit-LeadKit iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit iOS.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit iOS/Pods-LeadKit-LeadKit iOS.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -828,6 +848,7 @@ 785EDF7C220072B500985ED4 /* SwiftDate.framework in Frameworks */, 785EDF8322007DF900985ED4 /* TableKit.framework in Frameworks */, 785EDF8522007E5200985ED4 /* UIScrollView_InfiniteScroll.framework in Frameworks */, + A916FFFB6784C37DCD2217D1 /* Pods_LeadKit_LeadKit_iOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -836,6 +857,7 @@ buildActionMask = 2147483647; files = ( 67186B311EB248F100CFAFFB /* LeadKit.framework in Frameworks */, + F9D8CB4031C3AFFF70F4B040 /* Pods_LeadKit_iOSTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -848,6 +870,7 @@ 785EDFA1220081F200985ED4 /* RxCocoa.framework in Frameworks */, 785EDFA2220081F200985ED4 /* SwiftDate.framework in Frameworks */, 785EDFA3220081F200985ED4 /* RxSwift.framework in Frameworks */, + 5F9DF5361ADE4207C1032252 /* Pods_LeadKit_LeadKit_watchOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -861,6 +884,7 @@ 785EDFB52200833100985ED4 /* RxCocoa.framework in Frameworks */, 785EDFB32200833100985ED4 /* RxAlamofire.framework in Frameworks */, 785EDFB72200833100985ED4 /* SwiftDate.framework in Frameworks */, + 21A3B105772E876EA9F3B332 /* Pods_LeadKit_LeadKit_tvOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -869,6 +893,7 @@ buildActionMask = 2147483647; files = ( 6782BBA91EB31D5A0086E0B8 /* LeadKit.framework in Frameworks */, + 4098E82DE6429EF5B01B43D7 /* Pods_LeadKit_tvOSTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1941,6 +1966,24 @@ path = TableKitViewModel; sourceTree = ""; }; + 6C722B542BA0317A7613C034 /* Pods */ = { + isa = PBXGroup; + children = ( + A29A396D649FAF4088CA5294 /* Pods-LeadKit iOSTests.debug.xcconfig */, + 90DA5FD2982B6AB31C3E8336 /* Pods-LeadKit iOSTests.release.xcconfig */, + 3EB2AD073C7659E7B3AD592B /* Pods-LeadKit tvOSTests.debug.xcconfig */, + D4922783EEF858FE8CF8C482 /* Pods-LeadKit tvOSTests.release.xcconfig */, + FC5D19C857C04F205661E12E /* Pods-LeadKit-LeadKit iOS.debug.xcconfig */, + FAE7BAF0ADEBBEFA10959BD0 /* Pods-LeadKit-LeadKit iOS.release.xcconfig */, + CC02AE0FB1F711D5C498A8A6 /* Pods-LeadKit-LeadKit tvOS.debug.xcconfig */, + 2D48ED6E97C783C9AB880754 /* Pods-LeadKit-LeadKit tvOS.release.xcconfig */, + E53A1E9E9F77B0F30940382F /* Pods-LeadKit-LeadKit watchOS.debug.xcconfig */, + 1D98F1F1E572E6B0AFA5D6DD /* Pods-LeadKit-LeadKit watchOS.release.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 785EDF75220072B400985ED4 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -1964,6 +2007,11 @@ 785EDF77220072B400985ED4 /* RxCocoa.framework */, 785EDF7B220072B500985ED4 /* RxSwift.framework */, 785EDF76220072B400985ED4 /* SwiftDate.framework */, + 98DD36236D8020BB8F15D803 /* Pods_LeadKit_iOSTests.framework */, + 94DC826707A87C30CD4DB157 /* Pods_LeadKit_tvOSTests.framework */, + 5D75C8B2B1AE880554CF104E /* Pods_LeadKit_LeadKit_iOS.framework */, + 30DABA466214FE9ABDE2E685 /* Pods_LeadKit_LeadKit_tvOS.framework */, + 48C5033AB9D51F5BA39AAAFC /* Pods_LeadKit_LeadKit_watchOS.framework */, ); name = Frameworks; sourceTree = ""; @@ -1976,6 +2024,7 @@ 67186B401EB24A5B00CFAFFB /* Tests */, 67186B411EB24AA000CFAFFB /* iOS.playground */, 785EDF75220072B400985ED4 /* Frameworks */, + 6C722B542BA0317A7613C034 /* Pods */, ); sourceTree = ""; }; @@ -2121,6 +2170,7 @@ isa = PBXNativeTarget; buildConfigurationList = 67186B391EB248F100CFAFFB /* Build configuration list for PBXNativeTarget "LeadKit iOS" */; buildPhases = ( + 066F9DA5186FEE09FCF88E82 /* [CP] Check Pods Manifest.lock */, 67887A0E1ECC856F008A9E1D /* CopyPaste Detection */, 67186C2E1EB2538E00CFAFFB /* SwiftLint */, 67186B231EB248F100CFAFFB /* Sources */, @@ -2141,6 +2191,7 @@ isa = PBXNativeTarget; buildConfigurationList = 67186B3C1EB248F100CFAFFB /* Build configuration list for PBXNativeTarget "LeadKit iOSTests" */; buildPhases = ( + 130F0A09690A2CDBEE833A21 /* [CP] Check Pods Manifest.lock */, 67186B2C1EB248F100CFAFFB /* Sources */, 67186B2D1EB248F100CFAFFB /* Frameworks */, 67186B2E1EB248F100CFAFFB /* Resources */, @@ -2159,6 +2210,7 @@ isa = PBXNativeTarget; buildConfigurationList = 6782BB961EB31CFE0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit watchOS" */; buildPhases = ( + 7C7BE398A5318A1AE32A308D /* [CP] Check Pods Manifest.lock */, 67EB7FCC2061538D00BDD9FB /* CopyPaste Detection */, 6782BBBC1EB31ED90086E0B8 /* SwiftLint */, 6782BB8C1EB31CFE0086E0B8 /* Sources */, @@ -2179,6 +2231,7 @@ isa = PBXNativeTarget; buildConfigurationList = 6782BBB11EB31D5A0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit tvOS" */; buildPhases = ( + F0D1119D492F8291848EED52 /* [CP] Check Pods Manifest.lock */, 67EB7FCD2061539500BDD9FB /* CopyPaste Detection */, 6782BBBE1EB31F210086E0B8 /* SwiftLint */, 6782BB9B1EB31D590086E0B8 /* Sources */, @@ -2199,6 +2252,7 @@ isa = PBXNativeTarget; buildConfigurationList = 6782BBB41EB31D5A0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit tvOSTests" */; buildPhases = ( + 598FD5D7DDAF5E72DE945195 /* [CP] Check Pods Manifest.lock */, 6782BBA41EB31D5A0086E0B8 /* Sources */, 6782BBA51EB31D5A0086E0B8 /* Frameworks */, 6782BBA61EB31D5A0086E0B8 /* Resources */, @@ -2317,6 +2371,72 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 066F9DA5186FEE09FCF88E82 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-LeadKit-LeadKit iOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 130F0A09690A2CDBEE833A21 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-LeadKit iOSTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 598FD5D7DDAF5E72DE945195 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-LeadKit tvOSTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 67186C2E1EB2538E00CFAFFB /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 12; @@ -2401,6 +2521,50 @@ shellPath = /bin/sh; shellScript = ". build-scripts/xcode/build_phases/copy_paste_detection.sh Sources"; }; + 7C7BE398A5318A1AE32A308D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-LeadKit-LeadKit watchOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + F0D1119D492F8291848EED52 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-LeadKit-LeadKit tvOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -2971,6 +3135,7 @@ /* Begin XCBuildConfiguration section */ 67186B3A1EB248F100CFAFFB /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = FC5D19C857C04F205661E12E /* Pods-LeadKit-LeadKit iOS.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -3001,6 +3166,7 @@ }; 67186B3B1EB248F100CFAFFB /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = FAE7BAF0ADEBBEFA10959BD0 /* Pods-LeadKit-LeadKit iOS.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -3030,6 +3196,7 @@ }; 67186B3D1EB248F100CFAFFB /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = A29A396D649FAF4088CA5294 /* Pods-LeadKit iOSTests.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3049,6 +3216,7 @@ }; 67186B3E1EB248F100CFAFFB /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 90DA5FD2982B6AB31C3E8336 /* Pods-LeadKit iOSTests.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3066,6 +3234,7 @@ }; 6782BB971EB31CFE0086E0B8 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E53A1E9E9F77B0F30940382F /* Pods-LeadKit-LeadKit watchOS.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -3098,6 +3267,7 @@ }; 6782BB981EB31CFE0086E0B8 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 1D98F1F1E572E6B0AFA5D6DD /* Pods-LeadKit-LeadKit watchOS.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -3129,6 +3299,7 @@ }; 6782BBB21EB31D5A0086E0B8 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = CC02AE0FB1F711D5C498A8A6 /* Pods-LeadKit-LeadKit tvOS.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3160,6 +3331,7 @@ }; 6782BBB31EB31D5A0086E0B8 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 2D48ED6E97C783C9AB880754 /* Pods-LeadKit-LeadKit tvOS.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3190,6 +3362,7 @@ }; 6782BBB51EB31D5A0086E0B8 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 3EB2AD073C7659E7B3AD592B /* Pods-LeadKit tvOSTests.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3210,6 +3383,7 @@ }; 6782BBB61EB31D5A0086E0B8 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D4922783EEF858FE8CF8C482 /* Pods-LeadKit tvOSTests.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; diff --git a/LeadKit.xcodeproj/xcshareddata/xcschemes/LeadKit iOS Extensions.xcscheme b/LeadKit.xcodeproj/xcshareddata/xcschemes/LeadKit iOS Extensions.xcscheme deleted file mode 100644 index c4a9d46e..00000000 --- a/LeadKit.xcodeproj/xcshareddata/xcschemes/LeadKit iOS Extensions.xcscheme +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Podfile b/Podfile index 4c6162af..abe1ed18 100644 --- a/Podfile +++ b/Podfile @@ -22,20 +22,6 @@ abstract_target 'LeadKit' do end - target 'LeadKit iOS Extensions' do - platform :ios, '9.0' - - use_frameworks! - - pod "TableKit" - - target 'LeadKit iOS ExtensionsTests' do - inherit! :search_paths - # Pods for testing - end - - end - target 'LeadKit watchOS' do platform :watchos, '3.0' diff --git a/Podfile.lock b/Podfile.lock index b2f2e04e..3211090d 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -47,6 +47,6 @@ SPEC CHECKSUMS: TableKit: 18a0049dea981c1106409bdeebc763ef74d36f02 UIScrollView-InfiniteScroll: 3ef456bcbe759c19f510a383cff96e6647c98c98 -PODFILE CHECKSUM: abec65fc699c906f3429fd91a31217e4263a7e88 +PODFILE CHECKSUM: 35078953e1674fd44d276c008f8bdf5f910ea145 -COCOAPODS: 1.6.0.rc.1 +COCOAPODS: 1.6.1 From cb6d5c4232c79c31415a5a0f3f2305050893ee9f Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Wed, 13 Mar 2019 14:28:58 +0500 Subject: [PATCH 05/36] New closure typealiases --- LeadKit.xcodeproj/project.pbxproj | 17 ++++++++-------- .../{VoidBlock.swift => Block.swift} | 20 +++++++++++++++---- 2 files changed, 24 insertions(+), 13 deletions(-) rename Sources/Functions/{VoidBlock.swift => Block.swift} (60%) diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 55011f8b..96373ea4 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -205,9 +205,6 @@ 67153E43207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67153E3F207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift */; }; 67186B311EB248F100CFAFFB /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67186B281EB248F100CFAFFB /* LeadKit.framework */; }; 67186B3F1EB24A1900CFAFFB /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 67186B201EB247A200CFAFFB /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 671AD25C206A343300EAF887 /* VoidBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD25B206A343300EAF887 /* VoidBlock.swift */; }; - 671AD25E206A343300EAF887 /* VoidBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD25B206A343300EAF887 /* VoidBlock.swift */; }; - 671AD25F206A343300EAF887 /* VoidBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD25B206A343300EAF887 /* VoidBlock.swift */; }; 671AD26C206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; }; 671AD26E206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; }; 671AD26F206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; }; @@ -500,6 +497,9 @@ 78EC7B1522019F5A0007DCFD /* String+TelpromptURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78EC7B1222019F5A0007DCFD /* String+TelpromptURL.swift */; }; 820CAD8420B43B080033EF94 /* PaginationWrapperDelegate+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820CAD8320B43B080033EF94 /* PaginationWrapperDelegate+DefaultImplementation.swift */; }; 825F8F2820B3384C00594857 /* PaginationWrapperUIDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825F8F2720B3384C00594857 /* PaginationWrapperUIDelegate.swift */; }; + 82B4F8DB223903B800F6708C /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B4F8DA223903B800F6708C /* Block.swift */; }; + 82B4F8DC223903B800F6708C /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B4F8DA223903B800F6708C /* Block.swift */; }; + 82B4F8DD223903B800F6708C /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B4F8DA223903B800F6708C /* Block.swift */; }; 82F8BB181F5DDED100C1061B /* Single+DeferredJust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F8BB171F5DDED100C1061B /* Single+DeferredJust.swift */; }; A658E54D1F8CD7790093527A /* TableRow+SeparatorsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A658E54C1F8CD7790093527A /* TableRow+SeparatorsExtensions.swift */; }; A658E5501F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A658E54F1F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift */; }; @@ -658,7 +658,6 @@ 67186B301EB248F100CFAFFB /* LeadKit iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LeadKit iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 67186B411EB24AA000CFAFFB /* iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = iOS.playground; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 67186C1A1EB24B7800CFAFFB /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; - 671AD25B206A343300EAF887 /* VoidBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoidBlock.swift; sourceTree = ""; }; 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+TotalCountCursorListingResult.swift"; sourceTree = ""; }; 67274768206CCC9D00725163 /* ViewBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewBackground.swift; sourceTree = ""; }; 6727476D206CCDDB00725163 /* ViewBackground+Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewBackground+Configuration.swift"; sourceTree = ""; }; @@ -800,6 +799,7 @@ 78EC7B1222019F5A0007DCFD /* String+TelpromptURL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+TelpromptURL.swift"; sourceTree = ""; }; 820CAD8320B43B080033EF94 /* PaginationWrapperDelegate+DefaultImplementation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PaginationWrapperDelegate+DefaultImplementation.swift"; sourceTree = ""; }; 825F8F2720B3384C00594857 /* PaginationWrapperUIDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationWrapperUIDelegate.swift; sourceTree = ""; }; + 82B4F8DA223903B800F6708C /* Block.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Block.swift; sourceTree = ""; }; 82F8BB171F5DDED100C1061B /* Single+DeferredJust.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Single+DeferredJust.swift"; sourceTree = ""; }; 90DA5FD2982B6AB31C3E8336 /* Pods-LeadKit iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit iOSTests.release.xcconfig"; path = "Target Support Files/Pods-LeadKit iOSTests/Pods-LeadKit iOSTests.release.xcconfig"; sourceTree = ""; }; 94DC826707A87C30CD4DB157 /* Pods_LeadKit_tvOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_tvOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1173,7 +1173,7 @@ A676AE4C1F9810C1001F9214 /* Any+Cast.swift */, 671462211EB3396E00EAB194 /* Any+TypeName.swift */, 67FD4381206BD24B005B0C64 /* EqutableOptionalArray.swift */, - 671AD25B206A343300EAF887 /* VoidBlock.swift */, + 82B4F8DA223903B800F6708C /* Block.swift */, ); path = Functions; sourceTree = ""; @@ -1980,7 +1980,6 @@ E53A1E9E9F77B0F30940382F /* Pods-LeadKit-LeadKit watchOS.debug.xcconfig */, 1D98F1F1E572E6B0AFA5D6DD /* Pods-LeadKit-LeadKit watchOS.release.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -2641,7 +2640,6 @@ A6D10EAB1F8A9278003E69DD /* Comparable+Extensions.swift in Sources */, 671463801EB3396E00EAB194 /* PaddingDrawingOperation.swift in Sources */, 671463281EB3396E00EAB194 /* BaseViewModel.swift in Sources */, - 671AD25C206A343300EAF887 /* VoidBlock.swift in Sources */, A6E0DDDF1F8A696F002CA74E /* SeparatorCell.swift in Sources */, 67153E40207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift in Sources */, 671462AC1EB3396E00EAB194 /* Observable+DeferredJust.swift in Sources */, @@ -2767,6 +2765,7 @@ 673CF4342063E29B00C329F6 /* TextWithButtonPlaceholder.swift in Sources */, 673CF4222063D90600C329F6 /* DisposeBagHolder.swift in Sources */, 67DB776D210871E8001CB56B /* BaseCollectionContentController.swift in Sources */, + 82B4F8DB223903B800F6708C /* Block.swift in Sources */, 671463681EB3396E00EAB194 /* ConfigurableView.swift in Sources */, 6B5B64BACFF8C5487FB0939D /* TableKitViewModel.swift in Sources */, 6B5B6F0BFA22832C47142BAD /* TableKitViewModel+Extenstions.swift in Sources */, @@ -2812,6 +2811,7 @@ 67274781206CD3BD00725163 /* ViewText+Extensions.swift in Sources */, 6713C23920AF0C4D00875921 /* NetworkOperationState.swift in Sources */, 671463561EB3396E00EAB194 /* StaticViewHeightProtocol.swift in Sources */, + 82B4F8DC223903B800F6708C /* Block.swift in Sources */, 671463621EB3396E00EAB194 /* SupportProtocol.swift in Sources */, 678D26A220692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */, 671462861EB3396E00EAB194 /* CGContext+Initializers.swift in Sources */, @@ -2907,7 +2907,6 @@ 6714638E1EB3396E00EAB194 /* SolidFillDrawingOperation.swift in Sources */, 6774529420625D170024EEEF /* GeneralDataLoadingModel.swift in Sources */, 67FDC2611FA310EA00C76A77 /* RequestError.swift in Sources */, - 671AD25E206A343300EAF887 /* VoidBlock.swift in Sources */, 671462521EB3396E00EAB194 /* StaticCursor.swift in Sources */, 67ED2BE720B44F4300508B3E /* InitializableView+DefaultImplementation.swift in Sources */, 6714629E1EB3396E00EAB194 /* CursorType+Slice.swift in Sources */, @@ -2922,6 +2921,7 @@ buildActionMask = 2147483647; files = ( 6714634B1EB3396E00EAB194 /* ResettableType.swift in Sources */, + 82B4F8DD223903B800F6708C /* Block.swift in Sources */, 671462E71EB3396E00EAB194 /* UIColor+Hex.swift in Sources */, 67ED2BE120B44DEB00508B3E /* InitializableView.swift in Sources */, 67990AD9213EA6A50040D195 /* ContentLoadingViewModel+Extensions.swift in Sources */, @@ -3011,7 +3011,6 @@ B84CB07B20B872AD0090DB91 /* Decodable+Extensions.swift in Sources */, 671463731EB3396E00EAB194 /* ApiRequestParameters.swift in Sources */, 671462EF1EB3396E00EAB194 /* UIImage+Extensions.swift in Sources */, - 671AD25F206A343300EAF887 /* VoidBlock.swift in Sources */, 6774526A206249360024EEEF /* UITableView+PaginationWrappable.swift in Sources */, 6714636F1EB3396E00EAB194 /* XibNameProtocol.swift in Sources */, EFBE57DE1EC361620040E00A /* UIView+Layout.swift in Sources */, diff --git a/Sources/Functions/VoidBlock.swift b/Sources/Functions/Block.swift similarity index 60% rename from Sources/Functions/VoidBlock.swift rename to Sources/Functions/Block.swift index e7cf2f7c..b1b619cd 100644 --- a/Sources/Functions/VoidBlock.swift +++ b/Sources/Functions/Block.swift @@ -20,8 +20,20 @@ // THE SOFTWARE. // -/// Closure that takes no arguments and return Void. -public typealias VoidBlock = () -> Void +/// Closure with custom arguments and return value. +public typealias Block = (Input) -> Output -/// Closure that takes no arguments, may throw error and return Void. -public typealias ThrowableVoidBlock = () throws -> Void +/// Closure with no arguments and custom return value. +public typealias ResultBlock = Block + +/// Closure that takes custom arguments and returns Void. +public typealias ParameterBlock = Block + +/// Closure that takes no arguments and returns Void. +public typealias VoidBlock = ResultBlock + +/// Closure with custom arguments and return value, may throw an error. +public typealias ThrowableBlock = (Input) throws -> Output + +/// Closure that takes no arguments, may throw an error and returns Void. +public typealias ThrowableVoidBlock = ThrowableBlock From f2519ad3fc48a4b49ed257c8eb91b36a04be9107 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Wed, 13 Mar 2019 14:54:25 +0500 Subject: [PATCH 06/36] Changelog update --- CHANGELOG.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 240e0cf2..98994868 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### 0.9.10 +- **Remove**: Removed unused scheme & target +- **Update**: New closure typealiases + ### 0.9.9 - **Add**: `validStatusCodes` parameter to request methods in `NetworkService` class, that expands valid status codes for request. - **Add**: `validStatusCodes` parameter to response methods in `SessionManager` extension, that expands valid status codes for request. @@ -41,7 +45,7 @@ ### 0.8.13 - **Add**: `configureLayout` method to `InitializeableView` protocol and all implementations. - **Update**: `GeneralDataLoadingViewModel` now can handle state changes and result of data source. Previously it was possible only in view controller. -- **Add**: `GeneralDataLoadingHandler` protocol, that defines methods for common data loading states handling. +- **Add**: `GeneralDataLoadingHandler` protocol, that defines methods for common data loading states handling. - **Add**: `resultObservable` and `resultDriver` properties to `GeneralDataLoadingViewModel`. - **Add**: `hidesWhenStopped` option to `SpinnerView`, so you can stop animation without hiding image inside it. - **Update**: Migrate to Swift 4.2 & Xcode 10. Update dependencies. @@ -92,12 +96,12 @@ ### 0.8.5 -- **Add**: `replaceDataSource` method to `RxNetworkOperationModel`. +- **Add**: `replaceDataSource` method to `RxNetworkOperationModel`. - **Add**: `customErrorHandler` constructor parameter to `RxNetworkOperationModel` and it heirs. ### 0.8.4 -- **Fix**: Add `SeparatorCell` to `Core-iOS-Extension`. +- **Fix**: Add `SeparatorCell` to `Core-iOS-Extension`. - **Fix**: `UIApplication` extensions path for `Core-iOS-Extension` exclusions. ### 0.8.3 From f6b39ddcf7fe09e34cd685b693e25c5400f3bcaf Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Wed, 13 Mar 2019 14:58:17 +0500 Subject: [PATCH 07/36] Plist updates --- LeadKit.xcodeproj/project.pbxproj | 2 -- Sources/Info-iOS-Extensions.plist | 24 ------------------------ Sources/Info-iOS.plist | 2 +- Sources/Info-tvOS.plist | 2 +- Sources/Info-watchOS.plist | 2 +- 5 files changed, 3 insertions(+), 29 deletions(-) delete mode 100644 Sources/Info-iOS-Extensions.plist diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 96373ea4..1c9e0f63 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -729,7 +729,6 @@ 67952C391EB3203F00B3BA1A /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; 67952C3A1EB3205D00B3BA1A /* Info-watchOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-watchOS.plist"; sourceTree = ""; }; 67952C3B1EB3208000B3BA1A /* Info-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; - 67952DDC1EB3280900B3BA1A /* Info-iOS-Extensions.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS-Extensions.plist"; sourceTree = ""; }; 67952DDE1EB3285A00B3BA1A /* Info-iOS-Extensions.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS-Extensions.plist"; sourceTree = ""; }; 67955D51206D216B0021ECD2 /* Singleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Singleton.swift; sourceTree = ""; }; 67990AC4213EA4DB0040D195 /* PlaceholderConfigurable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderConfigurable.swift; sourceTree = ""; }; @@ -1294,7 +1293,6 @@ 671461D61EB3396E00EAB194 /* Enums */, 671461DA1EB3396E00EAB194 /* Extensions */, 6714621F1EB3396E00EAB194 /* Functions */, - 67952DDC1EB3280900B3BA1A /* Info-iOS-Extensions.plist */, 67952C391EB3203F00B3BA1A /* Info-iOS.plist */, 67952C3B1EB3208000B3BA1A /* Info-tvOS.plist */, 67952C3A1EB3205D00B3BA1A /* Info-watchOS.plist */, diff --git a/Sources/Info-iOS-Extensions.plist b/Sources/Info-iOS-Extensions.plist deleted file mode 100644 index 399882e1..00000000 --- a/Sources/Info-iOS-Extensions.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 0.5.0 - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/Sources/Info-iOS.plist b/Sources/Info-iOS.plist index dd711d9f..4675ccda 100644 --- a/Sources/Info-iOS.plist +++ b/Sources/Info-iOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.9 + 0.9.10 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist index dd711d9f..4675ccda 100644 --- a/Sources/Info-tvOS.plist +++ b/Sources/Info-tvOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.9 + 0.9.10 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist index dd711d9f..4675ccda 100644 --- a/Sources/Info-watchOS.plist +++ b/Sources/Info-watchOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.9 + 0.9.10 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass From 192a30bfa6605cf92b6c1eb10ccaeb5c317c6609 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Wed, 13 Mar 2019 21:28:42 +0500 Subject: [PATCH 08/36] Throwable block fix --- Sources/Functions/Block.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Functions/Block.swift b/Sources/Functions/Block.swift index b1b619cd..06d3620e 100644 --- a/Sources/Functions/Block.swift +++ b/Sources/Functions/Block.swift @@ -36,4 +36,4 @@ public typealias VoidBlock = ResultBlock public typealias ThrowableBlock = (Input) throws -> Output /// Closure that takes no arguments, may throw an error and returns Void. -public typealias ThrowableVoidBlock = ThrowableBlock +public typealias ThrowableVoidBlock = () throws -> Void From 512f8542962fce3962661c9317bd8dabb2630c17 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Wed, 13 Mar 2019 21:28:53 +0500 Subject: [PATCH 09/36] Pods deintegrated --- LeadKit.xcodeproj/project.pbxproj | 165 ------------------------------ 1 file changed, 165 deletions(-) diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 1c9e0f63..66fab7b7 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -7,16 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 21A3B105772E876EA9F3B332 /* Pods_LeadKit_LeadKit_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30DABA466214FE9ABDE2E685 /* Pods_LeadKit_LeadKit_tvOS.framework */; }; 36977763200CF12100ED9C6E /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36DAAF502007CC920090BE0D /* UITableView+Extensions.swift */; }; 36DAAF512007CC920090BE0D /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36DAAF502007CC920090BE0D /* UITableView+Extensions.swift */; }; 36FE777020F669E300284C09 /* String+ConvertToHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */; }; 36FE777220F669E300284C09 /* String+ConvertToHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */; }; 36FE777320F669E300284C09 /* String+ConvertToHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */; }; - 4098E82DE6429EF5B01B43D7 /* Pods_LeadKit_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94DC826707A87C30CD4DB157 /* Pods_LeadKit_tvOSTests.framework */; }; 40F118471F8FEF97004AADAF /* AppearanceConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */; }; 40F118491F8FF223004AADAF /* TableRow+AppearanceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118481F8FF223004AADAF /* TableRow+AppearanceExtension.swift */; }; - 5F9DF5361ADE4207C1032252 /* Pods_LeadKit_LeadKit_watchOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48C5033AB9D51F5BA39AAAFC /* Pods_LeadKit_LeadKit_watchOS.framework */; }; 67051ADB1EBC7C36008EADC0 /* SpinnerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67051ADA1EBC7C36008EADC0 /* SpinnerView.swift */; }; 67051ADD1EBC7C36008EADC0 /* SpinnerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67051ADA1EBC7C36008EADC0 /* SpinnerView.swift */; }; 6713C23720AF0C4D00875921 /* NetworkOperationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6713C23620AF0C4D00875921 /* NetworkOperationState.swift */; }; @@ -525,7 +522,6 @@ A6F32C0C1F6EBE5C00AC08EE /* String+LocalizedComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C071F6EBDAA00AC08EE /* String+LocalizedComponent.swift */; }; A6F32C101F6EBE9600AC08EE /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C0E1F6EBE8E00AC08EE /* StringExtensionTests.swift */; }; A6F32C121F6EBE9800AC08EE /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C0E1F6EBE8E00AC08EE /* StringExtensionTests.swift */; }; - A916FFFB6784C37DCD2217D1 /* Pods_LeadKit_LeadKit_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D75C8B2B1AE880554CF104E /* Pods_LeadKit_LeadKit_iOS.framework */; }; B84CB06A20B702240090DB91 /* Encodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */; }; B84CB06B20B702260090DB91 /* Encodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */; }; B84CB06D20B8325D0090DB91 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB06C20B8325D0090DB91 /* SessionManager.swift */; }; @@ -551,7 +547,6 @@ EFBE57D31EC35EF20040E00A /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57CF1EC35EF20040E00A /* Array+Extensions.swift */; }; EFBE57DB1EC361620040E00A /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57DA1EC361620040E00A /* UIView+Layout.swift */; }; EFBE57DE1EC361620040E00A /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57DA1EC361620040E00A /* UIView+Layout.swift */; }; - F9D8CB4031C3AFFF70F4B040 /* Pods_LeadKit_iOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98DD36236D8020BB8F15D803 /* Pods_LeadKit_iOSTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -572,16 +567,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 1D98F1F1E572E6B0AFA5D6DD /* Pods-LeadKit-LeadKit watchOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit watchOS.release.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit watchOS/Pods-LeadKit-LeadKit watchOS.release.xcconfig"; sourceTree = ""; }; - 2D48ED6E97C783C9AB880754 /* Pods-LeadKit-LeadKit tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit tvOS.release.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit tvOS/Pods-LeadKit-LeadKit tvOS.release.xcconfig"; sourceTree = ""; }; - 30DABA466214FE9ABDE2E685 /* Pods_LeadKit_LeadKit_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_LeadKit_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 36DAAF502007CC920090BE0D /* UITableView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+Extensions.swift"; sourceTree = ""; }; 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ConvertToHost.swift"; sourceTree = ""; }; - 3EB2AD073C7659E7B3AD592B /* Pods-LeadKit tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit tvOSTests/Pods-LeadKit tvOSTests.debug.xcconfig"; sourceTree = ""; }; 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceConfigurable.swift; sourceTree = ""; }; 40F118481F8FF223004AADAF /* TableRow+AppearanceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TableRow+AppearanceExtension.swift"; sourceTree = ""; }; - 48C5033AB9D51F5BA39AAAFC /* Pods_LeadKit_LeadKit_watchOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_LeadKit_watchOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5D75C8B2B1AE880554CF104E /* Pods_LeadKit_LeadKit_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_LeadKit_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 67051ADA1EBC7C36008EADC0 /* SpinnerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinnerView.swift; sourceTree = ""; }; 6713C23620AF0C4D00875921 /* NetworkOperationState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkOperationState.swift; sourceTree = ""; }; 6713C23B20AF0D5900875921 /* NetworkOperationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkOperationModel.swift; sourceTree = ""; }; @@ -800,10 +789,6 @@ 825F8F2720B3384C00594857 /* PaginationWrapperUIDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationWrapperUIDelegate.swift; sourceTree = ""; }; 82B4F8DA223903B800F6708C /* Block.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Block.swift; sourceTree = ""; }; 82F8BB171F5DDED100C1061B /* Single+DeferredJust.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Single+DeferredJust.swift"; sourceTree = ""; }; - 90DA5FD2982B6AB31C3E8336 /* Pods-LeadKit iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit iOSTests.release.xcconfig"; path = "Target Support Files/Pods-LeadKit iOSTests/Pods-LeadKit iOSTests.release.xcconfig"; sourceTree = ""; }; - 94DC826707A87C30CD4DB157 /* Pods_LeadKit_tvOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_tvOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 98DD36236D8020BB8F15D803 /* Pods_LeadKit_iOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_iOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A29A396D649FAF4088CA5294 /* Pods-LeadKit iOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit iOSTests.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit iOSTests/Pods-LeadKit iOSTests.debug.xcconfig"; sourceTree = ""; }; A658E54C1F8CD7790093527A /* TableRow+SeparatorsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TableRow+SeparatorsExtensions.swift"; sourceTree = ""; }; A658E54F1F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+SeparatorRowBoxExtensions.swift"; sourceTree = ""; }; A66428A61F8A653600C6308D /* SeparatorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorCell.swift; sourceTree = ""; }; @@ -823,15 +808,10 @@ B85B766620AC4EA300F837C4 /* Album.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Album.swift; sourceTree = ""; }; B85B766B20AC51BE00F837C4 /* AlbumsContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumsContainer.swift; sourceTree = ""; }; B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Encodable+Extensions.swift"; sourceTree = ""; }; - CC02AE0FB1F711D5C498A8A6 /* Pods-LeadKit-LeadKit tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit tvOS.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit tvOS/Pods-LeadKit-LeadKit tvOS.debug.xcconfig"; sourceTree = ""; }; - D4922783EEF858FE8CF8C482 /* Pods-LeadKit tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-LeadKit tvOSTests/Pods-LeadKit tvOSTests.release.xcconfig"; sourceTree = ""; }; D93221ED20A44896003799D5 /* Double+RoundingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+RoundingTests.swift"; sourceTree = ""; }; - E53A1E9E9F77B0F30940382F /* Pods-LeadKit-LeadKit watchOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit watchOS.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit watchOS/Pods-LeadKit-LeadKit watchOS.debug.xcconfig"; sourceTree = ""; }; EF2421392076D5BD00FA9BE6 /* NetworkServiceConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkServiceConfiguration.swift; sourceTree = ""; }; EFBE57CF1EC35EF20040E00A /* Array+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Extensions.swift"; sourceTree = ""; }; EFBE57DA1EC361620040E00A /* UIView+Layout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Layout.swift"; sourceTree = ""; }; - FAE7BAF0ADEBBEFA10959BD0 /* Pods-LeadKit-LeadKit iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit iOS.release.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit iOS/Pods-LeadKit-LeadKit iOS.release.xcconfig"; sourceTree = ""; }; - FC5D19C857C04F205661E12E /* Pods-LeadKit-LeadKit iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit iOS.debug.xcconfig"; path = "Target Support Files/Pods-LeadKit-LeadKit iOS/Pods-LeadKit-LeadKit iOS.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -847,7 +827,6 @@ 785EDF7C220072B500985ED4 /* SwiftDate.framework in Frameworks */, 785EDF8322007DF900985ED4 /* TableKit.framework in Frameworks */, 785EDF8522007E5200985ED4 /* UIScrollView_InfiniteScroll.framework in Frameworks */, - A916FFFB6784C37DCD2217D1 /* Pods_LeadKit_LeadKit_iOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -856,7 +835,6 @@ buildActionMask = 2147483647; files = ( 67186B311EB248F100CFAFFB /* LeadKit.framework in Frameworks */, - F9D8CB4031C3AFFF70F4B040 /* Pods_LeadKit_iOSTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -869,7 +847,6 @@ 785EDFA1220081F200985ED4 /* RxCocoa.framework in Frameworks */, 785EDFA2220081F200985ED4 /* SwiftDate.framework in Frameworks */, 785EDFA3220081F200985ED4 /* RxSwift.framework in Frameworks */, - 5F9DF5361ADE4207C1032252 /* Pods_LeadKit_LeadKit_watchOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -883,7 +860,6 @@ 785EDFB52200833100985ED4 /* RxCocoa.framework in Frameworks */, 785EDFB32200833100985ED4 /* RxAlamofire.framework in Frameworks */, 785EDFB72200833100985ED4 /* SwiftDate.framework in Frameworks */, - 21A3B105772E876EA9F3B332 /* Pods_LeadKit_LeadKit_tvOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -892,7 +868,6 @@ buildActionMask = 2147483647; files = ( 6782BBA91EB31D5A0086E0B8 /* LeadKit.framework in Frameworks */, - 4098E82DE6429EF5B01B43D7 /* Pods_LeadKit_tvOSTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1967,16 +1942,6 @@ 6C722B542BA0317A7613C034 /* Pods */ = { isa = PBXGroup; children = ( - A29A396D649FAF4088CA5294 /* Pods-LeadKit iOSTests.debug.xcconfig */, - 90DA5FD2982B6AB31C3E8336 /* Pods-LeadKit iOSTests.release.xcconfig */, - 3EB2AD073C7659E7B3AD592B /* Pods-LeadKit tvOSTests.debug.xcconfig */, - D4922783EEF858FE8CF8C482 /* Pods-LeadKit tvOSTests.release.xcconfig */, - FC5D19C857C04F205661E12E /* Pods-LeadKit-LeadKit iOS.debug.xcconfig */, - FAE7BAF0ADEBBEFA10959BD0 /* Pods-LeadKit-LeadKit iOS.release.xcconfig */, - CC02AE0FB1F711D5C498A8A6 /* Pods-LeadKit-LeadKit tvOS.debug.xcconfig */, - 2D48ED6E97C783C9AB880754 /* Pods-LeadKit-LeadKit tvOS.release.xcconfig */, - E53A1E9E9F77B0F30940382F /* Pods-LeadKit-LeadKit watchOS.debug.xcconfig */, - 1D98F1F1E572E6B0AFA5D6DD /* Pods-LeadKit-LeadKit watchOS.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -2004,11 +1969,6 @@ 785EDF77220072B400985ED4 /* RxCocoa.framework */, 785EDF7B220072B500985ED4 /* RxSwift.framework */, 785EDF76220072B400985ED4 /* SwiftDate.framework */, - 98DD36236D8020BB8F15D803 /* Pods_LeadKit_iOSTests.framework */, - 94DC826707A87C30CD4DB157 /* Pods_LeadKit_tvOSTests.framework */, - 5D75C8B2B1AE880554CF104E /* Pods_LeadKit_LeadKit_iOS.framework */, - 30DABA466214FE9ABDE2E685 /* Pods_LeadKit_LeadKit_tvOS.framework */, - 48C5033AB9D51F5BA39AAAFC /* Pods_LeadKit_LeadKit_watchOS.framework */, ); name = Frameworks; sourceTree = ""; @@ -2167,7 +2127,6 @@ isa = PBXNativeTarget; buildConfigurationList = 67186B391EB248F100CFAFFB /* Build configuration list for PBXNativeTarget "LeadKit iOS" */; buildPhases = ( - 066F9DA5186FEE09FCF88E82 /* [CP] Check Pods Manifest.lock */, 67887A0E1ECC856F008A9E1D /* CopyPaste Detection */, 67186C2E1EB2538E00CFAFFB /* SwiftLint */, 67186B231EB248F100CFAFFB /* Sources */, @@ -2188,7 +2147,6 @@ isa = PBXNativeTarget; buildConfigurationList = 67186B3C1EB248F100CFAFFB /* Build configuration list for PBXNativeTarget "LeadKit iOSTests" */; buildPhases = ( - 130F0A09690A2CDBEE833A21 /* [CP] Check Pods Manifest.lock */, 67186B2C1EB248F100CFAFFB /* Sources */, 67186B2D1EB248F100CFAFFB /* Frameworks */, 67186B2E1EB248F100CFAFFB /* Resources */, @@ -2207,7 +2165,6 @@ isa = PBXNativeTarget; buildConfigurationList = 6782BB961EB31CFE0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit watchOS" */; buildPhases = ( - 7C7BE398A5318A1AE32A308D /* [CP] Check Pods Manifest.lock */, 67EB7FCC2061538D00BDD9FB /* CopyPaste Detection */, 6782BBBC1EB31ED90086E0B8 /* SwiftLint */, 6782BB8C1EB31CFE0086E0B8 /* Sources */, @@ -2228,7 +2185,6 @@ isa = PBXNativeTarget; buildConfigurationList = 6782BBB11EB31D5A0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit tvOS" */; buildPhases = ( - F0D1119D492F8291848EED52 /* [CP] Check Pods Manifest.lock */, 67EB7FCD2061539500BDD9FB /* CopyPaste Detection */, 6782BBBE1EB31F210086E0B8 /* SwiftLint */, 6782BB9B1EB31D590086E0B8 /* Sources */, @@ -2249,7 +2205,6 @@ isa = PBXNativeTarget; buildConfigurationList = 6782BBB41EB31D5A0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit tvOSTests" */; buildPhases = ( - 598FD5D7DDAF5E72DE945195 /* [CP] Check Pods Manifest.lock */, 6782BBA41EB31D5A0086E0B8 /* Sources */, 6782BBA51EB31D5A0086E0B8 /* Frameworks */, 6782BBA61EB31D5A0086E0B8 /* Resources */, @@ -2368,72 +2323,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 066F9DA5186FEE09FCF88E82 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-LeadKit-LeadKit iOS-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 130F0A09690A2CDBEE833A21 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-LeadKit iOSTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 598FD5D7DDAF5E72DE945195 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-LeadKit tvOSTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; 67186C2E1EB2538E00CFAFFB /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 12; @@ -2518,50 +2407,6 @@ shellPath = /bin/sh; shellScript = ". build-scripts/xcode/build_phases/copy_paste_detection.sh Sources"; }; - 7C7BE398A5318A1AE32A308D /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-LeadKit-LeadKit watchOS-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - F0D1119D492F8291848EED52 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-LeadKit-LeadKit tvOS-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -3132,7 +2977,6 @@ /* Begin XCBuildConfiguration section */ 67186B3A1EB248F100CFAFFB /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FC5D19C857C04F205661E12E /* Pods-LeadKit-LeadKit iOS.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -3163,7 +3007,6 @@ }; 67186B3B1EB248F100CFAFFB /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FAE7BAF0ADEBBEFA10959BD0 /* Pods-LeadKit-LeadKit iOS.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -3193,7 +3036,6 @@ }; 67186B3D1EB248F100CFAFFB /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A29A396D649FAF4088CA5294 /* Pods-LeadKit iOSTests.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3213,7 +3055,6 @@ }; 67186B3E1EB248F100CFAFFB /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 90DA5FD2982B6AB31C3E8336 /* Pods-LeadKit iOSTests.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3231,7 +3072,6 @@ }; 6782BB971EB31CFE0086E0B8 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E53A1E9E9F77B0F30940382F /* Pods-LeadKit-LeadKit watchOS.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -3264,7 +3104,6 @@ }; 6782BB981EB31CFE0086E0B8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1D98F1F1E572E6B0AFA5D6DD /* Pods-LeadKit-LeadKit watchOS.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -3296,7 +3135,6 @@ }; 6782BBB21EB31D5A0086E0B8 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CC02AE0FB1F711D5C498A8A6 /* Pods-LeadKit-LeadKit tvOS.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3328,7 +3166,6 @@ }; 6782BBB31EB31D5A0086E0B8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2D48ED6E97C783C9AB880754 /* Pods-LeadKit-LeadKit tvOS.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3359,7 +3196,6 @@ }; 6782BBB51EB31D5A0086E0B8 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3EB2AD073C7659E7B3AD592B /* Pods-LeadKit tvOSTests.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3380,7 +3216,6 @@ }; 6782BBB61EB31D5A0086E0B8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D4922783EEF858FE8CF8C482 /* Pods-LeadKit tvOSTests.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; From c71626ba923099d6a7d8571175b4c8a84ab2579d Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Wed, 13 Mar 2019 21:30:08 +0500 Subject: [PATCH 10/36] Changelog update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98994868..a0fa931f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### 0.9.10 - **Remove**: Removed unused scheme & target +- **Remove**: Cocoapods deintegrated - **Update**: New closure typealiases ### 0.9.9 From e9eac22a3bfb26478c95f6f43fd9f9ec9eef5b2d Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Wed, 13 Mar 2019 21:33:08 +0500 Subject: [PATCH 11/36] Cocoapods removed --- LeadKit.xcodeproj/project.pbxproj | 8 ----- Podfile | 47 ---------------------------- Podfile.lock | 52 ------------------------------- 3 files changed, 107 deletions(-) delete mode 100644 Podfile delete mode 100644 Podfile.lock diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 66fab7b7..96f56f7f 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -1939,13 +1939,6 @@ path = TableKitViewModel; sourceTree = ""; }; - 6C722B542BA0317A7613C034 /* Pods */ = { - isa = PBXGroup; - children = ( - ); - path = Pods; - sourceTree = ""; - }; 785EDF75220072B400985ED4 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -1981,7 +1974,6 @@ 67186B401EB24A5B00CFAFFB /* Tests */, 67186B411EB24AA000CFAFFB /* iOS.playground */, 785EDF75220072B400985ED4 /* Frameworks */, - 6C722B542BA0317A7613C034 /* Pods */, ); sourceTree = ""; }; diff --git a/Podfile b/Podfile deleted file mode 100644 index abe1ed18..00000000 --- a/Podfile +++ /dev/null @@ -1,47 +0,0 @@ -abstract_target 'LeadKit' do - pod "RxSwift" - pod "RxCocoa" - pod "RxAlamofire" - pod "SwiftLint" - pod "SwiftDate" - - inhibit_all_warnings! - - target 'LeadKit iOS' do - platform :ios, '9.0' - - use_frameworks! - - pod "TableKit" - pod "UIScrollView-InfiniteScroll" - - target 'LeadKit iOSTests' do - inherit! :search_paths - # Pods for testing - end - - end - - target 'LeadKit watchOS' do - platform :watchos, '3.0' - - use_frameworks! - - end - - target 'LeadKit tvOS' do - platform :tvos, '9.0' - - use_frameworks! - - target 'LeadKit tvOSTests' do - inherit! :search_paths - # Pods for testing - end - - end - -end - -# If you have slow HDD -ENV['COCOAPODS_DISABLE_STATS'] = "true" diff --git a/Podfile.lock b/Podfile.lock deleted file mode 100644 index 3211090d..00000000 --- a/Podfile.lock +++ /dev/null @@ -1,52 +0,0 @@ -PODS: - - Alamofire (4.8.1) - - RxAlamofire (4.3.0): - - RxAlamofire/Core (= 4.3.0) - - RxAlamofire/Core (4.3.0): - - Alamofire (~> 4.5) - - RxSwift (~> 4) - - RxAtomic (4.4.0) - - RxCocoa (4.4.0): - - RxSwift (~> 4.0) - - RxSwift (4.4.0): - - RxAtomic (~> 4.4) - - SwiftDate (5.1.0) - - SwiftLint (0.30.1) - - TableKit (2.8.1) - - UIScrollView-InfiniteScroll (1.1.0) - -DEPENDENCIES: - - RxAlamofire - - RxCocoa - - RxSwift - - SwiftDate - - SwiftLint - - TableKit - - UIScrollView-InfiniteScroll - -SPEC REPOS: - https://github.com/cocoapods/specs.git: - - Alamofire - - RxAlamofire - - RxAtomic - - RxCocoa - - RxSwift - - SwiftDate - - SwiftLint - - TableKit - - UIScrollView-InfiniteScroll - -SPEC CHECKSUMS: - Alamofire: 16ce2c353fb72865124ddae8a57c5942388f4f11 - RxAlamofire: 09624d0f2d48ed8b686e4eb4cf68e28cbd2df556 - RxAtomic: eacf60db868c96bfd63320e28619fe29c179656f - RxCocoa: df63ebf7b9a70d6b4eeea407ed5dd4efc8979749 - RxSwift: 5976ecd04fc2fefd648827c23de5e11157faa973 - SwiftDate: 6329e58969a2de31cea7f1ee1143b247693196e7 - SwiftLint: a54bf1fe12b55c68560eb2a7689dfc81458508f7 - TableKit: 18a0049dea981c1106409bdeebc763ef74d36f02 - UIScrollView-InfiniteScroll: 3ef456bcbe759c19f510a383cff96e6647c98c98 - -PODFILE CHECKSUM: 35078953e1674fd44d276c008f8bdf5f910ea145 - -COCOAPODS: 1.6.1 From c529ae736e9e834dd23bcfd8a108dd2a4d2d3f20 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Thu, 14 Mar 2019 00:38:30 +0500 Subject: [PATCH 12/36] Podspec version update --- LeadKit.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LeadKit.podspec b/LeadKit.podspec index 935c3e96..79a14220 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.9.9" + s.version = "0.9.10" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" From 1b6d77f34c8013c5003b29294f02fc3d4658a31a Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Sun, 17 Mar 2019 13:57:31 +0500 Subject: [PATCH 13/36] Blocks fix --- Sources/Functions/Block.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Sources/Functions/Block.swift b/Sources/Functions/Block.swift index 06d3620e..e8a89711 100644 --- a/Sources/Functions/Block.swift +++ b/Sources/Functions/Block.swift @@ -23,14 +23,11 @@ /// Closure with custom arguments and return value. public typealias Block = (Input) -> Output -/// Closure with no arguments and custom return value. -public typealias ResultBlock = Block - /// Closure that takes custom arguments and returns Void. public typealias ParameterBlock = Block /// Closure that takes no arguments and returns Void. -public typealias VoidBlock = ResultBlock +public typealias VoidBlock = () -> Void /// Closure with custom arguments and return value, may throw an error. public typealias ThrowableBlock = (Input) throws -> Output From a21847b7ff62e6aa4a7ada2c5b7f2347e815181a Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Sun, 17 Mar 2019 14:09:08 +0500 Subject: [PATCH 14/36] Added case iterable --- .../NumberFormattingService+DefaultImplementation.swift | 2 +- Sources/Protocols/NumberFormattingService/NumberFormat.swift | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Sources/Extensions/NumberFormattingService/NumberFormattingService+DefaultImplementation.swift b/Sources/Extensions/NumberFormattingService/NumberFormattingService+DefaultImplementation.swift index 8908bf2e..e8302f51 100644 --- a/Sources/Extensions/NumberFormattingService/NumberFormattingService+DefaultImplementation.swift +++ b/Sources/Extensions/NumberFormattingService/NumberFormattingService+DefaultImplementation.swift @@ -26,7 +26,7 @@ public extension NumberFormattingService { /// Computed static property. Use only once for `formatters` field implementation! static var computedFormatters: [NumberFormatType: NumberFormatter] { - return Dictionary(uniqueKeysWithValues: NumberFormatType.allOptions.map { ($0, $0.numberFormatter) }) + return Dictionary(uniqueKeysWithValues: NumberFormatType.allCases.map { ($0, $0.numberFormatter) }) } func numberFormatter(for format: NumberFormatType) -> NumberFormatter { diff --git a/Sources/Protocols/NumberFormattingService/NumberFormat.swift b/Sources/Protocols/NumberFormattingService/NumberFormat.swift index 91ced382..818eb65a 100644 --- a/Sources/Protocols/NumberFormattingService/NumberFormat.swift +++ b/Sources/Protocols/NumberFormattingService/NumberFormat.swift @@ -23,10 +23,7 @@ import Foundation /// Protocol for describing number format. -public protocol NumberFormat: Hashable { - - /// All available options. - static var allOptions: [Self] { get } +public protocol NumberFormat: Hashable, CaseIterable { /// A NumberFormatter instance for this format. var numberFormatter: NumberFormatter { get } From a73baf825366beff7b21129783ec693e0033e320 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Sun, 17 Mar 2019 14:17:21 +0500 Subject: [PATCH 15/36] Version up --- CHANGELOG.md | 4 ++++ LeadKit.podspec | 2 +- Sources/Info-iOS.plist | 2 +- Sources/Info-tvOS.plist | 2 +- Sources/Info-watchOS.plist | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0fa931f..96f7c497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### 0.9.11 +- **[Breaking change]**: Renamed `NumberFormat`'s `allOptions` to `allCases` +- **Fix**: Closure syntax fix + ### 0.9.10 - **Remove**: Removed unused scheme & target - **Remove**: Cocoapods deintegrated diff --git a/LeadKit.podspec b/LeadKit.podspec index 79a14220..b9217b30 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.9.10" + s.version = "0.9.11" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/Sources/Info-iOS.plist b/Sources/Info-iOS.plist index 4675ccda..968be549 100644 --- a/Sources/Info-iOS.plist +++ b/Sources/Info-iOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.10 + 0.9.11 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist index 4675ccda..968be549 100644 --- a/Sources/Info-tvOS.plist +++ b/Sources/Info-tvOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.10 + 0.9.11 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist index 4675ccda..968be549 100644 --- a/Sources/Info-watchOS.plist +++ b/Sources/Info-watchOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.10 + 0.9.11 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass From 517e9619ae35cfdd7dab305638168a2f6c817ee7 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Mon, 18 Mar 2019 14:49:32 +0500 Subject: [PATCH 16/36] Naming fix --- Sources/Functions/Block.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Functions/Block.swift b/Sources/Functions/Block.swift index e8a89711..bdb95203 100644 --- a/Sources/Functions/Block.swift +++ b/Sources/Functions/Block.swift @@ -21,16 +21,16 @@ // /// Closure with custom arguments and return value. -public typealias Block = (Input) -> Output +public typealias Closure = (Input) -> Output /// Closure that takes custom arguments and returns Void. -public typealias ParameterBlock = Block +public typealias ParameterClosure = Closure /// Closure that takes no arguments and returns Void. public typealias VoidBlock = () -> Void /// Closure with custom arguments and return value, may throw an error. -public typealias ThrowableBlock = (Input) throws -> Output +public typealias ThrowableClosure = (Input) throws -> Output /// Closure that takes no arguments, may throw an error and returns Void. public typealias ThrowableVoidBlock = () throws -> Void From 6556d8368b3ae93f6e8823b8513257f4bc3fdee2 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Tue, 19 Mar 2019 15:05:41 +0500 Subject: [PATCH 17/36] PR fixes --- CHANGELOG.md | 2 +- Sources/Functions/Block.swift | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96f7c497..7f3e9f91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### 0.9.11 - **[Breaking change]**: Renamed `NumberFormat`'s `allOptions` to `allCases` -- **Fix**: Closure syntax fix +- **Fix**: Closure syntax fix. New closure naming. ### 0.9.10 - **Remove**: Removed unused scheme & target diff --git a/Sources/Functions/Block.swift b/Sources/Functions/Block.swift index bdb95203..5cc19334 100644 --- a/Sources/Functions/Block.swift +++ b/Sources/Functions/Block.swift @@ -23,6 +23,9 @@ /// Closure with custom arguments and return value. public typealias Closure = (Input) -> Output +/// Closure with no arguments and custom return value. +public typealias ResultBlock = () -> Output + /// Closure that takes custom arguments and returns Void. public typealias ParameterClosure = Closure From 2df2979d8f1ceb58a2315b009b813a636005b0c7 Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Tue, 19 Mar 2019 15:33:49 +0500 Subject: [PATCH 18/36] Naming fix --- Sources/Functions/Block.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Functions/Block.swift b/Sources/Functions/Block.swift index 5cc19334..98c2e15f 100644 --- a/Sources/Functions/Block.swift +++ b/Sources/Functions/Block.swift @@ -24,13 +24,13 @@ public typealias Closure = (Input) -> Output /// Closure with no arguments and custom return value. -public typealias ResultBlock = () -> Output +public typealias ResultClosure = () -> Output /// Closure that takes custom arguments and returns Void. public typealias ParameterClosure = Closure /// Closure that takes no arguments and returns Void. -public typealias VoidBlock = () -> Void +public typealias VoidBlock = ResultClosure /// Closure with custom arguments and return value, may throw an error. public typealias ThrowableClosure = (Input) throws -> Output From d9f7da35f1adf36a1fbbca397601f0287f8c5f5e Mon Sep 17 00:00:00 2001 From: Pavel Lukandiy Date: Tue, 19 Mar 2019 16:05:57 +0500 Subject: [PATCH 19/36] Added missing function --- CHANGELOG.md | 1 + .../Views/BasePlaceholderView/BasePlaceholerView.swift | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f3e9f91..fb7ec37b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### 0.9.11 - **[Breaking change]**: Renamed `NumberFormat`'s `allOptions` to `allCases` - **Fix**: Closure syntax fix. New closure naming. +- **Fix**: Added missing `BasePlaceholderView` protocol function. ### 0.9.10 - **Remove**: Removed unused scheme & target diff --git a/Sources/Classes/Views/BasePlaceholderView/BasePlaceholerView.swift b/Sources/Classes/Views/BasePlaceholderView/BasePlaceholerView.swift index 479b9ce2..3e5e77d9 100644 --- a/Sources/Classes/Views/BasePlaceholderView/BasePlaceholerView.swift +++ b/Sources/Classes/Views/BasePlaceholderView/BasePlaceholerView.swift @@ -75,6 +75,10 @@ open class BasePlaceholderView: UIView, InitializableView { open func localize() { // override in subclass } + + open func configureLayout() { + // override in subclass + } } public extension BasePlaceholderView { From df2f969dc42575d16cafd63687be8392078589c2 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Wed, 20 Mar 2019 14:58:01 +0300 Subject: [PATCH 20/36] Added upload file request --- Sources/Classes/Services/NetworkService.swift | 18 +++ .../Alamofire/DataRequest+Extensions.swift | 63 ++++++++++- .../Alamofire/SessionManager+Extensions.swift | 61 ++++------ .../Api/ApiUploadRequestParameters.swift | 105 ++++++++++++++++++ 4 files changed, 206 insertions(+), 41 deletions(-) create mode 100644 Sources/Structures/Api/ApiUploadRequestParameters.swift diff --git a/Sources/Classes/Services/NetworkService.swift b/Sources/Classes/Services/NetworkService.swift index 5205ce0c..57e0e265 100644 --- a/Sources/Classes/Services/NetworkService.swift +++ b/Sources/Classes/Services/NetworkService.swift @@ -101,6 +101,24 @@ open class NetworkService { return sessionManager.rx.responseData(requestParameters: parameters, validStatusCodes: validStatusCodes) .counterTracking(for: self) } + + /// Perform reactive request to upload data and get Observable model and http response + /// + /// - Parameters: + /// - parameters: api upload parameters to pass Alamofire + /// - validStatusCodes: et of additional valid status codes + /// - decoder: json decoder to decode response data + /// - Returns: Observable of model response + public func rxUploadRequest(with parameters: ApiUploadRequestParameters, + validStatusCodes: Set = [], + decoder: JSONDecoder = JSONDecoder()) + -> Observable> { + + return sessionManager.rx.uploadResponseModel(requestParameters: parameters, + validStatusCodes: validStatusCodes, + decoder: decoder) + .counterTracking(for: self) + } } private extension NetworkService { diff --git a/Sources/Extensions/Alamofire/DataRequest+Extensions.swift b/Sources/Extensions/Alamofire/DataRequest+Extensions.swift index 458559ba..63bc33bd 100644 --- a/Sources/Extensions/Alamofire/DataRequest+Extensions.swift +++ b/Sources/Extensions/Alamofire/DataRequest+Extensions.swift @@ -34,12 +34,13 @@ public extension Reactive where Base: DataRequest { /// - Parameter decoder: JSONDecoder used to decode a decodable type /// - Returns: Observable with HTTP URL Response and target object func apiResponse(mappingQueue: DispatchQueue = .global(), decoder: JSONDecoder) - -> Observable<(response: HTTPURLResponse, model: T)> { + -> Observable> { return response(onQueue: mappingQueue) .tryMapResult { response, data in (response, try decoder.decode(T.self, from: data)) } + .catchAsRequestError(with: self.base) } /// Method that serializes response into target object @@ -47,7 +48,7 @@ public extension Reactive where Base: DataRequest { /// - Parameter mappingQueue: The dispatch queue to use for mapping /// - Returns: Observable with HTTP URL Response and target object func observableApiResponse(mappingQueue: DispatchQueue = .global(), decoder: JSONDecoder) - -> Observable<(response: HTTPURLResponse, model: T)> { + -> Observable> { return response(onQueue: mappingQueue) .tryMapObservableResult { response, value in @@ -55,6 +56,13 @@ public extension Reactive where Base: DataRequest { return T.create(from: json, with: decoder) .map { (response, $0) } } + .catchAsRequestError(with: self.base) + } + + func dataApiResponse(mappingQueue: DispatchQueue) -> Observable { + return response(onQueue: mappingQueue) + .map { $0 as SessionManager.DataResponse } + .catchAsRequestError(with: self.base) } private func response(onQueue queue: DispatchQueue) -> Observable<(HTTPURLResponse, Data)> { @@ -62,6 +70,19 @@ public extension Reactive where Base: DataRequest { } } +public extension ObservableType where E == DataRequest { + + /// Method that validates status codes and catch network errors + /// + /// - Parameter statusCodes: set of status codes to validate + /// - Returns: Observable on self + func validate(statusCodes: Set) -> Observable { + return map { $0.validate(statusCode: statusCodes) } + .catchAsRequestError() + } +} + + private extension ObservableType where E == ServerResponse { func tryMapResult(_ transform: @escaping (E) throws -> R) -> Observable { @@ -87,3 +108,41 @@ private extension ObservableType where E == ServerResponse { } } } + +private extension ObservableType { + + func catchAsRequestError(with request: DataRequest? = nil) -> Observable { + return catchError { error in + let resultError: RequestError + let response = request?.delegate.data + + switch error { + case let requestError as RequestError: + resultError = requestError + + case let urlError as URLError: + switch urlError.code { + case .notConnectedToInternet: + resultError = .noConnection + + default: + resultError = .network(error: urlError, response: response) + } + + case let afError as AFError: + switch afError { + case .responseSerializationFailed, .responseValidationFailed: + resultError = .invalidResponse(error: afError, response: response) + + default: + resultError = .network(error: afError, response: response) + } + + default: + resultError = .network(error: error, response: response) + } + + throw resultError + } + } +} diff --git a/Sources/Extensions/Alamofire/SessionManager+Extensions.swift b/Sources/Extensions/Alamofire/SessionManager+Extensions.swift index 52399baf..67ae710f 100644 --- a/Sources/Extensions/Alamofire/SessionManager+Extensions.swift +++ b/Sources/Extensions/Alamofire/SessionManager+Extensions.swift @@ -106,8 +106,7 @@ public extension Reactive where Base: SessionManager { } return requestObservable - .map { $0.validate(statusCode: self.base.acceptableStatusCodes.union(validStatusCodes)) } - .catchAsRequestError() + .validate(statusCodes: self.base.acceptableStatusCodes.union(validStatusCodes)) } /// Method that executes request and serializes response into target object @@ -125,7 +124,6 @@ public extension Reactive where Base: SessionManager { return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) .flatMap { $0.rx.apiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) - .catchAsRequestError(with: $0) } } @@ -144,7 +142,6 @@ public extension Reactive where Base: SessionManager { return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) .flatMap { $0.rx.observableApiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) - .catchAsRequestError(with: $0) } } @@ -159,47 +156,33 @@ public extension Reactive where Base: SessionManager { return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) .flatMap { - $0.rx.responseResult(queue: self.base.mappingQueue, - responseSerializer: DataRequest.dataResponseSerializer()) - .map { $0 as SessionManager.DataResponse } - .catchAsRequestError(with: $0) + $0.rx.dataApiResponse(mappingQueue: self.base.mappingQueue) } } -} -private extension ObservableType { - func catchAsRequestError(with request: DataRequest? = nil) -> Observable { - return catchError { error in - let resultError: RequestError - let response = request?.delegate.data + /// Method that executes upload request and serializes response into target object + /// + /// - Parameters: + /// - requestParameters: api upload parameters to pass Alamofire + /// - validStatusCodes: set of additional valid status codes + /// - decoder: json decoder to decode response data + /// - Returns: Observable with HTTP URL Response and target object + func uploadResponseModel(requestParameters: ApiUploadRequestParameters, + validStatusCodes: Set, + decoder: JSONDecoder) + -> Observable> { - switch error { - case let requestError as RequestError: - resultError = requestError + return Observable.deferred { - case let urlError as URLError: - switch urlError.code { - case .notConnectedToInternet: - resultError = .noConnection + let urlRequest = try URLRequest(url: requestParameters.url, method: .post, headers: requestParameters.headers) + let data = try requestParameters.formData.encode() - default: - resultError = .network(error: urlError, response: response) - } - - case let afError as AFError: - switch afError { - case .responseSerializationFailed, .responseValidationFailed: - resultError = .invalidResponse(error: afError, response: response) - - default: - resultError = .network(error: afError, response: response) - } - - default: - resultError = .network(error: error, response: response) + return self.upload(data, urlRequest: urlRequest) + .map { $0 as DataRequest } + .validate(statusCodes: self.base.acceptableStatusCodes.union(validStatusCodes)) + .flatMap { + $0.rx.apiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) + } } - - throw resultError - } } } diff --git a/Sources/Structures/Api/ApiUploadRequestParameters.swift b/Sources/Structures/Api/ApiUploadRequestParameters.swift new file mode 100644 index 00000000..706eb05a --- /dev/null +++ b/Sources/Structures/Api/ApiUploadRequestParameters.swift @@ -0,0 +1,105 @@ +// +// Copyright (c) 2019 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 +import MobileCoreServices + +private enum Constants { + + static let contentTypeKey = "Content-Type" + static let contentTypeValue = "multipart/form-data" + static let boundaryKey = "boundary" +} + +enum UploadParametersError: Error { + + case unableGetMimeType +} + + +/// Struct which keeps base parameters required for upload api request +public struct ApiUploadRequestParameters { + + let formData: MultipartFormData + let url: URLConvertible + let headers: HTTPHeaders + + public init(data: Data, + url: URLConvertible, + headers: HTTPHeaders?, + fileName: String, + name: String? = nil, + mimeType: String? = nil) throws { + + let formData = MultipartFormData() + + self.url = url + self.headers = ApiUploadRequestParameters.configureHTTPHeaders(with: headers ?? HTTPHeaders(), + formData: formData) + + let name = name ?? (fileName as NSString).deletingPathExtension + + let fileMimeType: String + + if let mimeType = mimeType { + fileMimeType = mimeType + } else { + fileMimeType = try ApiUploadRequestParameters.getFileMimeType(from: fileName) + } + + formData.append(data, withName: name, fileName: fileName, mimeType: fileMimeType) + + self.formData = formData + } +} + +private extension ApiUploadRequestParameters { + + static func configureHTTPHeaders(with headers: HTTPHeaders, + formData: MultipartFormData) -> HTTPHeaders { + + var requestHeaders = headers + + requestHeaders[Constants.boundaryKey] = formData.boundary + + if requestHeaders[Constants.contentTypeKey] == nil { + requestHeaders[Constants.contentTypeKey] = Constants.contentTypeValue + } + + return requestHeaders + } + + static func getFileMimeType(from fileName: String) throws -> String { + let fileExtension = (fileName as NSString).pathExtension + + guard let utiType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, + fileExtension as CFString, + nil)?.takeUnretainedValue(), + let mimeType = UTTypeCopyPreferredTagWithClass(utiType, kUTTagClassMIMEType) as? String else { + + assertionFailure("Unable to get mime type from file name") + throw UploadParametersError.unableGetMimeType + } + + return mimeType + } +} From 9938f1fc49276e6a1f8a698a277223138fb1298e Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Fri, 22 Mar 2019 16:33:40 +0300 Subject: [PATCH 21/36] Refactoring --- .../Api/ApiUploadRequestParameters.swift | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/Sources/Structures/Api/ApiUploadRequestParameters.swift b/Sources/Structures/Api/ApiUploadRequestParameters.swift index 706eb05a..7f6b3628 100644 --- a/Sources/Structures/Api/ApiUploadRequestParameters.swift +++ b/Sources/Structures/Api/ApiUploadRequestParameters.swift @@ -26,7 +26,7 @@ import MobileCoreServices private enum Constants { static let contentTypeKey = "Content-Type" - static let contentTypeValue = "multipart/form-data" + static let contentTypeValue = "multipart/form-data; " static let boundaryKey = "boundary" } @@ -43,9 +43,19 @@ public struct ApiUploadRequestParameters { let url: URLConvertible let headers: HTTPHeaders + /// ApiUploadRequestParameters initializator (You can get mime type from data using "Swime" pod) + /// + /// - Parameters: + /// - data: data to upload + /// - url: request url + /// - additionalHeaders: request additional headers exсept Content-Type + /// - fileName: file name with extension + /// - name: file name + /// - mimeType: file MIME-type + /// - Throws: UploadParametersError public init(data: Data, url: URLConvertible, - headers: HTTPHeaders?, + additionalHeaders: HTTPHeaders?, fileName: String, name: String? = nil, mimeType: String? = nil) throws { @@ -53,7 +63,7 @@ public struct ApiUploadRequestParameters { let formData = MultipartFormData() self.url = url - self.headers = ApiUploadRequestParameters.configureHTTPHeaders(with: headers ?? HTTPHeaders(), + self.headers = ApiUploadRequestParameters.configureHTTPHeaders(with: additionalHeaders ?? HTTPHeaders(), formData: formData) let name = name ?? (fileName as NSString).deletingPathExtension @@ -79,11 +89,9 @@ private extension ApiUploadRequestParameters { var requestHeaders = headers - requestHeaders[Constants.boundaryKey] = formData.boundary - - if requestHeaders[Constants.contentTypeKey] == nil { - requestHeaders[Constants.contentTypeKey] = Constants.contentTypeValue - } + let boundary = "\(Constants.boundaryKey)=\(formData.boundary)" + + requestHeaders[Constants.contentTypeKey] = Constants.contentTypeValue + boundary return requestHeaders } @@ -93,8 +101,9 @@ private extension ApiUploadRequestParameters { guard let utiType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, - nil)?.takeUnretainedValue(), - let mimeType = UTTypeCopyPreferredTagWithClass(utiType, kUTTagClassMIMEType) as? String else { + nil)?.takeRetainedValue(), + let mimeType = UTTypeCopyPreferredTagWithClass(utiType, + kUTTagClassMIMEType)?.takeRetainedValue() as? String else { assertionFailure("Unable to get mime type from file name") throw UploadParametersError.unableGetMimeType From c713e786f0c102bff94e1fd3b1f074d85baa3890 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Mon, 25 Mar 2019 13:20:18 +0300 Subject: [PATCH 22/36] Added mapping error handling --- .../Error/Error+NetworkExtensions.swift | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Sources/Extensions/Error/Error+NetworkExtensions.swift diff --git a/Sources/Extensions/Error/Error+NetworkExtensions.swift b/Sources/Extensions/Error/Error+NetworkExtensions.swift new file mode 100644 index 00000000..a8b68b72 --- /dev/null +++ b/Sources/Extensions/Error/Error+NetworkExtensions.swift @@ -0,0 +1,93 @@ +// +// Copyright (c) 2019 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 RxSwift + +public extension Error { + + var requestError: RequestError? { + return self as? RequestError + } + + /// Method that tries to serialize response from a mapping request error to a model + /// + /// - Parameter decoder: json decoder to decode response data + /// - Returns: optional target object + func handleMappingError(with decoder: JSONDecoder = JSONDecoder()) -> T? { + guard let self = requestError, case .mapping(_, let response) = self else { + return nil + } + + return try? decoder.decode(T.self, from: response) + } +} + +public extension ObservableType { + + /// Method that handles a mapping error and serialize response to a model + /// + /// - Parameters: + /// - decoder: json decoder to decode response data + /// - handler: closure that recieves serialized response + /// - Returns: Observable on caller + func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), + handler: @escaping (T?) -> ()) -> Observable { + return self.do(onError: { error in + let mappingModel: T? = error.handleMappingError(with: decoder) + handler(mappingModel) + }) + } +} + +public extension PrimitiveSequence where Trait == SingleTrait { + + /// Method that handles a mapping error and serialize response to a model + /// + /// - Parameters: + /// - decoder: json decoder to decode response data + /// - handler: closure that recieves serialized response + /// - Returns: Single on caller + func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), + handler: @escaping (T?) -> ()) -> PrimitiveSequence { + return self.do(onError: { error in + let mappingModel: T? = error.handleMappingError(with: decoder) + handler(mappingModel) + }) + } +} + +public extension PrimitiveSequence where Trait == CompletableTrait, Element == Never { + + /// Method that handles a mapping error and serialize response to a model + /// + /// - Parameters: + /// - decoder: json decoder to decode response data + /// - handler: closure that recieves serialized response + /// - Returns: Completable + func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), + handler: @escaping (T?) -> ()) -> Completable { + return self.do(onError: { error in + let mappingModel: T? = error.handleMappingError(with: decoder) + handler(mappingModel) + }) + } +} From f82158959fa82a7da274b88f799b168a4b3376c3 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Mon, 25 Mar 2019 14:32:19 +0300 Subject: [PATCH 23/36] Refactoring --- .../Error/Error+NetworkExtensions.swift | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Sources/Extensions/Error/Error+NetworkExtensions.swift b/Sources/Extensions/Error/Error+NetworkExtensions.swift index a8b68b72..f32e0d6b 100644 --- a/Sources/Extensions/Error/Error+NetworkExtensions.swift +++ b/Sources/Extensions/Error/Error+NetworkExtensions.swift @@ -32,12 +32,12 @@ public extension Error { /// /// - Parameter decoder: json decoder to decode response data /// - Returns: optional target object - func handleMappingError(with decoder: JSONDecoder = JSONDecoder()) -> T? { + func handleMappingError(with decoder: JSONDecoder = JSONDecoder()) throws -> T? { guard let self = requestError, case .mapping(_, let response) = self else { return nil } - return try? decoder.decode(T.self, from: response) + return try decoder.decode(T.self, from: response) } } @@ -50,9 +50,12 @@ public extension ObservableType { /// - handler: closure that recieves serialized response /// - Returns: Observable on caller func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), - handler: @escaping (T?) -> ()) -> Observable { + handler: @escaping ParameterClosure) -> Observable { return self.do(onError: { error in - let mappingModel: T? = error.handleMappingError(with: decoder) + guard let mappingModel = try error.handleMappingError(with: decoder) as T? else { + return + } + handler(mappingModel) }) } @@ -67,9 +70,12 @@ public extension PrimitiveSequence where Trait == SingleTrait { /// - handler: closure that recieves serialized response /// - Returns: Single on caller func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), - handler: @escaping (T?) -> ()) -> PrimitiveSequence { + handler: @escaping ParameterClosure) -> PrimitiveSequence { return self.do(onError: { error in - let mappingModel: T? = error.handleMappingError(with: decoder) + guard let mappingModel = try error.handleMappingError(with: decoder) as T? else { + return + } + handler(mappingModel) }) } @@ -84,9 +90,12 @@ public extension PrimitiveSequence where Trait == CompletableTrait, Element == N /// - handler: closure that recieves serialized response /// - Returns: Completable func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), - handler: @escaping (T?) -> ()) -> Completable { + handler: @escaping ParameterClosure) -> Completable { return self.do(onError: { error in - let mappingModel: T? = error.handleMappingError(with: decoder) + guard let mappingModel = try error.handleMappingError(with: decoder) as T? else { + return + } + handler(mappingModel) }) } From d3d813647782ded787a442215cee3c5f89696561 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Mon, 25 Mar 2019 14:51:12 +0300 Subject: [PATCH 24/36] Refactoring --- .../Extensions/Error/Error+NetworkExtensions.swift | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Sources/Extensions/Error/Error+NetworkExtensions.swift b/Sources/Extensions/Error/Error+NetworkExtensions.swift index f32e0d6b..872a0508 100644 --- a/Sources/Extensions/Error/Error+NetworkExtensions.swift +++ b/Sources/Extensions/Error/Error+NetworkExtensions.swift @@ -32,6 +32,7 @@ public extension Error { /// /// - Parameter decoder: json decoder to decode response data /// - Returns: optional target object + /// - Throws: an error during decoding func handleMappingError(with decoder: JSONDecoder = JSONDecoder()) throws -> T? { guard let self = requestError, case .mapping(_, let response) = self else { return nil @@ -52,11 +53,11 @@ public extension ObservableType { func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), handler: @escaping ParameterClosure) -> Observable { return self.do(onError: { error in - guard let mappingModel = try error.handleMappingError(with: decoder) as T? else { + guard let errorModel = try error.handleMappingError(with: decoder) as T? else { return } - handler(mappingModel) + handler(errorModel) }) } } @@ -72,11 +73,11 @@ public extension PrimitiveSequence where Trait == SingleTrait { func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), handler: @escaping ParameterClosure) -> PrimitiveSequence { return self.do(onError: { error in - guard let mappingModel = try error.handleMappingError(with: decoder) as T? else { + guard let errorModel = try error.handleMappingError(with: decoder) as T? else { return } - handler(mappingModel) + handler(errorModel) }) } } @@ -92,11 +93,11 @@ public extension PrimitiveSequence where Trait == CompletableTrait, Element == N func handleMappingError(with decoder: JSONDecoder = JSONDecoder(), handler: @escaping ParameterClosure) -> Completable { return self.do(onError: { error in - guard let mappingModel = try error.handleMappingError(with: decoder) as T? else { + guard let errorModel = try error.handleMappingError(with: decoder) as T? else { return } - handler(mappingModel) + handler(errorModel) }) } } From 5088c20e826f3c0b52d66961fc37eaceb323fa91 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Mon, 25 Mar 2019 15:08:17 +0300 Subject: [PATCH 25/36] Updated changelog, version up --- CHANGELOG.md | 9 +++++++++ LeadKit.podspec | 2 +- .../Extensions/Alamofire/DataRequest+Extensions.swift | 4 ++++ Sources/Info-iOS.plist | 2 +- Sources/Info-tvOS.plist | 2 +- Sources/Info-watchOS.plist | 2 +- 6 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb7ec37b..9daf0d62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +### 0.9.12 +- **Add**: `ApiUploadRequestParameters` struct, that defines upload data request parameters. +- **Add**: `rxUploadRequest` method to `NetworkService` class, that performs reactive request to upload data. +- **Add**: `uploadResponseModel` method to `SessionManager` extension, that executes upload request and serializes response. +- **Add**: `handleMappingError` method to `Error` extension, that tries to serialize response from a mapping request error to a model. +- **Add**: `handleMappingError` method to `ObservableType`, `Single`, `Completable` extensions, that handles a mapping error and serialize response to a model. +- **Add**: `validate` method to `DataRequest` observable extension, that validates status codes and catch network errors. +- **Add**: `dataApiResponse` method to `DataRequest` reactive extension, that serializes response into data. + ### 0.9.11 - **[Breaking change]**: Renamed `NumberFormat`'s `allOptions` to `allCases` - **Fix**: Closure syntax fix. New closure naming. diff --git a/LeadKit.podspec b/LeadKit.podspec index b9217b30..171580c3 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.9.11" + s.version = "0.9.12" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/Sources/Extensions/Alamofire/DataRequest+Extensions.swift b/Sources/Extensions/Alamofire/DataRequest+Extensions.swift index 63bc33bd..78177d07 100644 --- a/Sources/Extensions/Alamofire/DataRequest+Extensions.swift +++ b/Sources/Extensions/Alamofire/DataRequest+Extensions.swift @@ -59,6 +59,10 @@ public extension Reactive where Base: DataRequest { .catchAsRequestError(with: self.base) } + /// Method that serializes response into data + /// + /// - Parameter mappingQueue: The dispatch queue to use for mapping + /// - Returns: Observable with HTTP URL Response and data func dataApiResponse(mappingQueue: DispatchQueue) -> Observable { return response(onQueue: mappingQueue) .map { $0 as SessionManager.DataResponse } diff --git a/Sources/Info-iOS.plist b/Sources/Info-iOS.plist index 968be549..c3778cb9 100644 --- a/Sources/Info-iOS.plist +++ b/Sources/Info-iOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.11 + 0.9.12 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist index 968be549..c3778cb9 100644 --- a/Sources/Info-tvOS.plist +++ b/Sources/Info-tvOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.11 + 0.9.12 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist index 968be549..c3778cb9 100644 --- a/Sources/Info-watchOS.plist +++ b/Sources/Info-watchOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.11 + 0.9.12 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass From b30447e8778adfcbfe5d13e957fb3baec7fe2a94 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Mon, 25 Mar 2019 19:56:25 +0300 Subject: [PATCH 26/36] Refactoring --- CHANGELOG.md | 1 + Sources/Classes/Services/NetworkService.swift | 25 ++++++++-------- .../Alamofire/SessionManager+Extensions.swift | 30 +++++++++---------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9daf0d62..a4f7afdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - **Add**: `handleMappingError` method to `ObservableType`, `Single`, `Completable` extensions, that handles a mapping error and serialize response to a model. - **Add**: `validate` method to `DataRequest` observable extension, that validates status codes and catch network errors. - **Add**: `dataApiResponse` method to `DataRequest` reactive extension, that serializes response into data. +- **Update**: `validStatusCodes` parameter in network methods renamed to `additionalValidStatusCodes`. ### 0.9.11 - **[Breaking change]**: Renamed `NumberFormat`'s `allOptions` to `allCases` diff --git a/Sources/Classes/Services/NetworkService.swift b/Sources/Classes/Services/NetworkService.swift index 57e0e265..10cb8f8e 100644 --- a/Sources/Classes/Services/NetworkService.swift +++ b/Sources/Classes/Services/NetworkService.swift @@ -57,16 +57,16 @@ open class NetworkService { /// /// - Parameters: /// - parameters: api parameters to pass to Alamofire - /// - validStatusCodes: set of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - decoder: json decoder to decode response data /// - Returns: Observable of tuple containing (HTTPURLResponse, ObservableMappable) public func rxObservableRequest(with parameters: ApiRequestParameters, - validStatusCodes: Set = [], + additionalValidStatusCodes: Set = [], decoder: JSONDecoder = JSONDecoder()) -> Observable> { return sessionManager.rx.responseObservableModel(requestParameters: parameters, - validStatusCodes: validStatusCodes, + additionalValidStatusCodes: additionalValidStatusCodes, decoder: decoder) .counterTracking(for: self) } @@ -75,16 +75,16 @@ open class NetworkService { /// /// - Parameters: /// - parameters: api parameters to pass to Alamofire - /// - validStatusCodes: set of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - decoder: json decoder to decode response data /// - Returns: Observable of tuple containing (HTTPURLResponse, ImmutableMappable) public func rxRequest(with parameters: ApiRequestParameters, - validStatusCodes: Set = [], + additionalValidStatusCodes: Set = [], decoder: JSONDecoder = JSONDecoder()) -> Observable> { return sessionManager.rx.responseModel(requestParameters: parameters, - validStatusCodes: validStatusCodes, + additionalValidStatusCodes: additionalValidStatusCodes, decoder: decoder) .counterTracking(for: self) } @@ -93,12 +93,13 @@ open class NetworkService { /// /// - Parameters: /// - parameters: api parameters to pass to Alamofire - /// - validStatusCodes: set of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - Returns: Observable of tuple containing (HTTPURLResponse, Data) - public func rxDataRequest(with parameters: ApiRequestParameters, validStatusCodes: Set = []) + public func rxDataRequest(with parameters: ApiRequestParameters, additionalValidStatusCodes: Set = []) -> Observable { - return sessionManager.rx.responseData(requestParameters: parameters, validStatusCodes: validStatusCodes) + return sessionManager.rx.responseData(requestParameters: parameters, + additionalValidStatusCodes: additionalValidStatusCodes) .counterTracking(for: self) } @@ -106,16 +107,16 @@ open class NetworkService { /// /// - Parameters: /// - parameters: api upload parameters to pass Alamofire - /// - validStatusCodes: et of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - decoder: json decoder to decode response data /// - Returns: Observable of model response public func rxUploadRequest(with parameters: ApiUploadRequestParameters, - validStatusCodes: Set = [], + additionalValidStatusCodes: Set = [], decoder: JSONDecoder = JSONDecoder()) -> Observable> { return sessionManager.rx.uploadResponseModel(requestParameters: parameters, - validStatusCodes: validStatusCodes, + additionalValidStatusCodes: additionalValidStatusCodes, decoder: decoder) .counterTracking(for: self) } diff --git a/Sources/Extensions/Alamofire/SessionManager+Extensions.swift b/Sources/Extensions/Alamofire/SessionManager+Extensions.swift index 67ae710f..a8afc976 100644 --- a/Sources/Extensions/Alamofire/SessionManager+Extensions.swift +++ b/Sources/Extensions/Alamofire/SessionManager+Extensions.swift @@ -70,9 +70,9 @@ public extension Reactive where Base: SessionManager { /// /// - Parameters: /// - requestParameters: api parameters to pass Alamofire - /// - validStatusCodes: set of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - Returns: Observable with request - func apiRequest(requestParameters: ApiRequestParameters, validStatusCodes: Set) + func apiRequest(requestParameters: ApiRequestParameters, additionalValidStatusCodes: Set) -> Observable { let requestObservable: Observable @@ -106,22 +106,22 @@ public extension Reactive where Base: SessionManager { } return requestObservable - .validate(statusCodes: self.base.acceptableStatusCodes.union(validStatusCodes)) + .validate(statusCodes: self.base.acceptableStatusCodes.union(additionalValidStatusCodes)) } /// Method that executes request and serializes response into target object /// /// - Parameters: /// - requestParameters: api parameters to pass Alamofire - /// - validStatusCodes: set of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - decoder: json decoder to decode response data /// - Returns: Observable with HTTP URL Response and target object func responseModel(requestParameters: ApiRequestParameters, - validStatusCodes: Set, + additionalValidStatusCodes: Set, decoder: JSONDecoder) -> Observable> { - return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) + return apiRequest(requestParameters: requestParameters, additionalValidStatusCodes: additionalValidStatusCodes) .flatMap { $0.rx.apiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) } @@ -131,15 +131,15 @@ public extension Reactive where Base: SessionManager { /// /// - Parameters: /// - requestParameters: api parameters to pass Alamofire - /// - validStatusCodes: set of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - decoder: json decoder to decode response data /// - Returns: Observable with HTTP URL Response and target object func responseObservableModel(requestParameters: ApiRequestParameters, - validStatusCodes: Set, + additionalValidStatusCodes: Set, decoder: JSONDecoder) -> Observable> { - return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) + return apiRequest(requestParameters: requestParameters, additionalValidStatusCodes: additionalValidStatusCodes) .flatMap { $0.rx.observableApiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) } @@ -149,12 +149,12 @@ public extension Reactive where Base: SessionManager { /// /// - Parameters: /// - requestParameters: api parameters to pass Alamofire - /// - validStatusCodes: set of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - Returns: Observable with HTTP URL Response and Data - func responseData(requestParameters: ApiRequestParameters, validStatusCodes: Set) + func responseData(requestParameters: ApiRequestParameters, additionalValidStatusCodes: Set) -> Observable { - return apiRequest(requestParameters: requestParameters, validStatusCodes: validStatusCodes) + return apiRequest(requestParameters: requestParameters, additionalValidStatusCodes: additionalValidStatusCodes) .flatMap { $0.rx.dataApiResponse(mappingQueue: self.base.mappingQueue) } @@ -164,11 +164,11 @@ public extension Reactive where Base: SessionManager { /// /// - Parameters: /// - requestParameters: api upload parameters to pass Alamofire - /// - validStatusCodes: set of additional valid status codes + /// - additionalValidStatusCodes: set of additional valid status codes /// - decoder: json decoder to decode response data /// - Returns: Observable with HTTP URL Response and target object func uploadResponseModel(requestParameters: ApiUploadRequestParameters, - validStatusCodes: Set, + additionalValidStatusCodes: Set, decoder: JSONDecoder) -> Observable> { @@ -179,7 +179,7 @@ public extension Reactive where Base: SessionManager { return self.upload(data, urlRequest: urlRequest) .map { $0 as DataRequest } - .validate(statusCodes: self.base.acceptableStatusCodes.union(validStatusCodes)) + .validate(statusCodes: self.base.acceptableStatusCodes.union(additionalValidStatusCodes)) .flatMap { $0.rx.apiResponse(mappingQueue: self.base.mappingQueue, decoder: decoder) } From 23058232cefe9d4dc2d682ec11bd3e679e7ad976 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Tue, 26 Mar 2019 13:03:05 +0300 Subject: [PATCH 27/36] Fixed changelog --- CHANGELOG.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4f7afdb..c4378c2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,13 @@ # Changelog ### 0.9.12 -- **Add**: `ApiUploadRequestParameters` struct, that defines upload data request parameters. -- **Add**: `rxUploadRequest` method to `NetworkService` class, that performs reactive request to upload data. -- **Add**: `uploadResponseModel` method to `SessionManager` extension, that executes upload request and serializes response. -- **Add**: `handleMappingError` method to `Error` extension, that tries to serialize response from a mapping request error to a model. -- **Add**: `handleMappingError` method to `ObservableType`, `Single`, `Completable` extensions, that handles a mapping error and serialize response to a model. -- **Add**: `validate` method to `DataRequest` observable extension, that validates status codes and catch network errors. -- **Add**: `dataApiResponse` method to `DataRequest` reactive extension, that serializes response into data. +- **Add**: `ApiUploadRequestParameters` struct that defines upload data request parameters. +- **Add**: `rxUploadRequest` method to `NetworkService` class that performs reactive request to upload data. +- **Add**: `uploadResponseModel` method to `SessionManager` extension that executes upload request and serializes response. +- **Add**: `handleMappingError` method to `Error` extension that tries to serialize response from a mapping request error to a model. +- **Add**: `handleMappingError` method to `ObservableType`, `Single`, `Completable` extensions that handles a mapping error and serialize response to a model. +- **Add**: `validate` method to `DataRequest` observable extension that validates status codes and catch network errors. +- **Add**: `dataApiResponse` method to `DataRequest` reactive extension that serializes response into data. - **Update**: `validStatusCodes` parameter in network methods renamed to `additionalValidStatusCodes`. ### 0.9.11 From 7d96e07b4ea35436415ab7ea6dc446fe7445fa8e Mon Sep 17 00:00:00 2001 From: Artur Date: Tue, 26 Mar 2019 20:22:04 +0300 Subject: [PATCH 28/36] Merge master --- CHANGELOG.md | 12 ++ Cartfile | 2 +- LeadKit.podspec | 2 + Podfile | 0 Podfile.lock | 0 .../Search/BaseSearchViewController.swift | 198 ++++++++++++++++++ .../Classes/Search/BaseSearchViewModel.swift | 100 +++++++++ .../SearchResultsViewControllerState.swift | 29 +++ .../SearchResultsViewController.swift | 29 +++ Sources/Protocols/OptionalType.swift | 42 ++++ build-scripts | 2 +- 11 files changed, 414 insertions(+), 2 deletions(-) create mode 100644 Podfile create mode 100644 Podfile.lock create mode 100644 Sources/Classes/Search/BaseSearchViewController.swift create mode 100644 Sources/Classes/Search/BaseSearchViewModel.swift create mode 100644 Sources/Enums/Search/SearchResultsViewControllerState.swift create mode 100644 Sources/Protocols/Controllers/SearchResultsViewController.swift create mode 100644 Sources/Protocols/OptionalType.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index fb7ec37b..1686b760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ # Changelog +### 0.9.9 +- **Add**: `BaseSearchViewController` class that that allows to enter text for search and then displays search results in table view. +- **Add**: `BaseSearchViewModel` class that loads data from a given data source and performs search among the results. +- **Add**: `SearchResultsController` protocol that represent a controller able to display search results. +- **Add**: `SearchResultsControllerState` enum that represents `SearchResultsController` state. + +### 0.9.8 +- **Add**: `rxDataRequest` method to `NetworkService` class, that performs reactive request to get data and http response. +- **Add**: `responseData` method to `SessionManager` extension, that executes request and returns data. + +### 0.9.7 +- **Add**: Carthage support. ### 0.9.11 - **[Breaking change]**: Renamed `NumberFormat`'s `allOptions` to `allCases` diff --git a/Cartfile b/Cartfile index a662e7b8..16dc9a2b 100644 --- a/Cartfile +++ b/Cartfile @@ -3,4 +3,4 @@ binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/Alamofire/A binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxAlamofire/RxAlamofire.json" github "ReactiveX/RxSwift" github "maxsokolov/TableKit" -github "pronebird/UIScrollView-InfiniteScroll" \ No newline at end of file +github "pronebird/UIScrollView-InfiniteScroll" diff --git a/LeadKit.podspec b/LeadKit.podspec index b9217b30..5d7ec659 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -34,6 +34,7 @@ Pod::Spec.new do |s| "Sources/Classes/Views/CollectionViewWrapperView/*", "Sources/Classes/Views/TableViewWrapperView/*", "Sources/Classes/Views/BasePlaceholderView/*", + "Sources/Classes/Search/*", "Sources/Extensions/CABasicAnimation/*", "Sources/Extensions/CGFloat/CGFloat+Pixels.swift", "Sources/Extensions/NetworkService/NetworkService+RxLoadImage.swift", @@ -69,6 +70,7 @@ Pod::Spec.new do |s| "Sources/Classes/Views/SeparatorCell/*", "Sources/Classes/Views/EmptyCell/*", "Sources/Classes/DataLoading/PaginationDataLoading/PaginationWrapper.swift", + "Sources/Classes/Search/*", "Sources/Structures/Drawing/CALayerDrawingOperation.swift", "Sources/Extensions/DataLoading/PaginationDataLoading/*", "Sources/Extensions/Support/UIScrollView+Support.swift", diff --git a/Podfile b/Podfile new file mode 100644 index 00000000..e69de29b diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 00000000..e69de29b diff --git a/Sources/Classes/Search/BaseSearchViewController.swift b/Sources/Classes/Search/BaseSearchViewController.swift new file mode 100644 index 00000000..e9b96d5f --- /dev/null +++ b/Sources/Classes/Search/BaseSearchViewController.swift @@ -0,0 +1,198 @@ +// +// Copyright (c) 2019 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 TableKit +import RxSwift +import UIKit + +public typealias SearchResultsController = UIViewController & SearchResultsViewController + +/// Class that allows to enter text for search and then displays search results in table view +open class BaseSearchViewController: BaseCustomViewController +where ViewModel: BaseSearchViewModel { + + // MARK: - Properties + + private let disposeBag = DisposeBag() + private let searchResultsController: SearchResultsController + private let searchController: UISearchController + private var didEnterText = false + + // MARK: - Initialization + + public init(viewModel: ViewModel, searchResultsController: SearchResultsController) { + self.searchResultsController = searchResultsController + self.searchController = UISearchController(searchResultsController: searchResultsController) + super.init(viewModel: viewModel) + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Configurable Controller + + open override func bindViews() { + super.bindViews() + + viewModel.itemsViewModelsDriver + .drive(onNext: { [weak self] viewModels in + self?.handle(itemViewModels: viewModels) + }) + .disposed(by: disposeBag) + + Observable.merge(searchResults, resetResults) + .subscribe(onNext: { [weak self] state in + self?.handle(searchResultsState: state) + }) + .disposed(by: disposeBag) + + let searchText = searchController.searchBar.rx.text + .changed + .do(onNext: { [weak self] text in + self?.handle(searchText: text) + }) + .map { $0 ?? "" } + + viewModel.bind(searchText: searchText) + .disposed(by: disposeBag) + } + + open override func addViews() { + super.addViews() + + if #available(iOS 11.0, *) { + navigationItem.searchController = searchController + } else { + customView.tableView.tableHeaderView = searchController.searchBar + } + searchController.view.addSubview(statusBarView) + } + + open override func configureAppearance() { + super.configureAppearance() + + definesPresentationContext = true + customView.tableView.tableHeaderView?.backgroundColor = searchBarColor + } + + open override func localize() { + super.localize() + + searchController.searchBar.placeholder = searchBarPlaceholder + } + + // MARK: - Search Controller Functionality + + open func createRows(from itemsViewModels: [ItemViewModel]) -> [Row] { + assertionFailure("createRows(from:) has not been implemented") + return [] + } + + open var searchBarPlaceholder: String { + return "" + } + + open var searchBarColor: UIColor { + return .gray + } + + open var statusBarView: UIView { + let statusBarSize = statusBarFrame().size + let statusBarView = UIView(frame: CGRect(x: 0, + y: 0, + width: statusBarSize.width, + height: statusBarSize.height)) + statusBarView.backgroundColor = statusBarColor + + return statusBarView + } + + open var statusBarColor: UIColor { + return .black + } + + open func updateContent(with viewModels: [ItemViewModel]) { + // override in subclass + } + + open func stateForUpdate(with viewModels: [ItemViewModel]) -> SearchResultsViewControllerState { + let rows = createRows(from: viewModels) + return .rowsContent(rows: rows) + } + + open var resetResults: Observable { + return searchController.rx.willPresent + .map { SearchResultsViewControllerState.initial } + } + + open var searchResults: Observable { + return viewModel.searchResultsDriver + .asObservable() + .map { [weak self] viewModels -> SearchResultsViewControllerState in + self?.stateForUpdate(with: viewModels) ?? .rowsContent(rows: []) + } + } + + // MARK: - Helpers + + open func handle(itemViewModels viewModels: [ItemViewModel]) { + updateContent(with: viewModels) + } + + open func handle(searchResultsState state: SearchResultsViewControllerState) { + searchResultsController.update(for: state) + } + + open func handle(searchText: String?) { + setTableViewInsets() + } + + private func setTableViewInsets() { + guard !didEnterText else { + return + } + didEnterText = true + searchResultsController.searchResultsView.tableView.contentInset = tableViewInsets + searchResultsController.searchResultsView.tableView.scrollIndicatorInsets = tableViewInsets + } + + open func statusBarFrame() -> CGRect { + /// override in subclass + return .zero + } +} + +extension BaseSearchViewController { + open var tableViewInsets: UIEdgeInsets { + let searchBarHeight = searchController.searchBar.frame.height + let statusBarHeight = statusBarFrame().height + + return UIEdgeInsets(top: searchBarHeight + statusBarHeight, + left: 0, + bottom: 0, + right: 0) + } +} diff --git a/Sources/Classes/Search/BaseSearchViewModel.swift b/Sources/Classes/Search/BaseSearchViewModel.swift new file mode 100644 index 00000000..e9e5cdc3 --- /dev/null +++ b/Sources/Classes/Search/BaseSearchViewModel.swift @@ -0,0 +1,100 @@ +// +// Copyright (c) 2019 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 RxSwift +import RxCocoa + +/// ViewModel that loads data from a given data source and performs search among results +open class BaseSearchViewModel: GeneralDataLoadingViewModel<[Item]> { + + public typealias ItemsList = [Item] + + private let searchTextRelay = BehaviorRelay(value: "") + + public init(dataSource: Single) { + super.init(dataSource: dataSource, emptyResultChecker: { $0.isEmpty }) + } + + open var itemsViewModelsDriver: Driver<[ItemViewModel]> { + return loadingResultObservable + .map { [weak self] items in + self?.viewModels(from: items) + } + .filterNil() + .share(replay: 1, scope: .forever) + .asDriver(onErrorDriveWith: .empty()) + } + + open var searchResultsDriver: Driver<[ItemViewModel]> { + return searchTextRelay.throttle(1, scheduler: MainScheduler.instance) + .withLatestFrom(loadingResultObservable) { ($0, $1) } + .flatMapLatest { [weak self] searchText, items -> Observable in + self?.search(by: searchText, from: items).asObservable() ?? .empty() + } + .map { [weak self] items in + self?.viewModels(from: items) + } + .filterNil() + .share(replay: 1, scope: .forever) + .asDriver(onErrorDriveWith: .empty()) + } + + open func viewModel(from item: Item) -> ItemViewModel { + fatalError("viewModel(from:) has not been implemented") + } + + open func search(by searchString: String, from items: ItemsList) -> Single { + fatalError("searchEngine(for:) has not been implemented") + } + + open func bind(searchText: Observable) -> Disposable { + return searchText.bind(to: searchTextRelay) + } + + open func onDidSelect(item: Item) { + // override in subclass + } + + private func viewModels(from items: ItemsList) -> [ItemViewModel] { + return items.map { self.viewModel(from: $0) } + } + + open var loadingResultObservable: Observable { + return loadingStateDriver + .asObservable() + .map { $0.result } + .filterNil() + } + + open var loadingErrorObservable: Observable { + return loadingStateDriver + .asObservable() + .map { $0.error } + .filterNil() + } + + open var firstLoadingResultObservable: Single { + return loadingResultObservable + .take(1) + .asSingle() + } +} diff --git a/Sources/Enums/Search/SearchResultsViewControllerState.swift b/Sources/Enums/Search/SearchResultsViewControllerState.swift new file mode 100644 index 00000000..783ab93a --- /dev/null +++ b/Sources/Enums/Search/SearchResultsViewControllerState.swift @@ -0,0 +1,29 @@ +// +// Copyright (c) 2019 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 TableKit + +public enum SearchResultsViewControllerState { + case initial + case rowsContent(rows: [Row]) + case sectionsContent(sections: [TableSection]) +} diff --git a/Sources/Protocols/Controllers/SearchResultsViewController.swift b/Sources/Protocols/Controllers/SearchResultsViewController.swift new file mode 100644 index 00000000..c29e5611 --- /dev/null +++ b/Sources/Protocols/Controllers/SearchResultsViewController.swift @@ -0,0 +1,29 @@ +// +// Copyright (c) 2019 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. +// + +/// Protocol that represents a ViewController able to present search results +public protocol SearchResultsViewController { + + var searchResultsView: TableViewHolder { get set } + + func update(for state: SearchResultsViewControllerState) +} diff --git a/Sources/Protocols/OptionalType.swift b/Sources/Protocols/OptionalType.swift new file mode 100644 index 00000000..ed36ea85 --- /dev/null +++ b/Sources/Protocols/OptionalType.swift @@ -0,0 +1,42 @@ +// +// Copyright (c) 2019 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 RxSwift + +/// Protocol that represents optional type. This is required for Observable's filterNil() function +protocol OptionalType { + associatedtype Wrapped + + var optional: Wrapped? { get } +} + +extension Optional: OptionalType { + public var optional: Wrapped? { return self } +} + +extension Observable where Element: OptionalType { + func filterNil() -> Observable { + return flatMap { value -> Observable in + value.optional.map { .just($0) } ?? .empty() + } + } +} diff --git a/build-scripts b/build-scripts index 54935bbe..8a74be38 160000 --- a/build-scripts +++ b/build-scripts @@ -1 +1 @@ -Subproject commit 54935bbe26063cdf04e72b8cb76d61c727ff99a7 +Subproject commit 8a74be38b9aa3f940503ad09127c28feee022983 From 1dfa0b4f4860c5a608981b1e0b1f0ed5a602e949 Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 27 Mar 2019 13:50:33 +0300 Subject: [PATCH 29/36] Issues fixed --- Sources/Protocols/OptionalType.swift | 42 ---------------------------- 1 file changed, 42 deletions(-) delete mode 100644 Sources/Protocols/OptionalType.swift diff --git a/Sources/Protocols/OptionalType.swift b/Sources/Protocols/OptionalType.swift deleted file mode 100644 index ed36ea85..00000000 --- a/Sources/Protocols/OptionalType.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) 2019 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 RxSwift - -/// Protocol that represents optional type. This is required for Observable's filterNil() function -protocol OptionalType { - associatedtype Wrapped - - var optional: Wrapped? { get } -} - -extension Optional: OptionalType { - public var optional: Wrapped? { return self } -} - -extension Observable where Element: OptionalType { - func filterNil() -> Observable { - return flatMap { value -> Observable in - value.optional.map { .just($0) } ?? .empty() - } - } -} From 053c08443bc6fa36b976b35e86cb95f87c9304b3 Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 27 Mar 2019 13:52:38 +0300 Subject: [PATCH 30/36] Fixes --- LeadKit.xcodeproj/project.pbxproj | 32 +++++++++++++++++++ .../Search/BaseSearchViewController.swift | 8 +++-- .../Classes/Search/BaseSearchViewModel.swift | 14 ++++---- iOS.playground/Contents.swift | 2 -- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 96f56f7f..7abae4ce 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -470,6 +470,10 @@ 7295473F21E661E6009558E7 /* TitleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7295473E21E661E6009558E7 /* TitleType.swift */; }; 7295474221E6628C009558E7 /* UINavigationItem+Support.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7295474121E6628C009558E7 /* UINavigationItem+Support.swift */; }; 7295474421E66328009558E7 /* UIViewController+UpdateNavigationItemTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7295474321E66328009558E7 /* UIViewController+UpdateNavigationItemTitle.swift */; }; + 72AECC6B224A979D00D12E7C /* BaseSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72AECC69224A979D00D12E7C /* BaseSearchViewController.swift */; }; + 72AECC6C224A979D00D12E7C /* BaseSearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72AECC6A224A979D00D12E7C /* BaseSearchViewModel.swift */; }; + 72AECC6F224A97B100D12E7C /* SearchResultsViewControllerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72AECC6E224A97B100D12E7C /* SearchResultsViewControllerState.swift */; }; + 72AECC71224A97F100D12E7C /* SearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72AECC70224A97F000D12E7C /* SearchResultsViewController.swift */; }; 785EDF7C220072B500985ED4 /* SwiftDate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 785EDF76220072B400985ED4 /* SwiftDate.framework */; }; 785EDF7D220072B500985ED4 /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 785EDF77220072B400985ED4 /* RxCocoa.framework */; }; 785EDF7E220072B500985ED4 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 785EDF78220072B500985ED4 /* Alamofire.framework */; }; @@ -764,6 +768,10 @@ 7295473E21E661E6009558E7 /* TitleType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleType.swift; sourceTree = ""; }; 7295474121E6628C009558E7 /* UINavigationItem+Support.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationItem+Support.swift"; sourceTree = ""; }; 7295474321E66328009558E7 /* UIViewController+UpdateNavigationItemTitle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+UpdateNavigationItemTitle.swift"; sourceTree = ""; }; + 72AECC69224A979D00D12E7C /* BaseSearchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseSearchViewController.swift; sourceTree = ""; }; + 72AECC6A224A979D00D12E7C /* BaseSearchViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseSearchViewModel.swift; sourceTree = ""; }; + 72AECC6E224A97B100D12E7C /* SearchResultsViewControllerState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchResultsViewControllerState.swift; sourceTree = ""; }; + 72AECC70224A97F000D12E7C /* SearchResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchResultsViewController.swift; sourceTree = ""; }; 785EDF76220072B400985ED4 /* SwiftDate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftDate.framework; path = Carthage/Build/iOS/SwiftDate.framework; sourceTree = ""; }; 785EDF77220072B400985ED4 /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxCocoa.framework; path = Carthage/Build/iOS/RxCocoa.framework; sourceTree = ""; }; 785EDF78220072B500985ED4 /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = Carthage/Build/iOS/Alamofire.framework; sourceTree = ""; }; @@ -887,6 +895,7 @@ isa = PBXGroup; children = ( 6741CEC520E2434900FEC4D9 /* Controllers */, + 72AECC68224A979D00D12E7C /* Search */, 6774527E2062566D0024EEEF /* DataLoading */, 671461D21EB3396E00EAB194 /* Services */, 671461D41EB3396E00EAB194 /* Views */, @@ -946,6 +955,7 @@ isa = PBXGroup; children = ( 67274767206CCB6F00725163 /* Views */, + 72AECC6D224A97B100D12E7C /* Search */, 6774528A20625C860024EEEF /* DataLoading */, 671461D81EB3396E00EAB194 /* LeadKitError.swift */, 671461D91EB3396E00EAB194 /* ResizeMode.swift */, @@ -1459,6 +1469,7 @@ isa = PBXGroup; children = ( 671462241EB3396E00EAB194 /* ConfigurableController.swift */, + 72AECC70224A97F000D12E7C /* SearchResultsViewController.swift */, ); path = Controllers; sourceTree = ""; @@ -1939,6 +1950,23 @@ path = TableKitViewModel; sourceTree = ""; }; + 72AECC68224A979D00D12E7C /* Search */ = { + isa = PBXGroup; + children = ( + 72AECC69224A979D00D12E7C /* BaseSearchViewController.swift */, + 72AECC6A224A979D00D12E7C /* BaseSearchViewModel.swift */, + ); + path = Search; + sourceTree = ""; + }; + 72AECC6D224A97B100D12E7C /* Search */ = { + isa = PBXGroup; + children = ( + 72AECC6E224A97B100D12E7C /* SearchResultsViewControllerState.swift */, + ); + path = Search; + sourceTree = ""; + }; 785EDF75220072B400985ED4 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -2423,6 +2451,7 @@ 67EB7FF8206175F700BDD9FB /* PaginationWrappable.swift in Sources */, 67990AD6213EA6A50040D195 /* ContentLoadingViewModel+Extensions.swift in Sources */, 671463541EB3396E00EAB194 /* StaticViewHeightProtocol.swift in Sources */, + 72AECC6B224A979D00D12E7C /* BaseSearchViewController.swift in Sources */, 673CF4112063ABD100C329F6 /* GeneralDataLoadingState+Extensions.swift in Sources */, 673CF42C2063DE5900C329F6 /* TextPlaceholderView.swift in Sources */, 67ED2BDE20B44DEB00508B3E /* InitializableView.swift in Sources */, @@ -2482,6 +2511,7 @@ 6741CEB420E242C100FEC4D9 /* CollectionViewHolder+ScrollViewHolder.swift in Sources */, A676AE501F9810C1001F9214 /* Any+Cast.swift in Sources */, 78EC7B1322019F5A0007DCFD /* String+TelpromptURL.swift in Sources */, + 72AECC6F224A97B100D12E7C /* SearchResultsViewControllerState.swift in Sources */, 6714627C1EB3396E00EAB194 /* SessionManager+Extensions.swift in Sources */, 671462D41EB3396E00EAB194 /* TableDirector+Extensions.swift in Sources */, 67E352572119ACF30035BDDB /* ViewTextConfigurable+Extensions.swift in Sources */, @@ -2507,6 +2537,7 @@ B84CB06D20B8325D0090DB91 /* SessionManager.swift in Sources */, A658E5501F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift in Sources */, 673564F12068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift in Sources */, + 72AECC6C224A979D00D12E7C /* BaseSearchViewModel.swift in Sources */, 7295474221E6628C009558E7 /* UINavigationItem+Support.swift in Sources */, 7295474421E66328009558E7 /* UIViewController+UpdateNavigationItemTitle.swift in Sources */, 671462EC1EB3396E00EAB194 /* UIImage+Extensions.swift in Sources */, @@ -2597,6 +2628,7 @@ 6714629C1EB3396E00EAB194 /* CursorType+Slice.swift in Sources */, 6774529F20625EEE0024EEEF /* PaginationDataLoadingModel.swift in Sources */, 678D267920691D8200B05B93 /* DataModelFieldBinding.swift in Sources */, + 72AECC71224A97F100D12E7C /* SearchResultsViewController.swift in Sources */, 673CF4342063E29B00C329F6 /* TextWithButtonPlaceholder.swift in Sources */, 673CF4222063D90600C329F6 /* DisposeBagHolder.swift in Sources */, 67DB776D210871E8001CB56B /* BaseCollectionContentController.swift in Sources */, diff --git a/Sources/Classes/Search/BaseSearchViewController.swift b/Sources/Classes/Search/BaseSearchViewController.swift index e9b96d5f..2e170cc1 100644 --- a/Sources/Classes/Search/BaseSearchViewController.swift +++ b/Sources/Classes/Search/BaseSearchViewController.swift @@ -46,6 +46,7 @@ where ViewModel: BaseSearchViewModel { self.searchResultsController = searchResultsController self.searchController = UISearchController(searchResultsController: searchResultsController) super.init(viewModel: viewModel) + initialLoadView() } required public init?(coder aDecoder: NSCoder) { @@ -56,7 +57,6 @@ where ViewModel: BaseSearchViewModel { open override func bindViews() { super.bindViews() - viewModel.itemsViewModelsDriver .drive(onNext: { [weak self] viewModels in self?.handle(itemViewModels: viewModels) @@ -93,8 +93,8 @@ where ViewModel: BaseSearchViewModel { open override func configureAppearance() { super.configureAppearance() - definesPresentationContext = true + configureSearchBarAppearance(searchController.searchBar) customView.tableView.tableHeaderView?.backgroundColor = searchBarColor } @@ -183,6 +183,10 @@ where ViewModel: BaseSearchViewModel { /// override in subclass return .zero } + + open func configureSearchBarAppearance(_ searchBar: UISearchBar) { + // override in subclass + } } extension BaseSearchViewController { diff --git a/Sources/Classes/Search/BaseSearchViewModel.swift b/Sources/Classes/Search/BaseSearchViewModel.swift index e9e5cdc3..b550fae7 100644 --- a/Sources/Classes/Search/BaseSearchViewModel.swift +++ b/Sources/Classes/Search/BaseSearchViewModel.swift @@ -44,8 +44,12 @@ open class BaseSearchViewModel: GeneralDataLoadingViewModel .asDriver(onErrorDriveWith: .empty()) } + open var searchDebounceInterval: RxTimeInterval { + return 1 + } + open var searchResultsDriver: Driver<[ItemViewModel]> { - return searchTextRelay.throttle(1, scheduler: MainScheduler.instance) + return searchTextRelay.debounce(searchDebounceInterval, scheduler: MainScheduler.instance) .withLatestFrom(loadingResultObservable) { ($0, $1) } .flatMapLatest { [weak self] searchText, items -> Observable in self?.search(by: searchText, from: items).asObservable() ?? .empty() @@ -70,10 +74,6 @@ open class BaseSearchViewModel: GeneralDataLoadingViewModel return searchText.bind(to: searchTextRelay) } - open func onDidSelect(item: Item) { - // override in subclass - } - private func viewModels(from items: ItemsList) -> [ItemViewModel] { return items.map { self.viewModel(from: $0) } } @@ -82,14 +82,14 @@ open class BaseSearchViewModel: GeneralDataLoadingViewModel return loadingStateDriver .asObservable() .map { $0.result } - .filterNil() + .flatMap { Observable.from(optional: $0) } } open var loadingErrorObservable: Observable { return loadingStateDriver .asObservable() .map { $0.error } - .filterNil() + .flatMap { Observable.from(optional: $0) } } open var firstLoadingResultObservable: Single { diff --git a/iOS.playground/Contents.swift b/iOS.playground/Contents.swift index 2a779426..8b137891 100644 --- a/iOS.playground/Contents.swift +++ b/iOS.playground/Contents.swift @@ -1,3 +1 @@ -import LeadKit -let str = "Hello, LeadKit playground" From 6f8c4e2b67f357841f6823514d3b2fe621cd2063 Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 27 Mar 2019 14:32:15 +0300 Subject: [PATCH 31/36] More fixes --- Sources/Classes/Search/BaseSearchViewModel.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Classes/Search/BaseSearchViewModel.swift b/Sources/Classes/Search/BaseSearchViewModel.swift index b550fae7..6c2671e0 100644 --- a/Sources/Classes/Search/BaseSearchViewModel.swift +++ b/Sources/Classes/Search/BaseSearchViewModel.swift @@ -39,7 +39,7 @@ open class BaseSearchViewModel: GeneralDataLoadingViewModel .map { [weak self] items in self?.viewModels(from: items) } - .filterNil() + .flatMap { Observable.from(optional: $0) } .share(replay: 1, scope: .forever) .asDriver(onErrorDriveWith: .empty()) } @@ -57,7 +57,7 @@ open class BaseSearchViewModel: GeneralDataLoadingViewModel .map { [weak self] items in self?.viewModels(from: items) } - .filterNil() + .flatMap { Observable.from(optional: $0) } .share(replay: 1, scope: .forever) .asDriver(onErrorDriveWith: .empty()) } From 223be00d74a27b82002e7877c38b08c69b03b62f Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 28 Mar 2019 12:00:16 +0300 Subject: [PATCH 32/36] migrate to Swift 5; remove test targets --- .swift-version | 2 +- Cartfile | 6 +- Cartfile.resolved | 6 +- LeadKit.xcodeproj/project.pbxproj | 283 +----------------- .../xcschemes/LeadKit iOS.xcscheme | 2 +- .../xcschemes/LeadKit tvOS.xcscheme | 2 +- .../Drawing/UIImage/UIImage+Extensions.swift | 2 +- ...iewController+ConfigurableController.swift | 2 +- Tests/NetworkServiceTests.swift | 8 +- 9 files changed, 23 insertions(+), 290 deletions(-) diff --git a/.swift-version b/.swift-version index bf77d549..819e07a2 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -4.2 +5.0 diff --git a/Cartfile b/Cartfile index a662e7b8..bb5b1695 100644 --- a/Cartfile +++ b/Cartfile @@ -1,6 +1,6 @@ binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/SwiftDate/SwiftDate.json" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/Alamofire/Alamofire.json" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxAlamofire/RxAlamofire.json" -github "ReactiveX/RxSwift" -github "maxsokolov/TableKit" -github "pronebird/UIScrollView-InfiniteScroll" \ No newline at end of file +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/TableKit/TableKit.json" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxSwift/RxSwift.json" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/UIScrollView_InfiniteScroll/UIScrollView_InfiniteScroll.json" \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index c9c2dbe3..4eb0e7d4 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,6 +1,6 @@ binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/Alamofire/Alamofire.json" "4.8.1" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxAlamofire/RxAlamofire.json" "4.3.0" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxSwift/RxSwift.json" "4.4.2" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/SwiftDate/SwiftDate.json" "5.1.0" -github "ReactiveX/RxSwift" "4.4.2" -github "maxsokolov/TableKit" "2.8.1" -github "pronebird/UIScrollView-InfiniteScroll" "1.1.0" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/TableKit/TableKit.json" "2.10008.1" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/UIScrollView_InfiniteScroll/UIScrollView_InfiniteScroll.json" "1.1.0" diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 96f56f7f..c32798bd 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -182,25 +182,12 @@ 671463A51EB33FF600EAB194 /* Animatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463A11EB33FF600EAB194 /* Animatable.swift */; }; 671463A71EB340C000EAB194 /* UIViewController+ConfigurableController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463A61EB340C000EAB194 /* UIViewController+ConfigurableController.swift */; }; 671463A91EB340C000EAB194 /* UIViewController+ConfigurableController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463A61EB340C000EAB194 /* UIViewController+ConfigurableController.swift */; }; - 671463B81EB34B1E00EAB194 /* StubCursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463AE1EB34B1E00EAB194 /* StubCursor.swift */; }; - 671463BA1EB34B1E00EAB194 /* StubCursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463AE1EB34B1E00EAB194 /* StubCursor.swift */; }; - 671463BB1EB34B1E00EAB194 /* CursorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463AF1EB34B1E00EAB194 /* CursorTests.swift */; }; - 671463BD1EB34B1E00EAB194 /* CursorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463AF1EB34B1E00EAB194 /* CursorTests.swift */; }; - 671463BE1EB34B1E00EAB194 /* LoadFromNibTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463B01EB34B1E00EAB194 /* LoadFromNibTests.swift */; }; - 671463C01EB34B1E00EAB194 /* LoadFromNibTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463B01EB34B1E00EAB194 /* LoadFromNibTests.swift */; }; - 671463C41EB34B1E00EAB194 /* Post.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463B31EB34B1E00EAB194 /* Post.swift */; }; - 671463C61EB34B1E00EAB194 /* Post.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463B31EB34B1E00EAB194 /* Post.swift */; }; - 671463CA1EB34B1E00EAB194 /* TestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463B61EB34B1E00EAB194 /* TestView.swift */; }; - 671463CC1EB34B1E00EAB194 /* TestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671463B61EB34B1E00EAB194 /* TestView.swift */; }; - 671463CD1EB34B1E00EAB194 /* TestView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 671463B71EB34B1E00EAB194 /* TestView.xib */; }; - 671463CF1EB34B1E00EAB194 /* TestView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 671463B71EB34B1E00EAB194 /* TestView.xib */; }; 67153E3A207DFADA0049D8C0 /* RotateDrawingOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67153E39207DFADA0049D8C0 /* RotateDrawingOperation.swift */; }; 67153E3C207DFADA0049D8C0 /* RotateDrawingOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67153E39207DFADA0049D8C0 /* RotateDrawingOperation.swift */; }; 67153E3D207DFADA0049D8C0 /* RotateDrawingOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67153E39207DFADA0049D8C0 /* RotateDrawingOperation.swift */; }; 67153E40207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67153E3F207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift */; }; 67153E42207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67153E3F207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift */; }; 67153E43207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67153E3F207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift */; }; - 67186B311EB248F100CFAFFB /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67186B281EB248F100CFAFFB /* LeadKit.framework */; }; 67186B3F1EB24A1900CFAFFB /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 67186B201EB247A200CFAFFB /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 671AD26C206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; }; 671AD26E206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; }; @@ -353,7 +340,6 @@ 677B06C221187559006C947D /* ViewTextConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 677B06BE21187559006C947D /* ViewTextConfigurable.swift */; }; 677B06C4211884F3006C947D /* BaseTextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 677B06C3211884F3006C947D /* BaseTextAttributes.swift */; }; 677B06C7211884F3006C947D /* BaseTextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 677B06C3211884F3006C947D /* BaseTextAttributes.swift */; }; - 6782BBA91EB31D5A0086E0B8 /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6782BBA01EB31D590086E0B8 /* LeadKit.framework */; }; 678D267920691D8200B05B93 /* DataModelFieldBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D267820691D8200B05B93 /* DataModelFieldBinding.swift */; }; 678D267B20691D8200B05B93 /* DataModelFieldBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D267820691D8200B05B93 /* DataModelFieldBinding.swift */; }; 678D267C20691D8200B05B93 /* DataModelFieldBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D267820691D8200B05B93 /* DataModelFieldBinding.swift */; }; @@ -510,8 +496,6 @@ A676AE571F981130001F9214 /* ObservableMappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A676AE541F981121001F9214 /* ObservableMappable.swift */; }; A676AE581F981131001F9214 /* ObservableMappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A676AE541F981121001F9214 /* ObservableMappable.swift */; }; A6C9A4FA1F8BBCF2009311CC /* EmptyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6AF3B371F8B956F00CDB971 /* EmptyCell.swift */; }; - A6C9A5051F8BC78F009311CC /* SeparatorConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E0DDF01F8A6C80002CA74E /* SeparatorConfiguration.swift */; }; - A6C9A50F1F8BC79D009311CC /* Comparable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D10EAA1F8A9278003E69DD /* Comparable+Extensions.swift */; }; A6D10EAB1F8A9278003E69DD /* Comparable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D10EAA1F8A9278003E69DD /* Comparable+Extensions.swift */; }; A6E0DDDE1F8A696F002CA74E /* EmptyCellRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A71F8A654600C6308D /* EmptyCellRow.swift */; }; A6E0DDDF1F8A696F002CA74E /* SeparatorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A61F8A653600C6308D /* SeparatorCell.swift */; }; @@ -520,8 +504,6 @@ A6F32C081F6EBDAA00AC08EE /* String+LocalizedComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C071F6EBDAA00AC08EE /* String+LocalizedComponent.swift */; }; A6F32C0B1F6EBE5C00AC08EE /* String+LocalizedComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C071F6EBDAA00AC08EE /* String+LocalizedComponent.swift */; }; A6F32C0C1F6EBE5C00AC08EE /* String+LocalizedComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C071F6EBDAA00AC08EE /* String+LocalizedComponent.swift */; }; - A6F32C101F6EBE9600AC08EE /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C0E1F6EBE8E00AC08EE /* StringExtensionTests.swift */; }; - A6F32C121F6EBE9800AC08EE /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6F32C0E1F6EBE8E00AC08EE /* StringExtensionTests.swift */; }; B84CB06A20B702240090DB91 /* Encodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */; }; B84CB06B20B702260090DB91 /* Encodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */; }; B84CB06D20B8325D0090DB91 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB06C20B8325D0090DB91 /* SessionManager.swift */; }; @@ -530,15 +512,7 @@ B84CB07820B872AD0090DB91 /* Decodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB07720B872AD0090DB91 /* Decodable+Extensions.swift */; }; B84CB07A20B872AD0090DB91 /* Decodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB07720B872AD0090DB91 /* Decodable+Extensions.swift */; }; B84CB07B20B872AD0090DB91 /* Decodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84CB07720B872AD0090DB91 /* Decodable+Extensions.swift */; }; - B84D64B120A70B7000DD76DA /* NetworkServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84D64B020A70B7000DD76DA /* NetworkServiceTests.swift */; }; - B84D64B320A70B7000DD76DA /* NetworkServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84D64B020A70B7000DD76DA /* NetworkServiceTests.swift */; }; - B85B766820AC4EC600F837C4 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B766620AC4EA300F837C4 /* Album.swift */; }; - B85B766A20AC4EC700F837C4 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B766620AC4EA300F837C4 /* Album.swift */; }; - B85B766D20AC51C600F837C4 /* AlbumsContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B766B20AC51BE00F837C4 /* AlbumsContainer.swift */; }; - B85B766F20AC51C700F837C4 /* AlbumsContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B766B20AC51BE00F837C4 /* AlbumsContainer.swift */; }; B85B768720B1CF6700F837C4 /* Encodable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85B768620B1CF6700F837C4 /* Encodable+Extensions.swift */; }; - D93221EE20A44896003799D5 /* Double+RoundingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93221ED20A44896003799D5 /* Double+RoundingTests.swift */; }; - D93221F020A44896003799D5 /* Double+RoundingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93221ED20A44896003799D5 /* Double+RoundingTests.swift */; }; EF24213A2076D5BD00FA9BE6 /* NetworkServiceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF2421392076D5BD00FA9BE6 /* NetworkServiceConfiguration.swift */; }; EF24213C2076D5C900FA9BE6 /* NetworkServiceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF2421392076D5BD00FA9BE6 /* NetworkServiceConfiguration.swift */; }; EF24213D2076D5CA00FA9BE6 /* NetworkServiceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF2421392076D5BD00FA9BE6 /* NetworkServiceConfiguration.swift */; }; @@ -549,23 +523,6 @@ EFBE57DE1EC361620040E00A /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57DA1EC361620040E00A /* UIView+Layout.swift */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 67186B321EB248F100CFAFFB /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78CFEE211C5C456B00F50370 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 67186B271EB248F100CFAFFB; - remoteInfo = "LeadKit iOS"; - }; - 6782BBAA1EB31D5A0086E0B8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78CFEE211C5C456B00F50370 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6782BB9F1EB31D590086E0B8; - remoteInfo = "LeadKit tvOS"; - }; -/* End PBXContainerItemProxy section */ - /* Begin PBXFileReference section */ 36DAAF502007CC920090BE0D /* UITableView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+Extensions.swift"; sourceTree = ""; }; 36FE776F20F669E300284C09 /* String+ConvertToHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ConvertToHost.swift"; sourceTree = ""; }; @@ -644,7 +601,6 @@ 67153E3F207DFBA80049D8C0 /* FloatingPoint+DegreesRadiansConvertion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FloatingPoint+DegreesRadiansConvertion.swift"; sourceTree = ""; }; 67186B201EB247A200CFAFFB /* LeadKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LeadKit.h; sourceTree = ""; }; 67186B281EB248F100CFAFFB /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 67186B301EB248F100CFAFFB /* LeadKit iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LeadKit iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 67186B411EB24AA000CFAFFB /* iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = iOS.playground; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 67186C1A1EB24B7800CFAFFB /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+TotalCountCursorListingResult.swift"; sourceTree = ""; }; @@ -708,7 +664,6 @@ 677B06C3211884F3006C947D /* BaseTextAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTextAttributes.swift; sourceTree = ""; }; 6782BB911EB31CFE0086E0B8 /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6782BBA01EB31D590086E0B8 /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 6782BBA81EB31D5A0086E0B8 /* LeadKit tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LeadKit tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 6782BBB91EB31DD90086E0B8 /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; 678D267820691D8200B05B93 /* DataModelFieldBinding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataModelFieldBinding.swift; sourceTree = ""; }; 678D269E20692BFF00B05B93 /* TextFieldViewEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldViewEvents.swift; sourceTree = ""; }; @@ -830,14 +785,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 67186B2D1EB248F100CFAFFB /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 67186B311EB248F100CFAFFB /* LeadKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 6782BB8D1EB31CFE0086E0B8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -863,14 +810,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6782BBA51EB31D5A0086E0B8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6782BBA91EB31D5A0086E0B8 /* LeadKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -1981,10 +1920,8 @@ isa = PBXGroup; children = ( 67186B281EB248F100CFAFFB /* LeadKit.framework */, - 67186B301EB248F100CFAFFB /* LeadKit iOSTests.xctest */, 6782BB911EB31CFE0086E0B8 /* LeadKit.framework */, 6782BBA01EB31D590086E0B8 /* LeadKit.framework */, - 6782BBA81EB31D5A0086E0B8 /* LeadKit tvOSTests.xctest */, ); name = Products; sourceTree = ""; @@ -2135,24 +2072,6 @@ productReference = 67186B281EB248F100CFAFFB /* LeadKit.framework */; productType = "com.apple.product-type.framework"; }; - 67186B2F1EB248F100CFAFFB /* LeadKit iOSTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 67186B3C1EB248F100CFAFFB /* Build configuration list for PBXNativeTarget "LeadKit iOSTests" */; - buildPhases = ( - 67186B2C1EB248F100CFAFFB /* Sources */, - 67186B2D1EB248F100CFAFFB /* Frameworks */, - 67186B2E1EB248F100CFAFFB /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 67186B331EB248F100CFAFFB /* PBXTargetDependency */, - ); - name = "LeadKit iOSTests"; - productName = "LeadKit iOSTests"; - productReference = 67186B301EB248F100CFAFFB /* LeadKit iOSTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; 6782BB901EB31CFE0086E0B8 /* LeadKit watchOS */ = { isa = PBXNativeTarget; buildConfigurationList = 6782BB961EB31CFE0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit watchOS" */; @@ -2193,24 +2112,6 @@ productReference = 6782BBA01EB31D590086E0B8 /* LeadKit.framework */; productType = "com.apple.product-type.framework"; }; - 6782BBA71EB31D5A0086E0B8 /* LeadKit tvOSTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6782BBB41EB31D5A0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit tvOSTests" */; - buildPhases = ( - 6782BBA41EB31D5A0086E0B8 /* Sources */, - 6782BBA51EB31D5A0086E0B8 /* Frameworks */, - 6782BBA61EB31D5A0086E0B8 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 6782BBAB1EB31D5A0086E0B8 /* PBXTargetDependency */, - ); - name = "LeadKit tvOSTests"; - productName = "LeadKit tvOSTests"; - productReference = 6782BBA81EB31D5A0086E0B8 /* LeadKit tvOSTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -2218,19 +2119,13 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0830; - LastUpgradeCheck = 0930; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "Touch Instinct"; TargetAttributes = { 67186B271EB248F100CFAFFB = { CreatedOnToolsVersion = 8.3; DevelopmentTeam = D4HA43V467; - LastSwiftMigration = 1000; - ProvisioningStyle = Automatic; - }; - 67186B2F1EB248F100CFAFFB = { - CreatedOnToolsVersion = 8.3; - DevelopmentTeam = D4HA43V467; - LastSwiftMigration = 1000; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; 6782BB901EB31CFE0086E0B8 = { @@ -2245,20 +2140,15 @@ LastSwiftMigration = 1000; ProvisioningStyle = Automatic; }; - 6782BBA71EB31D5A0086E0B8 = { - CreatedOnToolsVersion = 8.3; - DevelopmentTeam = D4HA43V467; - LastSwiftMigration = 1000; - ProvisioningStyle = Automatic; - }; }; }; buildConfigurationList = 78CFEE241C5C456B00F50370 /* Build configuration list for PBXProject "LeadKit" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 78CFEE201C5C456B00F50370; productRefGroup = 78CFEE2B1C5C456B00F50370 /* Products */; @@ -2266,10 +2156,8 @@ projectRoot = ""; targets = ( 67186B271EB248F100CFAFFB /* LeadKit iOS */, - 67186B2F1EB248F100CFAFFB /* LeadKit iOSTests */, 6782BB901EB31CFE0086E0B8 /* LeadKit watchOS */, 6782BB9F1EB31D590086E0B8 /* LeadKit tvOS */, - 6782BBA71EB31D5A0086E0B8 /* LeadKit tvOSTests */, ); }; /* End PBXProject section */ @@ -2282,14 +2170,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 67186B2E1EB248F100CFAFFB /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 671463CD1EB34B1E00EAB194 /* TestView.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 6782BB8F1EB31CFE0086E0B8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2304,14 +2184,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6782BBA61EB31D5A0086E0B8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 671463CF1EB34B1E00EAB194 /* TestView.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -2608,25 +2480,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 67186B2C1EB248F100CFAFFB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A6C9A5051F8BC78F009311CC /* SeparatorConfiguration.swift in Sources */, - D93221EE20A44896003799D5 /* Double+RoundingTests.swift in Sources */, - 671463CA1EB34B1E00EAB194 /* TestView.swift in Sources */, - 671463B81EB34B1E00EAB194 /* StubCursor.swift in Sources */, - B85B766D20AC51C600F837C4 /* AlbumsContainer.swift in Sources */, - 671463BB1EB34B1E00EAB194 /* CursorTests.swift in Sources */, - A6F32C101F6EBE9600AC08EE /* StringExtensionTests.swift in Sources */, - 671463BE1EB34B1E00EAB194 /* LoadFromNibTests.swift in Sources */, - A6C9A50F1F8BC79D009311CC /* Comparable+Extensions.swift in Sources */, - B85B766820AC4EC600F837C4 /* Album.swift in Sources */, - 671463C41EB34B1E00EAB194 /* Post.swift in Sources */, - B84D64B120A70B7000DD76DA /* NetworkServiceTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 6782BB8C1EB31CFE0086E0B8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2934,38 +2787,8 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6782BBA41EB31D5A0086E0B8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B85B766F20AC51C700F837C4 /* AlbumsContainer.swift in Sources */, - 671463CC1EB34B1E00EAB194 /* TestView.swift in Sources */, - B84D64B320A70B7000DD76DA /* NetworkServiceTests.swift in Sources */, - 671463BA1EB34B1E00EAB194 /* StubCursor.swift in Sources */, - 671463BD1EB34B1E00EAB194 /* CursorTests.swift in Sources */, - B85B766A20AC4EC700F837C4 /* Album.swift in Sources */, - A6F32C121F6EBE9800AC08EE /* StringExtensionTests.swift in Sources */, - D93221F020A44896003799D5 /* Double+RoundingTests.swift in Sources */, - 671463C01EB34B1E00EAB194 /* LoadFromNibTests.swift in Sources */, - 671463C61EB34B1E00EAB194 /* Post.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 67186B331EB248F100CFAFFB /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 67186B271EB248F100CFAFFB /* LeadKit iOS */; - targetProxy = 67186B321EB248F100CFAFFB /* PBXContainerItemProxy */; - }; - 6782BBAB1EB31D5A0086E0B8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 6782BB9F1EB31D590086E0B8 /* LeadKit tvOS */; - targetProxy = 6782BBAA1EB31D5A0086E0B8 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin XCBuildConfiguration section */ 67186B3A1EB248F100CFAFFB /* Debug */ = { isa = XCBuildConfiguration; @@ -2993,7 +2816,7 @@ PRODUCT_NAME = LeadKit; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -3022,43 +2845,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-iOS"; PRODUCT_NAME = LeadKit; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; - }; - name = Release; - }; - 67186B3D1EB248F100CFAFFB /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - DEVELOPMENT_TEAM = D4HA43V467; - INFOPLIST_FILE = "Tests/Info-iOS.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-iOSTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; - }; - name = Debug; - }; - 67186B3E1EB248F100CFAFFB /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - DEVELOPMENT_TEAM = D4HA43V467; - INFOPLIST_FILE = "Tests/Info-iOS.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-iOSTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -3186,48 +2973,11 @@ }; name = Release; }; - 6782BBB51EB31D5A0086E0B8 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - DEVELOPMENT_TEAM = D4HA43V467; - INFOPLIST_FILE = "Tests/Info-tvOS.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-tvOSTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; - TVOS_DEPLOYMENT_TARGET = 10.2; - }; - name = Debug; - }; - 6782BBB61EB31D5A0086E0B8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - DEVELOPMENT_TEAM = D4HA43V467; - INFOPLIST_FILE = "Tests/Info-tvOS.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-tvOSTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - SWIFT_VERSION = 4.2; - TVOS_DEPLOYMENT_TARGET = 10.2; - }; - name = Release; - }; 78CFEE3C1C5C456B00F50370 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -3286,6 +3036,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -3346,15 +3097,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 67186B3C1EB248F100CFAFFB /* Build configuration list for PBXNativeTarget "LeadKit iOSTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 67186B3D1EB248F100CFAFFB /* Debug */, - 67186B3E1EB248F100CFAFFB /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 6782BB961EB31CFE0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit watchOS" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3373,15 +3115,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6782BBB41EB31D5A0086E0B8 /* Build configuration list for PBXNativeTarget "LeadKit tvOSTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6782BBB51EB31D5A0086E0B8 /* Debug */, - 6782BBB61EB31D5A0086E0B8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 78CFEE241C5C456B00F50370 /* Build configuration list for PBXProject "LeadKit" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/LeadKit.xcodeproj/xcshareddata/xcschemes/LeadKit iOS.xcscheme b/LeadKit.xcodeproj/xcshareddata/xcschemes/LeadKit iOS.xcscheme index 879a6705..4e71a311 100644 --- a/LeadKit.xcodeproj/xcshareddata/xcschemes/LeadKit iOS.xcscheme +++ b/LeadKit.xcodeproj/xcshareddata/xcschemes/LeadKit iOS.xcscheme @@ -1,6 +1,6 @@ UIImage { let ctxSize = contextSize diff --git a/Sources/Extensions/UIKit/UIViewController/UIViewController+ConfigurableController.swift b/Sources/Extensions/UIKit/UIViewController/UIViewController+ConfigurableController.swift index 1384e2fd..5ba82451 100644 --- a/Sources/Extensions/UIKit/UIViewController/UIViewController+ConfigurableController.swift +++ b/Sources/Extensions/UIKit/UIViewController/UIViewController+ConfigurableController.swift @@ -25,7 +25,7 @@ import UIKit.UIViewController public extension ConfigurableController where Self: UIViewController { func initializeView() { - assertionFailure("Use \(initialLoadView) for UIViewController instead!") + assertionFailure("Use \(String(describing: initialLoadView)) for UIViewController instead!") } /// Method that should be called in viewDidLoad method of UIViewController. diff --git a/Tests/NetworkServiceTests.swift b/Tests/NetworkServiceTests.swift index c310fffe..94a76dba 100644 --- a/Tests/NetworkServiceTests.swift +++ b/Tests/NetworkServiceTests.swift @@ -54,7 +54,7 @@ final class NetworkServiceTests: XCTestCase { var receivedModel: Album? var error: Error? let requestCompletedExpectation = expectation(description: "Request completed") - let apiRequest = ApiRequestParameters(url: networkService.configuration.baseUrl + "/albums/1") + let apiRequest = ApiRequestParameters(url: networkService.configuration.baseUrl + "/albums/1", parameters: [:]) // when networkService.rxRequest(with: apiRequest) @@ -80,7 +80,7 @@ final class NetworkServiceTests: XCTestCase { var response: [Album]? var error: Error? let requestCompletedExpectation = expectation(description: "Request completed") - let apiRequest = ApiRequestParameters(url: networkService.configuration.baseUrl + "/albums") + let apiRequest = ApiRequestParameters(url: networkService.configuration.baseUrl + "/albums", parameters: [:]) //when networkService.rxRequest(with: apiRequest) @@ -110,7 +110,7 @@ final class NetworkServiceTests: XCTestCase { var receivedModel: Album? var error: Error? let requestCompletedExpectation = expectation(description: "Request completed") - let apiRequest = ApiRequestParameters(url: networkService.configuration.baseUrl + "/albums/1") + let apiRequest = ApiRequestParameters(url: networkService.configuration.baseUrl + "/albums/1", parameters: [:]) // when networkService.rxObservableRequest(with: apiRequest) @@ -136,7 +136,7 @@ final class NetworkServiceTests: XCTestCase { var receivedModel: AlbumContainer? var error: Error? let requestCompletedExpectation = expectation(description: "Request completed") - let apiRequest = ApiRequestParameters(url: networkService.configuration.baseUrl + "/albums") + let apiRequest = ApiRequestParameters(url: networkService.configuration.baseUrl + "/albums", parameters: [:]) // when networkService.rxObservableRequest(with: apiRequest) From 3be1d793a2a57ff557aa3c814f9e18dd0396ec65 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 28 Mar 2019 12:02:43 +0300 Subject: [PATCH 33/36] update changelog and podspec version --- CHANGELOG.md | 3 +++ LeadKit.podspec | 2 +- Sources/Info-iOS.plist | 2 +- Sources/Info-tvOS.plist | 2 +- Sources/Info-watchOS.plist | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb7ec37b..434a94b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +### 0.9.12 +- **Update**: Swift 5 support + ### 0.9.11 - **[Breaking change]**: Renamed `NumberFormat`'s `allOptions` to `allCases` - **Fix**: Closure syntax fix. New closure naming. diff --git a/LeadKit.podspec b/LeadKit.podspec index b9217b30..171580c3 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.9.11" + s.version = "0.9.12" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/Sources/Info-iOS.plist b/Sources/Info-iOS.plist index 968be549..c3778cb9 100644 --- a/Sources/Info-iOS.plist +++ b/Sources/Info-iOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.11 + 0.9.12 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist index 968be549..c3778cb9 100644 --- a/Sources/Info-tvOS.plist +++ b/Sources/Info-tvOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.11 + 0.9.12 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist index 968be549..c3778cb9 100644 --- a/Sources/Info-watchOS.plist +++ b/Sources/Info-watchOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.11 + 0.9.12 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass From e4e5dcfa30c28babe1542792e59b36b661bcae32 Mon Sep 17 00:00:00 2001 From: Ivan Babkin Date: Fri, 29 Mar 2019 20:01:48 +0300 Subject: [PATCH 34/36] Fixed LeadKit.xcodeproj --- LeadKit.xcodeproj/project.pbxproj | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index c32798bd..8957c4d8 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -484,6 +484,12 @@ 82B4F8DC223903B800F6708C /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B4F8DA223903B800F6708C /* Block.swift */; }; 82B4F8DD223903B800F6708C /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B4F8DA223903B800F6708C /* Block.swift */; }; 82F8BB181F5DDED100C1061B /* Single+DeferredJust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F8BB171F5DDED100C1061B /* Single+DeferredJust.swift */; }; + 8546C2E3224E86280059C255 /* ApiUploadRequestParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8546C2E2224E86280059C255 /* ApiUploadRequestParameters.swift */; }; + 8546C2E4224E86280059C255 /* ApiUploadRequestParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8546C2E2224E86280059C255 /* ApiUploadRequestParameters.swift */; }; + 8546C2E5224E86280059C255 /* ApiUploadRequestParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8546C2E2224E86280059C255 /* ApiUploadRequestParameters.swift */; }; + 8546C2E8224E864F0059C255 /* Error+NetworkExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8546C2E7224E864F0059C255 /* Error+NetworkExtensions.swift */; }; + 8546C2E9224E864F0059C255 /* Error+NetworkExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8546C2E7224E864F0059C255 /* Error+NetworkExtensions.swift */; }; + 8546C2EA224E864F0059C255 /* Error+NetworkExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8546C2E7224E864F0059C255 /* Error+NetworkExtensions.swift */; }; A658E54D1F8CD7790093527A /* TableRow+SeparatorsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A658E54C1F8CD7790093527A /* TableRow+SeparatorsExtensions.swift */; }; A658E5501F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A658E54F1F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift */; }; A676AE481F97D28A001F9214 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A676AE471F97D28A001F9214 /* String+Extensions.swift */; }; @@ -744,6 +750,8 @@ 825F8F2720B3384C00594857 /* PaginationWrapperUIDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationWrapperUIDelegate.swift; sourceTree = ""; }; 82B4F8DA223903B800F6708C /* Block.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Block.swift; sourceTree = ""; }; 82F8BB171F5DDED100C1061B /* Single+DeferredJust.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Single+DeferredJust.swift"; sourceTree = ""; }; + 8546C2E2224E86280059C255 /* ApiUploadRequestParameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiUploadRequestParameters.swift; sourceTree = ""; }; + 8546C2E7224E864F0059C255 /* Error+NetworkExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Error+NetworkExtensions.swift"; sourceTree = ""; }; A658E54C1F8CD7790093527A /* TableRow+SeparatorsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TableRow+SeparatorsExtensions.swift"; sourceTree = ""; }; A658E54F1F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+SeparatorRowBoxExtensions.swift"; sourceTree = ""; }; A66428A61F8A653600C6308D /* SeparatorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorCell.swift; sourceTree = ""; }; @@ -908,6 +916,7 @@ 6771DFE81EEA7C8F002DCDAE /* DateFormattingService */, 671461EA1EB3396E00EAB194 /* Double */, 672947E2206EA59E00AC6B6B /* Drawing */, + 8546C2E6224E864F0059C255 /* Error */, 67153E3E207DFB980049D8C0 /* FloatingPoint */, 676B22A0206A6249002E9F8A /* NSAttributedString */, 673564EF2068C29100F0CBED /* NumberFormattingService */, @@ -1137,6 +1146,7 @@ isa = PBXGroup; children = ( 671462371EB3396E00EAB194 /* ApiRequestParameters.swift */, + 8546C2E2224E86280059C255 /* ApiUploadRequestParameters.swift */, ); path = Api; sourceTree = ""; @@ -1935,6 +1945,14 @@ path = Single; sourceTree = ""; }; + 8546C2E6224E864F0059C255 /* Error */ = { + isa = PBXGroup; + children = ( + 8546C2E7224E864F0059C255 /* Error+NetworkExtensions.swift */, + ); + path = Error; + sourceTree = ""; + }; A66428A41F8A651700C6308D /* SeparatorCell */ = { isa = PBXGroup; children = ( @@ -2364,6 +2382,7 @@ 67E902512125B064008EDF45 /* BuildInNumberTypes+NSNumberConvertible.swift in Sources */, A676AE551F98112E001F9214 /* ObservableMappable.swift in Sources */, 6741CEA520E2418200FEC4D9 /* TableViewHolder.swift in Sources */, + 8546C2E3224E86280059C255 /* ApiUploadRequestParameters.swift in Sources */, A6E0DDE11F8A696F002CA74E /* SeparatorRowBox.swift in Sources */, A6E0DDDE1F8A696F002CA74E /* EmptyCellRow.swift in Sources */, 6762131820A0BBA30034EEF1 /* TableSection+Extensions.swift in Sources */, @@ -2467,6 +2486,7 @@ 67EB7FD420615D1700BDD9FB /* ResettableCursorType.swift in Sources */, 6741CEA120E2416C00FEC4D9 /* ScrollViewHolder.swift in Sources */, 6714629C1EB3396E00EAB194 /* CursorType+Slice.swift in Sources */, + 8546C2E8224E864F0059C255 /* Error+NetworkExtensions.swift in Sources */, 6774529F20625EEE0024EEEF /* PaginationDataLoadingModel.swift in Sources */, 678D267920691D8200B05B93 /* DataModelFieldBinding.swift in Sources */, 673CF4342063E29B00C329F6 /* TextWithButtonPlaceholder.swift in Sources */, @@ -2518,6 +2538,7 @@ 6741C41120EAC88800418D08 /* GeneralDataLoadingViewModel+Extensions.swift in Sources */, 671463861EB3396E00EAB194 /* ResizeDrawingOperation.swift in Sources */, 671463921EB3396E00EAB194 /* TemplateDrawingOperation.swift in Sources */, + 8546C2E4224E86280059C255 /* ApiUploadRequestParameters.swift in Sources */, 67745282206256A20024EEEF /* RxDataLoadingModel.swift in Sources */, 6714629A1EB3396E00EAB194 /* CGSize+Resize.swift in Sources */, 671463321EB3396E00EAB194 /* CursorType.swift in Sources */, @@ -2595,6 +2616,7 @@ 6714638E1EB3396E00EAB194 /* SolidFillDrawingOperation.swift in Sources */, 6774529420625D170024EEEF /* GeneralDataLoadingModel.swift in Sources */, 67FDC2611FA310EA00C76A77 /* RequestError.swift in Sources */, + 8546C2E9224E864F0059C255 /* Error+NetworkExtensions.swift in Sources */, 671462521EB3396E00EAB194 /* StaticCursor.swift in Sources */, 67ED2BE720B44F4300508B3E /* InitializableView+DefaultImplementation.swift in Sources */, 6714629E1EB3396E00EAB194 /* CursorType+Slice.swift in Sources */, @@ -2760,6 +2782,7 @@ 6774529520625D170024EEEF /* GeneralDataLoadingModel.swift in Sources */, 6713C23A20AF0C4D00875921 /* NetworkOperationState.swift in Sources */, 6774529D20625E5B0024EEEF /* PaginationDataLoadingState.swift in Sources */, + 8546C2E5224E86280059C255 /* ApiUploadRequestParameters.swift in Sources */, 6732F245214C189100B446F2 /* Single+DeferredJust.swift in Sources */, 6714632F1EB3396E00EAB194 /* ConfigurableController.swift in Sources */, 67990ACD213EA5B70040D195 /* ContentLoadingViewModel.swift in Sources */, @@ -2778,6 +2801,7 @@ 6714638F1EB3396E00EAB194 /* SolidFillDrawingOperation.swift in Sources */, 677B06A321186A69006C947D /* SharedSequence+Extensions.swift in Sources */, 67E6C2381EBB32F5007842A6 /* SingleLoadCursor.swift in Sources */, + 8546C2EA224E864F0059C255 /* Error+NetworkExtensions.swift in Sources */, 67C7B17C2068BB1C00C9EDA3 /* NumberFormattingService.swift in Sources */, 671462531EB3396E00EAB194 /* StaticCursor.swift in Sources */, 67E352502119ABE40035BDDB /* UITextField+ViewTextConfigurable.swift in Sources */, From 287955fdba141004a057fc445199b1522fb6501a Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Mon, 1 Apr 2019 11:55:50 +0300 Subject: [PATCH 35/36] update SwiftDate (~> 6) --- CHANGELOG.md | 3 +++ Cartfile.resolved | 2 +- LeadKit.podspec | 4 ++-- Sources/Info-iOS.plist | 2 +- Sources/Info-tvOS.plist | 2 +- Sources/Info-watchOS.plist | 2 +- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0be799d5..fff8b059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +### 0.9.14 +- **Update**: SwiftDate dependency (~> 6). + ### 0.9.13 - **Add**: `ApiUploadRequestParameters` struct that defines upload data request parameters. - **Add**: `rxUploadRequest` method to `NetworkService` class that performs reactive request to upload data. diff --git a/Cartfile.resolved b/Cartfile.resolved index 4eb0e7d4..a22b45ff 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,6 +1,6 @@ binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/Alamofire/Alamofire.json" "4.8.1" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxAlamofire/RxAlamofire.json" "4.3.0" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/RxSwift/RxSwift.json" "4.4.2" -binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/SwiftDate/SwiftDate.json" "5.1.0" +binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/SwiftDate/SwiftDate.json" "6.0.1" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/TableKit/TableKit.json" "2.10008.1" binary "https://raw.github.com/TouchInstinct/CarthageBinaries/master/UIScrollView_InfiniteScroll/UIScrollView_InfiniteScroll.json" "1.1.0" diff --git a/LeadKit.podspec b/LeadKit.podspec index 9bbbca60..c0e2d3bb 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.9.13" + s.version = "0.9.14" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" @@ -86,7 +86,7 @@ Pod::Spec.new do |s| ss.dependency "RxSwift", '~> 4' ss.dependency "RxCocoa", '~> 4' ss.dependency "RxAlamofire", '~> 4' - ss.dependency "SwiftDate", '~> 5.1' + ss.dependency "SwiftDate", '~> 6' ss.ios.dependency "TableKit", '~> 2.8' ss.ios.dependency "UIScrollView-InfiniteScroll", '~> 1.1.0' diff --git a/Sources/Info-iOS.plist b/Sources/Info-iOS.plist index 79b226a4..38e95826 100644 --- a/Sources/Info-iOS.plist +++ b/Sources/Info-iOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.13 + 0.9.14 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist index 79b226a4..38e95826 100644 --- a/Sources/Info-tvOS.plist +++ b/Sources/Info-tvOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.13 + 0.9.14 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist index 79b226a4..38e95826 100644 --- a/Sources/Info-watchOS.plist +++ b/Sources/Info-watchOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.13 + 0.9.14 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass From 2d4beef7f08f7201978bea3af8aab7e85023297c Mon Sep 17 00:00:00 2001 From: Artur Date: Tue, 9 Apr 2019 16:01:18 +0300 Subject: [PATCH 36/36] Changelog and podspec fixed --- CHANGELOG.md | 9 +-------- LeadKit.podspec | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 712f1c4a..ae8103ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,10 @@ # Changelog -### 0.9.9 +### 0.9.15 - **Add**: `BaseSearchViewController` class that that allows to enter text for search and then displays search results in table view. - **Add**: `BaseSearchViewModel` class that loads data from a given data source and performs search among the results. - **Add**: `SearchResultsController` protocol that represent a controller able to display search results. - **Add**: `SearchResultsControllerState` enum that represents `SearchResultsController` state. -### 0.9.8 -- **Add**: `rxDataRequest` method to `NetworkService` class, that performs reactive request to get data and http response. -- **Add**: `responseData` method to `SessionManager` extension, that executes request and returns data. - -### 0.9.7 -- **Add**: Carthage support. - ### 0.9.14 - **Update**: SwiftDate dependency (~> 6). diff --git a/LeadKit.podspec b/LeadKit.podspec index b3eb7fd1..909fde5d 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.9.14" + s.version = "0.9.15" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0"