Merge pull request #292 from TouchInstinct/feature/tinetworking_nullable_body
Few fixes for code generation
This commit is contained in:
commit
3e5d8d13fb
|
|
@ -1,5 +1,12 @@
|
|||
# Changelog
|
||||
|
||||
|
||||
### 1.12.0
|
||||
|
||||
- **Update**: EndpointRequest Body can take a nil value
|
||||
- **Update**: Parameter value can be nil as well
|
||||
- **Update**: observe operator of AsyncOperation now accepts callback queue parameter
|
||||
|
||||
### 1.11.1
|
||||
- **Fix**: `timeoutIntervalForRequest` parameter for `URLSessionConfiguration` in `NetworkServiceConfiguration` added.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = "LeadKit"
|
||||
s.version = "1.11.1"
|
||||
s.version = "1.12.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"
|
||||
|
|
|
|||
|
|
@ -27,18 +27,25 @@ private final class ClosureObserverOperation<Output, Failure: Error>: AsyncOpera
|
|||
|
||||
public init(dependency: AsyncOperation<Output, Failure>,
|
||||
onSuccess: ((Output) -> Void)? = nil,
|
||||
onFailure: ((Failure) -> Void)? = nil) {
|
||||
onFailure: ((Failure) -> Void)? = nil,
|
||||
callbackQueue: DispatchQueue = .main) {
|
||||
|
||||
super.init()
|
||||
|
||||
cancelOnCancellation(of: dependency)
|
||||
|
||||
dependencyObservation = dependency.subscribe { [weak self] in
|
||||
onSuccess?($0)
|
||||
self?.handle(result: $0)
|
||||
} onFailure: { [weak self] in
|
||||
onFailure?($0)
|
||||
self?.handle(error: $0)
|
||||
dependencyObservation = dependency.subscribe { [weak self] result in
|
||||
callbackQueue.async {
|
||||
onSuccess?(result)
|
||||
}
|
||||
|
||||
self?.handle(result: result)
|
||||
} onFailure: { [weak self] error in
|
||||
callbackQueue.async {
|
||||
onFailure?(error)
|
||||
}
|
||||
|
||||
self?.handle(error: error)
|
||||
}
|
||||
|
||||
addDependency(dependency) // keeps strong reference to dependency as well
|
||||
|
|
@ -49,8 +56,12 @@ private final class ClosureObserverOperation<Output, Failure: Error>: AsyncOpera
|
|||
|
||||
public extension AsyncOperation {
|
||||
func observe(onSuccess: ((Output) -> Void)? = nil,
|
||||
onFailure: ((Failure) -> Void)? = nil) -> AsyncOperation<Output, Failure> {
|
||||
onFailure: ((Failure) -> Void)? = nil,
|
||||
callbackQueue: DispatchQueue = .main) -> AsyncOperation<Output, Failure> {
|
||||
|
||||
ClosureObserverOperation(dependency: self, onSuccess: onSuccess, onFailure: onFailure)
|
||||
ClosureObserverOperation(dependency: self,
|
||||
onSuccess: onSuccess,
|
||||
onFailure: onFailure,
|
||||
callbackQueue: callbackQueue)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,5 +28,6 @@ public protocol CancellableTask {
|
|||
|
||||
@available(iOS 13.0, *)
|
||||
extension Task: CancellableTask {}
|
||||
|
||||
extension Operation: CancellableTask {}
|
||||
extension DispatchWorkItem: CancellableTask {}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TIFoundationUtils'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TIKeychainUtils'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// 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 TISwiftUtils
|
||||
|
||||
public extension Cancellable {
|
||||
static func nonCancellable() -> Cancellable {
|
||||
NonCancellable()
|
||||
}
|
||||
|
||||
static func scoped(scopeCancellableClosure: ScopeCancellable.ScopeCancellableClosure) -> Cancellable {
|
||||
ScopeCancellable(scopeCancellableClosure: scopeCancellableClosure)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// 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
|
||||
|
||||
public struct NonCancellable: Cancellable {
|
||||
public let isCancelled = true
|
||||
|
||||
public func cancel() {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,9 @@ import Moya
|
|||
import TISwiftUtils
|
||||
|
||||
public final class ScopeCancellable: CancellableBag {
|
||||
public init(scopeCancellableClosure: Closure<ScopeCancellable, Cancellable>) {
|
||||
public typealias ScopeCancellableClosure = Closure<ScopeCancellable, Cancellable>
|
||||
|
||||
public init(scopeCancellableClosure: ScopeCancellableClosure) {
|
||||
super.init()
|
||||
|
||||
cancellables = [scopeCancellableClosure(self)]
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ import Moya
|
|||
open class DefaultRecoverableJsonNetworkService<ApiError: Decodable & Error>: DefaultJsonNetworkService {
|
||||
public typealias ErrorHandler = AnyAsyncEventHandler<ApiError>
|
||||
|
||||
private var defaultErrorHandlers: [ErrorHandler] = []
|
||||
private(set) public var defaultErrorHandlers: [ErrorHandler] = []
|
||||
|
||||
public func process<B: Encodable, S: Decodable>(request: EndpointRequest<B, S>,
|
||||
prependErrorHandlers: [ErrorHandler] = [],
|
||||
appendErrorHandlers: [ErrorHandler] = [],
|
||||
prependErrorHandlers: [ErrorHandler],
|
||||
appendErrorHandlers: [ErrorHandler],
|
||||
mapMoyaError: @escaping Closure<MoyaError, ApiError>) async -> Result<S, ApiError> {
|
||||
|
||||
await process(request: request,
|
||||
|
|
@ -41,7 +41,7 @@ open class DefaultRecoverableJsonNetworkService<ApiError: Decodable & Error>: De
|
|||
}
|
||||
|
||||
public func process<B: Encodable, S: Decodable>(request: EndpointRequest<B, S>,
|
||||
errorHandlers: [ErrorHandler] = [],
|
||||
errorHandlers: [ErrorHandler],
|
||||
mapMoyaError: @escaping Closure<MoyaError, ApiError>) async -> Result<S, ApiError> {
|
||||
|
||||
let result = await process(request: request, mapMoyaError: mapMoyaError)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TIMoyaNetworking'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -38,7 +38,13 @@ public struct ApplicationJsonBodySerializer<Body>: BodySerializer {
|
|||
}
|
||||
}
|
||||
|
||||
public func serialize(body: Body) throws -> ContentTypeData {
|
||||
(CommonMediaTypes.applicationJson.rawValue, try encodingClosure(body))
|
||||
public func serialize(body: Body?) throws -> ContentTypeData {
|
||||
let mimeType = CommonMediaTypes.applicationJson.rawValue
|
||||
|
||||
guard let body = body else {
|
||||
return (mimeType, Data())
|
||||
}
|
||||
|
||||
return ContentTypeData(mimeType, try encodingClosure(body))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,5 +27,5 @@ public protocol BodySerializer {
|
|||
|
||||
typealias ContentTypeData = (String, Data)
|
||||
|
||||
func serialize(body: Body) throws -> ContentTypeData
|
||||
func serialize(body: Body?) throws -> ContentTypeData
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct EmptyBody: Encodable {
|
||||
public struct Nothing: Codable {
|
||||
public init() {}
|
||||
}
|
||||
|
|
@ -31,11 +31,11 @@ open class BaseUrlParameterEncoding {
|
|||
var filteredComponents: [KeyValueTuple<String, String>] = []
|
||||
|
||||
for key in parameters.keys.sorted(by: <) {
|
||||
guard let parameter = parameters[key] else {
|
||||
guard let parameter = parameters[key], let value = parameter.value else {
|
||||
continue
|
||||
}
|
||||
|
||||
let components = encoding.queryComponents(fromKey: key, value: parameter.value)
|
||||
let components = encoding.queryComponents(fromKey: key, value: value)
|
||||
// filter components with empty values if parameter doesn't allow empty value
|
||||
.filter { !$0.1.isEmpty || parameter.allowEmptyValue }
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
open class HeaderParameterEncoding: BaseUrlParameterEncoding, ParameterEncoding {
|
||||
// MARK: - ParameterEncoding
|
||||
|
||||
open func encode(parameters: [String: Parameter<LocationHeader>]) -> [String: String] {
|
||||
return Dictionary(uniqueKeysWithValues: super.encode(parameters: parameters))
|
||||
}
|
||||
}
|
||||
|
|
@ -25,10 +25,10 @@ open class QueryStringParameterEncoding: BaseUrlParameterEncoding, ParameterEnco
|
|||
// MARK: - ParameterEncoding
|
||||
|
||||
open func encode(parameters: [String: Parameter<LocationQuery>]) -> [String: Any] {
|
||||
let includedKeys = Set(super.encode(parameters: parameters).map { $0.key })
|
||||
let nonEmptyValueKeys = Set(super.encode(parameters: parameters).map { $0.key })
|
||||
|
||||
return parameters
|
||||
.filter { includedKeys.contains($0.key) }
|
||||
.mapValues { $0.value }
|
||||
.filter { nonEmptyValueKeys.contains($0.key) }
|
||||
.compactMapValues { $0.value }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@
|
|||
//
|
||||
|
||||
public struct Parameter<Location: ParameterLocation> {
|
||||
public let value: Any
|
||||
public let value: Any?
|
||||
public let allowEmptyValue: Bool
|
||||
|
||||
public init(value: Any, allowEmptyValue: Bool = false) {
|
||||
public init(value: Any?, allowEmptyValue: Bool = false) {
|
||||
self.value = value
|
||||
self.allowEmptyValue = allowEmptyValue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,15 @@ public extension EndpointRequest {
|
|||
let baseUrl = try (server ?? defaultServer).url(using: customServerVariables)
|
||||
let path = PathParameterEncoding(templateUrl: templatePath).encode(parameters: pathParameters)
|
||||
let (contentType, bodyData) = try serializer.serialize(body: body)
|
||||
let queryParameters = QueryStringParameterEncoding().encode(parameters: queryParameters)
|
||||
let serializedQueryParameters = QueryStringParameterEncoding().encode(parameters: queryParameters)
|
||||
|
||||
var headerParameters = headerParameters ?? HTTPHeaders()
|
||||
headerParameters.add(.contentType(contentType))
|
||||
var serializedHeaderParameters: [String: String]?
|
||||
|
||||
if let customHeaderParameters = headerParameters {
|
||||
serializedHeaderParameters = HeaderParameterEncoding().encode(parameters: customHeaderParameters)
|
||||
}
|
||||
|
||||
serializedHeaderParameters?[HTTPHeader.contentType(contentType).name] = contentType
|
||||
|
||||
let cookies: [HTTPCookie]
|
||||
|
||||
|
|
@ -54,8 +59,8 @@ public extension EndpointRequest {
|
|||
path: path,
|
||||
method: method,
|
||||
bodyData: bodyData,
|
||||
queryParameters: queryParameters,
|
||||
headers: headerParameters.dictionary,
|
||||
queryParameters: serializedQueryParameters,
|
||||
headers: serializedHeaderParameters,
|
||||
cookies: cookies,
|
||||
acceptableStatusCodes: acceptableStatusCodes)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ import Alamofire
|
|||
public struct EndpointRequest<Body, SuccessResponse> {
|
||||
public var templatePath: String
|
||||
public var method: HTTPMethod
|
||||
public var body: Body
|
||||
public var body: Body?
|
||||
public var queryParameters: [String: Parameter<LocationQuery>]
|
||||
public var pathParameters: [String: Parameter<LocationPath>]
|
||||
public var headerParameters: HTTPHeaders?
|
||||
public var headerParameters: [String: Parameter<LocationHeader>]?
|
||||
public var cookieParameters: [String: Parameter<LocationCookie>]
|
||||
public var acceptableStatusCodes: Set<Int>
|
||||
public var server: Server?
|
||||
|
|
@ -36,10 +36,10 @@ public struct EndpointRequest<Body, SuccessResponse> {
|
|||
|
||||
public init(templatePath: String,
|
||||
method: HTTPMethod,
|
||||
body: Body,
|
||||
body: Body?,
|
||||
queryParameters: [String: Parameter<LocationQuery>] = [:],
|
||||
pathParameters: [String: Parameter<LocationPath>] = [:],
|
||||
headerParameters: HTTPHeaders? = nil,
|
||||
headerParameters: [String: Parameter<LocationHeader>]? = nil,
|
||||
cookieParameters: [String: Parameter<LocationCookie>] = [:],
|
||||
acceptableStatusCodes: Set<Int> = HTTPCodes.success.asSet(),
|
||||
server: Server? = nil,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public struct SerializedRequest {
|
|||
method: HTTPMethod,
|
||||
bodyData: Data,
|
||||
queryParameters: Parameters,
|
||||
headers: [String: String],
|
||||
headers: [String: String]?,
|
||||
cookies: [HTTPCookie],
|
||||
acceptableStatusCodes: Set<Int>) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TINetworking'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TISwiftUtils'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TITableKitUtils'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TITransitions'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TIUIElements'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'TIUIKitCore'
|
||||
s.version = '1.11.1'
|
||||
s.version = '1.12.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' }
|
||||
|
|
|
|||
|
|
@ -5,10 +5,15 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||
|
||||
cd "$DIR"
|
||||
|
||||
# Push changes
|
||||
find ../ -name '*.podspec' \
|
||||
-not -path "../Carthage/*" \
|
||||
-not -path "../*/Carthage/*" \
|
||||
-not -path "../Pods/*" \
|
||||
-not -path "../*/Pods/*" \
|
||||
| xargs -I% pod repo push git@github.com:TouchInstinct/Podspecs % --allow-warnings
|
||||
ORDERED_PODSPECS="../TISwiftUtils/TISwiftUtils.podspec
|
||||
../TIFoundationUtils/TIFoundationUtils.podspec
|
||||
../TIKeychainUtils/TIKeychainUtils.podspec
|
||||
../TIUIKitCore/TIUIKitCore.podspec
|
||||
../TIUIElements/TIUIElements.podspec
|
||||
../TITableKitUtils/TITableKitUtils.podspec
|
||||
../TINetworking/TINetworking.podspec
|
||||
../TIMoyaNetworking/TIMoyaNetworking.podspec"
|
||||
|
||||
for podspec_path in ${ORDERED_PODSPECS}; do
|
||||
pod repo push git@github.com:TouchInstinct/Podspecs ${podspec_path} --allow-warnings
|
||||
done
|
||||
|
|
|
|||
Loading…
Reference in New Issue