From 532e54fe9efb5a4cab8a3be45637fcb0b96c35d4 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 14 Apr 2022 15:04:59 +0300 Subject: [PATCH] feat: Network services in TIMoyaNetworking now passes MoyaError in result of EnpointRequest execution. feat: TINetworkingCache module - caching results of EndpointRequests. --- CHANGELOG.md | 6 ++ LeadKit.podspec | 2 +- Package.resolved | 9 +++ Package.swift | 6 ++ TIFoundationUtils/TIFoundationUtils.podspec | 2 +- TIKeychainUtils/TIKeychainUtils.podspec | 2 +- .../DefaultJsonNetworkService.swift | 17 ++-- .../NetworkService/EndpointErrorResult.swift | 43 ++++++++++ .../EndpointRequestResult.swift | 23 ++++++ ...DefaultRecoverableJsonNetworkService.swift | 27 +++---- TIMoyaNetworking/TIMoyaNetworking.podspec | 2 +- .../Sources/Request/SerializedRequest.swift | 30 +++++++ TINetworking/TINetworking.podspec | 2 +- .../Sources/EndpointCacheService.swift | 81 +++++++++++++++++++ TINetworkingCache/TINetworkingCache.podspec | 18 +++++ TISwiftUtils/TISwiftUtils.podspec | 2 +- .../TableSection+Extensions.swift | 1 + TITableKitUtils/TITableKitUtils.podspec | 2 +- TITransitions/TITransitions.podspec | 2 +- TIUIElements/TIUIElements.podspec | 2 +- TIUIKitCore/TIUIKitCore.podspec | 2 +- project-scripts/push_to_podspecs.sh | 1 + 22 files changed, 249 insertions(+), 33 deletions(-) create mode 100644 TIMoyaNetworking/Sources/NetworkService/EndpointErrorResult.swift create mode 100644 TIMoyaNetworking/Sources/NetworkService/EndpointRequestResult.swift create mode 100644 TINetworkingCache/Sources/EndpointCacheService.swift create mode 100644 TINetworkingCache/TINetworkingCache.podspec diff --git a/CHANGELOG.md b/CHANGELOG.md index acc78d25..44a43fe3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### 1.15.0 + +- **Update**: Network services in TIMoyaNetworking now passes MoyaError in result of EnpointRequest execution. +- **Add**: `TINetworkingCache` module - caching results of EndpointRequests. +- **Important Note**: `TINetworkingCache` may require you to add `DISABLE_DIAMOND_PROBLEM_DIAGNOSTIC=YES` flag to build settings of project target (see [probably related problem](https://forums.swift.org/t/adding-a-package-to-two-targets-in-one-projects-results-in-an-error/35007/18)) + ### 1.14.3 - **Fix**: Creating headerView and footerView when initializing a section with rows in `TITableKitUtils`. diff --git a/LeadKit.podspec b/LeadKit.podspec index dcd2c437..df247480 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "1.14.3" + s.version = "1.15.0" 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/Package.resolved b/Package.resolved index 6ce42b93..64252c9e 100644 --- a/Package.resolved +++ b/Package.resolved @@ -10,6 +10,15 @@ "version": "5.4.3" } }, + { + "package": "Cache", + "repositoryURL": "https://github.com/hyperoslo/Cache.git", + "state": { + "branch": null, + "revision": "c7f4d633049c3bd649a353bad36f6c17e9df085f", + "version": "6.0.0" + } + }, { "package": "Cursors", "repositoryURL": "https://github.com/petropavel13/Cursors", diff --git a/Package.swift b/Package.swift index 5536e3bc..c824c208 100644 --- a/Package.swift +++ b/Package.swift @@ -17,8 +17,12 @@ let package = Package( .library(name: "TIFoundationUtils", targets: ["TIFoundationUtils"]), .library(name: "TIKeychainUtils", targets: ["TIKeychainUtils"]), .library(name: "TITableKitUtils", targets: ["TITableKitUtils"]), + + // MARK: - Networking + .library(name: "TINetworking", targets: ["TINetworking"]), .library(name: "TIMoyaNetworking", targets: ["TIMoyaNetworking"]), + .library(name: "TINetworkingCache", targets: ["TINetworkingCache"]), // MARK: - Elements .library(name: "OTPSwiftView", targets: ["OTPSwiftView"]), @@ -31,6 +35,7 @@ let package = Package( .package(url: "https://github.com/petropavel13/Cursors", .upToNextMajor(from: "0.5.1")), .package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.4.0")), .package(url: "https://github.com/Moya/Moya.git", .upToNextMajor(from: "15.0.0")), + .package(url: "https://github.com/hyperoslo/Cache.git", .upToNextMajor(from: "6.0.0")) ], targets: [ @@ -48,6 +53,7 @@ let package = Package( .target(name: "TINetworking", dependencies: ["TISwiftUtils", "Alamofire"], path: "TINetworking/Sources"), .target(name: "TIMoyaNetworking", dependencies: ["TINetworking", "TIFoundationUtils", "Moya"], path: "TIMoyaNetworking"), + .target(name: "TINetworkingCache", dependencies: ["TIFoundationUtils", "TINetworking", "Cache"], path: "TINetworkingCache/Sources"), // MARK: - Elements diff --git a/TIFoundationUtils/TIFoundationUtils.podspec b/TIFoundationUtils/TIFoundationUtils.podspec index 7fd15c61..8c9859aa 100644 --- a/TIFoundationUtils/TIFoundationUtils.podspec +++ b/TIFoundationUtils/TIFoundationUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIFoundationUtils' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Set of helpers for Foundation framework classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIKeychainUtils/TIKeychainUtils.podspec b/TIKeychainUtils/TIKeychainUtils.podspec index caf0d2e9..7f0c0a34 100644 --- a/TIKeychainUtils/TIKeychainUtils.podspec +++ b/TIKeychainUtils/TIKeychainUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIKeychainUtils' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Set of helpers for Keychain classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIMoyaNetworking/Sources/NetworkService/DefaultJsonNetworkService.swift b/TIMoyaNetworking/Sources/NetworkService/DefaultJsonNetworkService.swift index c7952237..4f2ef79d 100644 --- a/TIMoyaNetworking/Sources/NetworkService/DefaultJsonNetworkService.swift +++ b/TIMoyaNetworking/Sources/NetworkService/DefaultJsonNetworkService.swift @@ -59,13 +59,17 @@ open class DefaultJsonNetworkService { plugins: plugins) } + open func serialize(request: EndpointRequest) throws -> SerializedRequest { + try request.serialize(using: ApplicationJsonBodySerializer(jsonEncoder: jsonEncoder), + defaultServer: defaultServer) + } + @available(iOS 13.0.0, *) - open func process(request: EndpointRequest, - mapMoyaError: @escaping Closure) async -> Result { + open func process(request: EndpointRequest) async -> EndpointRequestResult { await process(request: request, mapSuccess: Result.success, - mapFailure: Result.failure, - mapMoyaError: { .failure(mapMoyaError($0)) }) + mapFailure: { .failure(.apiError($0)) }, + mapMoyaError: { .failure(.networkError($0)) }) } @available(iOS 13.0.0, *) @@ -98,15 +102,14 @@ open class DefaultJsonNetworkService { mapMoyaError: @escaping Closure, completion: @escaping ParameterClosure) -> Cancellable { - ScopeCancellable { [jsonEncoder, serializationQueue, callbackQueue, defaultServer] scope in + ScopeCancellable { [serializationQueue, callbackQueue] scope in let workItem = DispatchWorkItem { guard !scope.isCancelled else { return } do { - let serializedRequest = try request.serialize(using: ApplicationJsonBodySerializer(jsonEncoder: jsonEncoder), - defaultServer: defaultServer) + let serializedRequest = try self.serialize(request: request) scope.add(cancellable: self.process(request: serializedRequest, mapSuccess: mapSuccess, diff --git a/TIMoyaNetworking/Sources/NetworkService/EndpointErrorResult.swift b/TIMoyaNetworking/Sources/NetworkService/EndpointErrorResult.swift new file mode 100644 index 00000000..b7c4a65c --- /dev/null +++ b/TIMoyaNetworking/Sources/NetworkService/EndpointErrorResult.swift @@ -0,0 +1,43 @@ +// +// Copyright (c) 2022 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 Moya +import Foundation + +public enum EndpointErrorResult: Error { + case apiError(E) + case networkError(MoyaError) +} + +public extension EndpointErrorResult { + var isNetworkConnectionProblem: Bool { + guard case let .networkError(moyaError) = self, + case let .underlying(error, _) = moyaError, + case let .sessionTaskFailed(urlSessionTaskError) = error.asAFError, + let urlError = urlSessionTaskError as? URLError else { + + return false + } + + return urlError.code == .notConnectedToInternet + } +} diff --git a/TIMoyaNetworking/Sources/NetworkService/EndpointRequestResult.swift b/TIMoyaNetworking/Sources/NetworkService/EndpointRequestResult.swift new file mode 100644 index 00000000..d9a318ac --- /dev/null +++ b/TIMoyaNetworking/Sources/NetworkService/EndpointRequestResult.swift @@ -0,0 +1,23 @@ +// +// Copyright (c) 2022 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. +// + +public typealias EndpointRequestResult = Result> diff --git a/TIMoyaNetworking/Sources/RecoverableNetworkService/DefaultRecoverableJsonNetworkService.swift b/TIMoyaNetworking/Sources/RecoverableNetworkService/DefaultRecoverableJsonNetworkService.swift index a89d13dd..049e26ed 100644 --- a/TIMoyaNetworking/Sources/RecoverableNetworkService/DefaultRecoverableJsonNetworkService.swift +++ b/TIMoyaNetworking/Sources/RecoverableNetworkService/DefaultRecoverableJsonNetworkService.swift @@ -26,45 +26,40 @@ import Moya @available(iOS 13.0.0, *) open class DefaultRecoverableJsonNetworkService: DefaultJsonNetworkService { - public typealias ErrorHandler = AnyAsyncEventHandler + public typealias ErrorHandler = AnyAsyncEventHandler> private(set) public var defaultErrorHandlers: [ErrorHandler] = [] - public func process(recoverableRequest: EndpointRequest, - prependErrorHandlers: [ErrorHandler], - appendErrorHandlers: [ErrorHandler], - mapMoyaError: @escaping Closure) async -> Result { + open func process(recoverableRequest: EndpointRequest, + prependErrorHandlers: [ErrorHandler] = [], + appendErrorHandlers: [ErrorHandler] = []) async -> EndpointRequestResult { await process(recoverableRequest: recoverableRequest, - errorHandlers: prependErrorHandlers + defaultErrorHandlers + appendErrorHandlers, - mapMoyaError: mapMoyaError) + errorHandlers: prependErrorHandlers + defaultErrorHandlers + appendErrorHandlers) } - public func process(recoverableRequest: EndpointRequest, - errorHandlers: [ErrorHandler], - mapMoyaError: @escaping Closure) async -> Result { + open func process(recoverableRequest: EndpointRequest, + errorHandlers: [ErrorHandler]) async -> EndpointRequestResult { - let result = await process(request: recoverableRequest, - mapMoyaError: mapMoyaError) + let result: EndpointRequestResult = await process(request: recoverableRequest) if case let .failure(errorResponse) = result { let chain = AsyncEventHandlingChain(handlers: errorHandlers) if await chain.handle(errorResponse) { return await process(recoverableRequest: recoverableRequest, - errorHandlers: errorHandlers, - mapMoyaError: mapMoyaError) + errorHandlers: errorHandlers) } } return result } - public func register(defaultErrorHandler: ErrorHandler) where ErrorHandler.EventType == ApiError { + public func register(defaultErrorHandler: ErrorHandler) where ErrorHandler.EventType == EndpointErrorResult { defaultErrorHandlers.append(defaultErrorHandler.asAnyAsyncEventHandler()) } - public func set(defaultErrorHandlers: ErrorHandler...) where ErrorHandler.EventType == ApiError { + public func set(defaultErrorHandlers: ErrorHandler...) where ErrorHandler.EventType == EndpointErrorResult { self.defaultErrorHandlers = defaultErrorHandlers.map { $0.asAnyAsyncEventHandler() } } } diff --git a/TIMoyaNetworking/TIMoyaNetworking.podspec b/TIMoyaNetworking/TIMoyaNetworking.podspec index 29415d8a..6d9e70d5 100644 --- a/TIMoyaNetworking/TIMoyaNetworking.podspec +++ b/TIMoyaNetworking/TIMoyaNetworking.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIMoyaNetworking' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Moya + Swagger network service.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TINetworking/Sources/Request/SerializedRequest.swift b/TINetworking/Sources/Request/SerializedRequest.swift index fa7f2f68..755d9b9f 100644 --- a/TINetworking/Sources/Request/SerializedRequest.swift +++ b/TINetworking/Sources/Request/SerializedRequest.swift @@ -52,3 +52,33 @@ public struct SerializedRequest { self.acceptableStatusCodes = acceptableStatusCodes } } + +extension SerializedRequest: Hashable { + private var comparableQueryParameters: [String: String] { + queryParameters.mapValues(String.init(describing:)) + } + + public static func == (lhs: SerializedRequest, rhs: SerializedRequest) -> Bool { + lhs.baseURL == rhs.baseURL && + lhs.path == rhs.path && + lhs.method == rhs.method && + lhs.bodyData == rhs.bodyData && + lhs.comparableQueryParameters == rhs.comparableQueryParameters && + lhs.headers == rhs.headers && + lhs.cookies == rhs.cookies && + lhs.acceptableStatusCodes == rhs.acceptableStatusCodes + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(baseURL) + hasher.combine(path) + hasher.combine(method) + hasher.combine(bodyData) + hasher.combine(comparableQueryParameters.keys.sorted()) + hasher.combine(comparableQueryParameters.values.sorted()) + hasher.combine(headers?.keys.sorted() ?? []) + hasher.combine(headers?.values.sorted() ?? []) + hasher.combine(cookies) + hasher.combine(acceptableStatusCodes.sorted()) + } +} diff --git a/TINetworking/TINetworking.podspec b/TINetworking/TINetworking.podspec index 0057a4a0..787a0874 100644 --- a/TINetworking/TINetworking.podspec +++ b/TINetworking/TINetworking.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TINetworking' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Swagger-frendly networking layer helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TINetworkingCache/Sources/EndpointCacheService.swift b/TINetworkingCache/Sources/EndpointCacheService.swift new file mode 100644 index 00000000..ae0a50ca --- /dev/null +++ b/TINetworkingCache/Sources/EndpointCacheService.swift @@ -0,0 +1,81 @@ +// +// Copyright (c) 2022 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 TINetworking +import TIFoundationUtils +import Cache +import Foundation + +public struct EndpointCacheService { + private let serializedRequest: SerializedRequest + private let multiLevelStorage: Storage + + public var cachedContent: Content? { + get { + guard let entry = try? multiLevelStorage.entry(forKey: serializedRequest), !entry.expiry.isExpired else { + try? multiLevelStorage.removeObject(forKey: serializedRequest) + return nil + } + + return entry.object + } + nonmutating set { + if let object = newValue { + try? multiLevelStorage.setObject(object, + forKey: serializedRequest) + } else { + try? multiLevelStorage.removeObject(forKey: serializedRequest) + } + } + } + + public init(serializedRequest: SerializedRequest, + cacheLifetime: TimeInterval, + jsonCodingConfigurator: JsonCodingConfigurator) throws { + + self.serializedRequest = serializedRequest + + let nameWithoutLeadingSlash: String + + if serializedRequest.path.starts(with: "/") { + nameWithoutLeadingSlash = serializedRequest.path.drop { $0 == "/" }.string + } else { + nameWithoutLeadingSlash = serializedRequest.path + } + + let diskConfig = DiskConfig(name: nameWithoutLeadingSlash, + expiry: .seconds(cacheLifetime)) + let memoryConfig = MemoryConfig(expiry: .seconds(cacheLifetime), + countLimit: 0, + totalCostLimit: 0) + + let transformer = Transformer { + try jsonCodingConfigurator.jsonEncoder.encode($0) + } fromData: { + try jsonCodingConfigurator.jsonDecoder.decode(Content.self, from: $0) + } + + self.multiLevelStorage = try Storage(diskConfig: diskConfig, + memoryConfig: memoryConfig, + transformer: transformer) + } +} diff --git a/TINetworkingCache/TINetworkingCache.podspec b/TINetworkingCache/TINetworkingCache.podspec new file mode 100644 index 00000000..ed2f2df0 --- /dev/null +++ b/TINetworkingCache/TINetworkingCache.podspec @@ -0,0 +1,18 @@ +Pod::Spec.new do |s| + s.name = 'TINetworkingCache' + s.version = '1.15.0' + s.summary = 'Caching results of EndpointRequests.' + s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'petropavel13' => 'ivan.smolin@touchin.ru' } + s.source = { :git => 'https://github.com/TouchInstinct/LeadKit.git', :tag => s.version.to_s } + + s.ios.deployment_target = '11.0' + s.swift_versions = ['5.3'] + + s.source_files = s.name + '/Sources/**/*' + + s.dependency 'TIFoundationUtils', s.version.to_s + s.dependency 'TINetworking', s.version.to_s + s.dependency 'Cache', "~> 6.0.0" +end diff --git a/TISwiftUtils/TISwiftUtils.podspec b/TISwiftUtils/TISwiftUtils.podspec index 979c5d21..c45f7043 100644 --- a/TISwiftUtils/TISwiftUtils.podspec +++ b/TISwiftUtils/TISwiftUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TISwiftUtils' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Bunch of useful helpers for Swift development.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITableKitUtils/Sources/Extensions/TableSection/TableSection+Extensions.swift b/TITableKitUtils/Sources/Extensions/TableSection/TableSection+Extensions.swift index d3e5d24f..2ef74dc2 100644 --- a/TITableKitUtils/Sources/Extensions/TableSection/TableSection+Extensions.swift +++ b/TITableKitUtils/Sources/Extensions/TableSection/TableSection+Extensions.swift @@ -21,6 +21,7 @@ // import TableKit +import class UIKit.UIView public extension TableSection { diff --git a/TITableKitUtils/TITableKitUtils.podspec b/TITableKitUtils/TITableKitUtils.podspec index 76119bb9..7c23989c 100644 --- a/TITableKitUtils/TITableKitUtils.podspec +++ b/TITableKitUtils/TITableKitUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITableKitUtils' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Set of helpers for TableKit classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITransitions/TITransitions.podspec b/TITransitions/TITransitions.podspec index 3046806f..0616a5ef 100644 --- a/TITransitions/TITransitions.podspec +++ b/TITransitions/TITransitions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITransitions' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Set of custom transitions to present controller. ' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIElements/TIUIElements.podspec b/TIUIElements/TIUIElements.podspec index 5fcd3f57..76f61d39 100644 --- a/TIUIElements/TIUIElements.podspec +++ b/TIUIElements/TIUIElements.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIElements' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Bunch of useful protocols and views.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIKitCore/TIUIKitCore.podspec b/TIUIKitCore/TIUIKitCore.podspec index edcf36d2..f52155a0 100644 --- a/TIUIKitCore/TIUIKitCore.podspec +++ b/TIUIKitCore/TIUIKitCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIKitCore' - s.version = '1.14.3' + s.version = '1.15.0' s.summary = 'Core UI elements: protocols, views and helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/project-scripts/push_to_podspecs.sh b/project-scripts/push_to_podspecs.sh index c1362353..44252139 100755 --- a/project-scripts/push_to_podspecs.sh +++ b/project-scripts/push_to_podspecs.sh @@ -12,6 +12,7 @@ ORDERED_PODSPECS="../TISwiftUtils/TISwiftUtils.podspec ../TIUIElements/TIUIElements.podspec ../TITableKitUtils/TITableKitUtils.podspec ../TINetworking/TINetworking.podspec +../TINetworking/TINetworkingCache.podspec ../TIMoyaNetworking/TIMoyaNetworking.podspec" for podspec_path in ${ORDERED_PODSPECS}; do