mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-10 14:52:44 +00:00
[Swift4]Update templates for swift 4 (#6921)
* update versions of dependencies on swift4 and swift3 * change syntax for swift4 * run petstore script * change enum case from UpperCamel to lowerCamel * remove unneeded break statements * avoid wrapping conditionals in parentheses * avoid force casting * run pod update on petstore/swift4/rxswift * update project for swift 4 * run swift4-petstore-all.sh * fix compile error * avoid use iso8601 date strategy for encoder / decoder * resolve file references
This commit is contained in:
committed by
William Cheng
parent
b06ccec11e
commit
a5e4abe5ec
@@ -1 +1 @@
|
||||
2.3.0-SNAPSHOT
|
||||
unset
|
||||
@@ -1,2 +1,2 @@
|
||||
github "Alamofire/Alamofire" >= 3.1.0
|
||||
github "ReactiveX/RxSwift" ~> 2.0
|
||||
github "Alamofire/Alamofire" ~> 4.5.0
|
||||
github "ReactiveX/RxSwift" ~> 4.0
|
||||
|
||||
@@ -9,6 +9,6 @@ Pod::Spec.new do |s|
|
||||
s.homepage = 'https://github.com/swagger-api/swagger-codegen'
|
||||
s.summary = 'PetstoreClient'
|
||||
s.source_files = 'PetstoreClient/Classes/**/*.swift'
|
||||
s.dependency 'RxSwift', '~> 3.4.1'
|
||||
s.dependency 'RxSwift', '~> 4.0'
|
||||
s.dependency 'Alamofire', '~> 4.5.0'
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// AnotherfakeAPI.swift
|
||||
// AnotherFakeAPI.swift
|
||||
//
|
||||
// Generated by swagger-codegen
|
||||
// https://github.com/swagger-api/swagger-codegen
|
||||
@@ -11,7 +11,7 @@ import RxSwift
|
||||
|
||||
|
||||
|
||||
open class AnotherfakeAPI {
|
||||
open class AnotherFakeAPI {
|
||||
/**
|
||||
To test special tags
|
||||
|
||||
@@ -34,7 +34,7 @@ open class AnotherfakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
testSpecialTags(body: body) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ open class FakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
fakeOuterBooleanSerialize(body: body) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -84,7 +84,7 @@ open class FakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
fakeOuterCompositeSerialize(body: body) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -140,7 +140,7 @@ open class FakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
fakeOuterNumberSerialize(body: body) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -192,7 +192,7 @@ open class FakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
fakeOuterStringSerialize(body: body) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -246,7 +246,7 @@ open class FakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
testClientModel(body: body) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -329,9 +329,9 @@ open class FakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
testEndpointParameters(number: number, double: double, patternWithoutDelimiter: patternWithoutDelimiter, byte: byte, integer: integer, int32: int32, int64: int64, float: float, string: string, binary: binary, date: date, dateTime: dateTime, password: password, callback: callback) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -498,9 +498,9 @@ open class FakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
testEnumParameters(enumFormStringArray: enumFormStringArray, enumFormString: enumFormString, enumHeaderStringArray: enumHeaderStringArray, enumHeaderString: enumHeaderString, enumQueryStringArray: enumQueryStringArray, enumQueryString: enumQueryString, enumQueryInteger: enumQueryInteger, enumQueryDouble: enumQueryDouble) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -554,6 +554,60 @@ open class FakeAPI {
|
||||
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false, headers: headerParameters)
|
||||
}
|
||||
|
||||
/**
|
||||
test inline additionalProperties
|
||||
|
||||
- parameter param: (body) request body
|
||||
- parameter completion: completion handler to receive the data and the error objects
|
||||
*/
|
||||
open class func testInlineAdditionalProperties(param: Any, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||
testInlineAdditionalPropertiesWithRequestBuilder(param: param).execute { (response, error) -> Void in
|
||||
completion(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
test inline additionalProperties
|
||||
|
||||
- parameter param: (body) request body
|
||||
- returns: Observable<Void>
|
||||
*/
|
||||
open class func testInlineAdditionalProperties(param: Any) -> Observable<Void> {
|
||||
return Observable.create { observer -> Disposable in
|
||||
testInlineAdditionalProperties(param: param) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
return Disposables.create()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
test inline additionalProperties
|
||||
- POST /fake/inline-additionalProperties
|
||||
-
|
||||
|
||||
- parameter param: (body) request body
|
||||
|
||||
- returns: RequestBuilder<Void>
|
||||
*/
|
||||
open class func testInlineAdditionalPropertiesWithRequestBuilder(param: Any) -> RequestBuilder<Void> {
|
||||
let path = "/fake/inline-additionalProperties"
|
||||
let URLString = PetstoreClientAPI.basePath + path
|
||||
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: param)
|
||||
|
||||
let url = NSURLComponents(string: URLString)
|
||||
|
||||
|
||||
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||
|
||||
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||
}
|
||||
|
||||
/**
|
||||
test json serialization of form data
|
||||
|
||||
@@ -578,9 +632,9 @@ open class FakeAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
testJsonFormData(param: param, param2: param2) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Fake_classname_tags123API.swift
|
||||
// FakeClassnameTags123API.swift
|
||||
//
|
||||
// Generated by swagger-codegen
|
||||
// https://github.com/swagger-api/swagger-codegen
|
||||
@@ -11,7 +11,7 @@ import RxSwift
|
||||
|
||||
|
||||
|
||||
open class Fake_classname_tags123API {
|
||||
open class FakeClassnameTags123API {
|
||||
/**
|
||||
To test class name in snake case
|
||||
|
||||
@@ -34,7 +34,7 @@ open class Fake_classname_tags123API {
|
||||
return Observable.create { observer -> Disposable in
|
||||
testClassname(body: body) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -34,9 +34,9 @@ open class PetAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
addPet(body: body) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -93,9 +93,9 @@ open class PetAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
deletePet(petId: petId, apiKey: apiKey) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -165,7 +165,7 @@ open class PetAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
findPetsByStatus(status: status) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -309,7 +309,7 @@ open class PetAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
findPetsByTags(tags: tags) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -453,7 +453,7 @@ open class PetAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
getPetById(petId: petId) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -563,9 +563,9 @@ open class PetAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
updatePet(body: body) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -624,9 +624,9 @@ open class PetAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
updatePetWithForm(petId: petId, name: name, status: status) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -694,7 +694,7 @@ open class PetAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
uploadFile(petId: petId, additionalMetadata: additionalMetadata, file: file) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@ open class StoreAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
deleteOrder(orderId: orderId) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -87,7 +87,7 @@ open class StoreAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
getInventory() { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -145,7 +145,7 @@ open class StoreAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
getOrderById(orderId: orderId) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -230,7 +230,7 @@ open class StoreAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
placeOrder(body: body) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@ open class UserAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
createUser(body: body) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -88,9 +88,9 @@ open class UserAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
createUsersWithArrayInput(body: body) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -142,9 +142,9 @@ open class UserAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
createUsersWithListInput(body: body) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -196,9 +196,9 @@ open class UserAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
deleteUser(username: username) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -251,7 +251,7 @@ open class UserAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
getUserByName(username: username) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -346,7 +346,7 @@ open class UserAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
loginUser(username: username, password: password) { data, error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next(data!))
|
||||
}
|
||||
@@ -407,9 +407,9 @@ open class UserAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
logoutUser() { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
@@ -461,9 +461,9 @@ open class UserAPI {
|
||||
return Observable.create { observer -> Disposable in
|
||||
updateUser(username: username, body: body) { error in
|
||||
if let error = error {
|
||||
observer.on(.error(error as Error))
|
||||
observer.on(.error(error))
|
||||
} else {
|
||||
observer.on(.next())
|
||||
observer.on(.next(()))
|
||||
}
|
||||
observer.on(.completed)
|
||||
}
|
||||
|
||||
@@ -77,16 +77,12 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
|
||||
else {
|
||||
mpForm.append(fileURL, withName: k)
|
||||
}
|
||||
break
|
||||
case let string as String:
|
||||
mpForm.append(string.data(using: String.Encoding.utf8)!, withName: k)
|
||||
break
|
||||
case let number as NSNumber:
|
||||
mpForm.append(number.stringValue.data(using: String.Encoding.utf8)!, withName: k)
|
||||
break
|
||||
default:
|
||||
fatalError("Unprocessable value \(v) with key \(k)")
|
||||
break
|
||||
}
|
||||
}
|
||||
}, to: URLString, method: xMethod!, headers: nil, encodingCompletion: { encodingResult in
|
||||
@@ -97,7 +93,7 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
|
||||
}
|
||||
self.processRequest(request: upload, managerId, completion)
|
||||
case .failure(let encodingError):
|
||||
completion(nil, ErrorResponse.Error(415, nil, encodingError))
|
||||
completion(nil, ErrorResponse.error(415, nil, encodingError))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@@ -129,7 +125,7 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
|
||||
if stringResponse.result.isFailure {
|
||||
completion(
|
||||
nil,
|
||||
ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
|
||||
ErrorResponse.error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -186,9 +182,9 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
|
||||
)
|
||||
|
||||
} catch let requestParserError as DownloadException {
|
||||
completion(nil, ErrorResponse.Error(400, dataResponse.data, requestParserError))
|
||||
completion(nil, ErrorResponse.error(400, dataResponse.data, requestParserError))
|
||||
} catch let error {
|
||||
completion(nil, ErrorResponse.Error(400, dataResponse.data, error))
|
||||
completion(nil, ErrorResponse.error(400, dataResponse.data, error))
|
||||
}
|
||||
return
|
||||
})
|
||||
@@ -199,7 +195,7 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
|
||||
if voidResponse.result.isFailure {
|
||||
completion(
|
||||
nil,
|
||||
ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
|
||||
ErrorResponse.error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -215,10 +211,10 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
|
||||
validatedRequest.responseData(completionHandler: { (dataResponse) in
|
||||
cleanupRequest()
|
||||
|
||||
if (dataResponse.result.isFailure) {
|
||||
if dataResponse.result.isFailure {
|
||||
completion(
|
||||
nil,
|
||||
ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
|
||||
ErrorResponse.error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -331,7 +327,7 @@ open class AlamofireDecodableRequestBuilder<T:Decodable>: AlamofireRequestBuilde
|
||||
if stringResponse.result.isFailure {
|
||||
completion(
|
||||
nil,
|
||||
ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
|
||||
ErrorResponse.error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -351,7 +347,7 @@ open class AlamofireDecodableRequestBuilder<T:Decodable>: AlamofireRequestBuilde
|
||||
if voidResponse.result.isFailure {
|
||||
completion(
|
||||
nil,
|
||||
ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
|
||||
ErrorResponse.error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -367,10 +363,10 @@ open class AlamofireDecodableRequestBuilder<T:Decodable>: AlamofireRequestBuilde
|
||||
validatedRequest.responseData(completionHandler: { (dataResponse) in
|
||||
cleanupRequest()
|
||||
|
||||
if (dataResponse.result.isFailure) {
|
||||
if dataResponse.result.isFailure {
|
||||
completion(
|
||||
nil,
|
||||
ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
|
||||
ErrorResponse.error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -388,17 +384,17 @@ open class AlamofireDecodableRequestBuilder<T:Decodable>: AlamofireRequestBuilde
|
||||
cleanupRequest()
|
||||
|
||||
guard dataResponse.result.isSuccess else {
|
||||
completion(nil, ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!))
|
||||
completion(nil, ErrorResponse.error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!))
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = dataResponse.data, !data.isEmpty else {
|
||||
completion(nil, ErrorResponse.Error(-1, nil, AlamofireDecodableRequestBuilderError.emptyDataResponse))
|
||||
completion(nil, ErrorResponse.error(-1, nil, AlamofireDecodableRequestBuilderError.emptyDataResponse))
|
||||
return
|
||||
}
|
||||
|
||||
guard let httpResponse = dataResponse.response else {
|
||||
completion(nil, ErrorResponse.Error(-2, nil, AlamofireDecodableRequestBuilderError.nilHTTPResponse))
|
||||
completion(nil, ErrorResponse.error(-2, nil, AlamofireDecodableRequestBuilderError.nilHTTPResponse))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,12 @@ open class CodableHelper {
|
||||
decoder.dateDecodingStrategy = .formatted(df)
|
||||
} else {
|
||||
decoder.dataDecodingStrategy = .base64
|
||||
if #available(iOS 10.0, *) {
|
||||
decoder.dateDecodingStrategy = .iso8601
|
||||
}
|
||||
let formatter = DateFormatter()
|
||||
formatter.calendar = Calendar(identifier: .iso8601)
|
||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
formatter.timeZone = TimeZone(secondsFromGMT: 0)
|
||||
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
|
||||
decoder.dateDecodingStrategy = .formatted(formatter)
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -45,9 +48,12 @@ open class CodableHelper {
|
||||
encoder.outputFormatting = .prettyPrinted
|
||||
}
|
||||
encoder.dataEncodingStrategy = .base64
|
||||
if #available(iOS 10.0, *) {
|
||||
encoder.dateEncodingStrategy = .iso8601
|
||||
}
|
||||
let formatter = DateFormatter()
|
||||
formatter.calendar = Calendar(identifier: .iso8601)
|
||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
formatter.timeZone = TimeZone(secondsFromGMT: 0)
|
||||
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
|
||||
encoder.dateEncodingStrategy = .formatted(formatter)
|
||||
|
||||
do {
|
||||
returnedData = try encoder.encode(value)
|
||||
|
||||
@@ -53,7 +53,7 @@ extension Dictionary: JSONEncodable {
|
||||
func encodeToJSON() -> Any {
|
||||
var dictionary = [AnyHashable: Any]()
|
||||
for (key, value) in self {
|
||||
dictionary[key as! NSObject] = encodeIfPossible(value)
|
||||
dictionary[key] = encodeIfPossible(value)
|
||||
}
|
||||
return dictionary as Any
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ protocol JSONEncodable {
|
||||
}
|
||||
|
||||
public enum ErrorResponse : Error {
|
||||
case Error(Int, Data?, Error)
|
||||
case error(Int, Data?, Error)
|
||||
}
|
||||
|
||||
open class Response<T> {
|
||||
@@ -28,8 +28,8 @@ open class Response<T> {
|
||||
public convenience init(response: HTTPURLResponse, body: T?) {
|
||||
let rawHeader = response.allHeaderFields
|
||||
var header = [String:String]()
|
||||
for (key, value) in rawHeader {
|
||||
header[key as! String] = value as? String
|
||||
for case let (key, value) as (String, String) in rawHeader {
|
||||
header[key] = value
|
||||
}
|
||||
self.init(statusCode: response.statusCode, header: header, body: body)
|
||||
}
|
||||
|
||||
@@ -15,10 +15,12 @@ open class AdditionalPropertiesClass: Codable {
|
||||
public var mapOfMapProperty: [String:[String:String]]?
|
||||
|
||||
|
||||
|
||||
public init(mapProperty: [String:String]?, mapOfMapProperty: [String:[String:String]]?) {
|
||||
self.mapProperty = mapProperty
|
||||
self.mapOfMapProperty = mapOfMapProperty
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -15,10 +15,12 @@ open class Animal: Codable {
|
||||
public var color: String?
|
||||
|
||||
|
||||
|
||||
public init(className: String, color: String?) {
|
||||
self.className = className
|
||||
self.color = color
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -16,11 +16,13 @@ open class ApiResponse: Codable {
|
||||
public var message: String?
|
||||
|
||||
|
||||
|
||||
public init(code: Int?, type: String?, message: String?) {
|
||||
self.code = code
|
||||
self.type = type
|
||||
self.message = message
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ open class ArrayOfArrayOfNumberOnly: Codable {
|
||||
public var arrayArrayNumber: [[Double]]?
|
||||
|
||||
|
||||
|
||||
public init(arrayArrayNumber: [[Double]]?) {
|
||||
self.arrayArrayNumber = arrayArrayNumber
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -24,7 +26,7 @@ open class ArrayOfArrayOfNumberOnly: Codable {
|
||||
|
||||
var container = encoder.container(keyedBy: String.self)
|
||||
|
||||
try container.encodeArrayIfPresent(arrayArrayNumber, forKey: "ArrayArrayNumber")
|
||||
try container.encodeIfPresent(arrayArrayNumber, forKey: "ArrayArrayNumber")
|
||||
}
|
||||
|
||||
// Decodable protocol methods
|
||||
@@ -32,7 +34,7 @@ open class ArrayOfArrayOfNumberOnly: Codable {
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: String.self)
|
||||
|
||||
arrayArrayNumber = try container.decodeArrayIfPresent([Double].self, forKey: "ArrayArrayNumber")
|
||||
arrayArrayNumber = try container.decodeIfPresent([[Double]].self, forKey: "ArrayArrayNumber")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ open class ArrayOfNumberOnly: Codable {
|
||||
public var arrayNumber: [Double]?
|
||||
|
||||
|
||||
|
||||
public init(arrayNumber: [Double]?) {
|
||||
self.arrayNumber = arrayNumber
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -24,7 +26,7 @@ open class ArrayOfNumberOnly: Codable {
|
||||
|
||||
var container = encoder.container(keyedBy: String.self)
|
||||
|
||||
try container.encodeArrayIfPresent(arrayNumber, forKey: "ArrayNumber")
|
||||
try container.encodeIfPresent(arrayNumber, forKey: "ArrayNumber")
|
||||
}
|
||||
|
||||
// Decodable protocol methods
|
||||
@@ -32,7 +34,7 @@ open class ArrayOfNumberOnly: Codable {
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: String.self)
|
||||
|
||||
arrayNumber = try container.decodeArrayIfPresent(Double.self, forKey: "ArrayNumber")
|
||||
arrayNumber = try container.decodeIfPresent([Double].self, forKey: "ArrayNumber")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,13 @@ open class ArrayTest: Codable {
|
||||
public var arrayArrayOfModel: [[ReadOnlyFirst]]?
|
||||
|
||||
|
||||
|
||||
public init(arrayOfString: [String]?, arrayArrayOfInteger: [[Int64]]?, arrayArrayOfModel: [[ReadOnlyFirst]]?) {
|
||||
self.arrayOfString = arrayOfString
|
||||
self.arrayArrayOfInteger = arrayArrayOfInteger
|
||||
self.arrayArrayOfModel = arrayArrayOfModel
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -28,9 +30,9 @@ open class ArrayTest: Codable {
|
||||
|
||||
var container = encoder.container(keyedBy: String.self)
|
||||
|
||||
try container.encodeArrayIfPresent(arrayOfString, forKey: "array_of_string")
|
||||
try container.encodeArrayIfPresent(arrayArrayOfInteger, forKey: "array_array_of_integer")
|
||||
try container.encodeArrayIfPresent(arrayArrayOfModel, forKey: "array_array_of_model")
|
||||
try container.encodeIfPresent(arrayOfString, forKey: "array_of_string")
|
||||
try container.encodeIfPresent(arrayArrayOfInteger, forKey: "array_array_of_integer")
|
||||
try container.encodeIfPresent(arrayArrayOfModel, forKey: "array_array_of_model")
|
||||
}
|
||||
|
||||
// Decodable protocol methods
|
||||
@@ -38,9 +40,9 @@ open class ArrayTest: Codable {
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: String.self)
|
||||
|
||||
arrayOfString = try container.decodeArrayIfPresent(String.self, forKey: "array_of_string")
|
||||
arrayArrayOfInteger = try container.decodeArrayIfPresent([Int64].self, forKey: "array_array_of_integer")
|
||||
arrayArrayOfModel = try container.decodeArrayIfPresent([ReadOnlyFirst].self, forKey: "array_array_of_model")
|
||||
arrayOfString = try container.decodeIfPresent([String].self, forKey: "array_of_string")
|
||||
arrayArrayOfInteger = try container.decodeIfPresent([[Int64]].self, forKey: "array_array_of_integer")
|
||||
arrayArrayOfModel = try container.decodeIfPresent([[ReadOnlyFirst]].self, forKey: "array_array_of_model")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ open class Capitalization: Codable {
|
||||
public var ATT_NAME: String?
|
||||
|
||||
|
||||
|
||||
public init(smallCamel: String?, capitalCamel: String?, smallSnake: String?, capitalSnake: String?, sCAETHFlowPoints: String?, ATT_NAME: String?) {
|
||||
self.smallCamel = smallCamel
|
||||
self.capitalCamel = capitalCamel
|
||||
@@ -28,6 +29,7 @@ open class Capitalization: Codable {
|
||||
self.sCAETHFlowPoints = sCAETHFlowPoints
|
||||
self.ATT_NAME = ATT_NAME
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -14,9 +14,7 @@ open class Cat: Animal {
|
||||
public var declawed: Bool?
|
||||
|
||||
|
||||
public init(declawed: Bool?) {
|
||||
self.declawed = declawed
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -29,10 +27,11 @@ open class Cat: Animal {
|
||||
|
||||
// Decodable protocol methods
|
||||
|
||||
public override required init(from decoder: Decoder) throws {
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: String.self)
|
||||
|
||||
declawed = try container.decodeIfPresent(Bool.self, forKey: "declawed")
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,12 @@ open class Category: Codable {
|
||||
public var name: String?
|
||||
|
||||
|
||||
|
||||
public init(id: Int64?, name: String?) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -15,9 +15,11 @@ open class ClassModel: Codable {
|
||||
public var _class: String?
|
||||
|
||||
|
||||
|
||||
public init(_class: String?) {
|
||||
self._class = _class
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ open class Client: Codable {
|
||||
public var client: String?
|
||||
|
||||
|
||||
|
||||
public init(client: String?) {
|
||||
self.client = client
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -14,9 +14,7 @@ open class Dog: Animal {
|
||||
public var breed: String?
|
||||
|
||||
|
||||
public init(breed: String?) {
|
||||
self.breed = breed
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -29,10 +27,11 @@ open class Dog: Animal {
|
||||
|
||||
// Decodable protocol methods
|
||||
|
||||
public override required init(from decoder: Decoder) throws {
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: String.self)
|
||||
|
||||
breed = try container.decodeIfPresent(String.self, forKey: "breed")
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,12 @@ open class EnumArrays: Codable {
|
||||
public var arrayEnum: [ArrayEnum]?
|
||||
|
||||
|
||||
|
||||
public init(justSymbol: JustSymbol?, arrayEnum: [ArrayEnum]?) {
|
||||
self.justSymbol = justSymbol
|
||||
self.arrayEnum = arrayEnum
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -35,7 +37,7 @@ open class EnumArrays: Codable {
|
||||
var container = encoder.container(keyedBy: String.self)
|
||||
|
||||
try container.encodeIfPresent(justSymbol, forKey: "just_symbol")
|
||||
try container.encodeArrayIfPresent(arrayEnum, forKey: "array_enum")
|
||||
try container.encodeIfPresent(arrayEnum, forKey: "array_enum")
|
||||
}
|
||||
|
||||
// Decodable protocol methods
|
||||
@@ -43,8 +45,8 @@ open class EnumArrays: Codable {
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: String.self)
|
||||
|
||||
justSymbol = try container.decodeIfPresent(String.self, forKey: "just_symbol")
|
||||
arrayEnum = try container.decodeArrayIfPresent(String.self, forKey: "array_enum")
|
||||
justSymbol = try container.decodeIfPresent(JustSymbol.self, forKey: "just_symbol")
|
||||
arrayEnum = try container.decodeIfPresent([ArrayEnum].self, forKey: "array_enum")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,14 @@ open class EnumTest: Codable {
|
||||
public var outerEnum: OuterEnum?
|
||||
|
||||
|
||||
|
||||
public init(enumString: EnumString?, enumInteger: EnumInteger?, enumNumber: EnumNumber?, outerEnum: OuterEnum?) {
|
||||
self.enumString = enumString
|
||||
self.enumInteger = enumInteger
|
||||
self.enumNumber = enumNumber
|
||||
self.outerEnum = outerEnum
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -54,9 +56,9 @@ open class EnumTest: Codable {
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: String.self)
|
||||
|
||||
enumString = try container.decodeIfPresent(String.self, forKey: "enum_string")
|
||||
enumInteger = try container.decodeIfPresent(Int.self, forKey: "enum_integer")
|
||||
enumNumber = try container.decodeIfPresent(Double.self, forKey: "enum_number")
|
||||
enumString = try container.decodeIfPresent(EnumString.self, forKey: "enum_string")
|
||||
enumInteger = try container.decodeIfPresent(EnumInteger.self, forKey: "enum_integer")
|
||||
enumNumber = try container.decodeIfPresent(EnumNumber.self, forKey: "enum_number")
|
||||
outerEnum = try container.decodeIfPresent(OuterEnum.self, forKey: "outerEnum")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ open class FormatTest: Codable {
|
||||
public var password: String
|
||||
|
||||
|
||||
|
||||
public init(integer: Int?, int32: Int?, int64: Int64?, number: Double, float: Float?, double: Double?, string: String?, byte: Data, binary: Data?, date: Date, dateTime: Date?, uuid: UUID?, password: String) {
|
||||
self.integer = integer
|
||||
self.int32 = int32
|
||||
@@ -41,6 +42,7 @@ open class FormatTest: Codable {
|
||||
self.uuid = uuid
|
||||
self.password = password
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -15,10 +15,12 @@ open class HasOnlyReadOnly: Codable {
|
||||
public var foo: String?
|
||||
|
||||
|
||||
|
||||
public init(bar: String?, foo: String?) {
|
||||
self.bar = bar
|
||||
self.foo = foo
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ open class List: Codable {
|
||||
public var _123List: String?
|
||||
|
||||
|
||||
|
||||
public init(_123List: String?) {
|
||||
self._123List = _123List
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -19,10 +19,12 @@ open class MapTest: Codable {
|
||||
public var mapOfEnumString: [String:String]?
|
||||
|
||||
|
||||
|
||||
public init(mapMapOfString: [String:[String:String]]?, mapOfEnumString: [String:String]?) {
|
||||
self.mapMapOfString = mapMapOfString
|
||||
self.mapOfEnumString = mapOfEnumString
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -16,11 +16,13 @@ open class MixedPropertiesAndAdditionalPropertiesClass: Codable {
|
||||
public var map: [String:Animal]?
|
||||
|
||||
|
||||
|
||||
public init(uuid: UUID?, dateTime: Date?, map: [String:Animal]?) {
|
||||
self.uuid = uuid
|
||||
self.dateTime = dateTime
|
||||
self.map = map
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -16,10 +16,12 @@ open class Model200Response: Codable {
|
||||
public var _class: String?
|
||||
|
||||
|
||||
|
||||
public init(name: Int?, _class: String?) {
|
||||
self.name = name
|
||||
self._class = _class
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -18,12 +18,14 @@ open class Name: Codable {
|
||||
public var _123Number: Int?
|
||||
|
||||
|
||||
|
||||
public init(name: Int, snakeCase: Int?, property: String?, _123Number: Int?) {
|
||||
self.name = name
|
||||
self.snakeCase = snakeCase
|
||||
self.property = property
|
||||
self._123Number = _123Number
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ open class NumberOnly: Codable {
|
||||
public var justNumber: Double?
|
||||
|
||||
|
||||
|
||||
public init(justNumber: Double?) {
|
||||
self.justNumber = justNumber
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ open class Order: Codable {
|
||||
public var complete: Bool?
|
||||
|
||||
|
||||
|
||||
public init(id: Int64?, petId: Int64?, quantity: Int?, shipDate: Date?, status: Status?, complete: Bool?) {
|
||||
self.id = id
|
||||
self.petId = petId
|
||||
@@ -33,6 +34,7 @@ open class Order: Codable {
|
||||
self.status = status
|
||||
self.complete = complete
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -57,7 +59,7 @@ open class Order: Codable {
|
||||
petId = try container.decodeIfPresent(Int64.self, forKey: "petId")
|
||||
quantity = try container.decodeIfPresent(Int.self, forKey: "quantity")
|
||||
shipDate = try container.decodeIfPresent(Date.self, forKey: "shipDate")
|
||||
status = try container.decodeIfPresent(String.self, forKey: "status")
|
||||
status = try container.decodeIfPresent(Status.self, forKey: "status")
|
||||
complete = try container.decodeIfPresent(Bool.self, forKey: "complete")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ open class OuterBoolean: Codable {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -16,11 +16,13 @@ open class OuterComposite: Codable {
|
||||
public var myBoolean: OuterBoolean?
|
||||
|
||||
|
||||
|
||||
public init(myNumber: OuterNumber?, myString: OuterString?, myBoolean: OuterBoolean?) {
|
||||
self.myNumber = myNumber
|
||||
self.myString = myString
|
||||
self.myBoolean = myBoolean
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ open class OuterNumber: Codable {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ open class OuterString: Codable {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ open class Pet: Codable {
|
||||
public var status: Status?
|
||||
|
||||
|
||||
|
||||
public init(id: Int64?, category: Category?, name: String, photoUrls: [String], tags: [Tag]?, status: Status?) {
|
||||
self.id = id
|
||||
self.category = category
|
||||
@@ -33,6 +34,7 @@ open class Pet: Codable {
|
||||
self.tags = tags
|
||||
self.status = status
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
@@ -43,8 +45,8 @@ open class Pet: Codable {
|
||||
try container.encodeIfPresent(id, forKey: "id")
|
||||
try container.encodeIfPresent(category, forKey: "category")
|
||||
try container.encode(name, forKey: "name")
|
||||
try container.encodeArray(photoUrls, forKey: "photoUrls")
|
||||
try container.encodeArrayIfPresent(tags, forKey: "tags")
|
||||
try container.encode(photoUrls, forKey: "photoUrls")
|
||||
try container.encodeIfPresent(tags, forKey: "tags")
|
||||
try container.encodeIfPresent(status, forKey: "status")
|
||||
}
|
||||
|
||||
@@ -56,9 +58,9 @@ open class Pet: Codable {
|
||||
id = try container.decodeIfPresent(Int64.self, forKey: "id")
|
||||
category = try container.decodeIfPresent(Category.self, forKey: "category")
|
||||
name = try container.decode(String.self, forKey: "name")
|
||||
photoUrls = try container.decodeArray(String.self, forKey: "photoUrls")
|
||||
tags = try container.decodeArrayIfPresent(Tag.self, forKey: "tags")
|
||||
status = try container.decodeIfPresent(String.self, forKey: "status")
|
||||
photoUrls = try container.decode([String].self, forKey: "photoUrls")
|
||||
tags = try container.decodeIfPresent([Tag].self, forKey: "tags")
|
||||
status = try container.decodeIfPresent(Status.self, forKey: "status")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,12 @@ open class ReadOnlyFirst: Codable {
|
||||
public var baz: String?
|
||||
|
||||
|
||||
|
||||
public init(bar: String?, baz: String?) {
|
||||
self.bar = bar
|
||||
self.baz = baz
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -15,9 +15,11 @@ open class Return: Codable {
|
||||
public var _return: Int?
|
||||
|
||||
|
||||
|
||||
public init(_return: Int?) {
|
||||
self._return = _return
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ open class SpecialModelName: Codable {
|
||||
public var specialPropertyName: Int64?
|
||||
|
||||
|
||||
|
||||
public init(specialPropertyName: Int64?) {
|
||||
self.specialPropertyName = specialPropertyName
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -15,10 +15,12 @@ open class Tag: Codable {
|
||||
public var name: String?
|
||||
|
||||
|
||||
|
||||
public init(id: Int64?, name: String?) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ open class User: Codable {
|
||||
public var userStatus: Int?
|
||||
|
||||
|
||||
|
||||
public init(id: Int64?, username: String?, firstName: String?, lastName: String?, email: String?, password: String?, phone: String?, userStatus: Int?) {
|
||||
self.id = id
|
||||
self.username = username
|
||||
@@ -32,6 +33,7 @@ open class User: Codable {
|
||||
self.phone = phone
|
||||
self.userStatus = userStatus
|
||||
}
|
||||
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
|
||||
@@ -8,11 +8,3 @@ target 'SwaggerClient' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |configuration|
|
||||
configuration.build_settings['SWIFT_VERSION'] = "3.0"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
PODS:
|
||||
- Alamofire (4.5.0)
|
||||
- Alamofire (4.5.1)
|
||||
- PetstoreClient (0.0.1):
|
||||
- Alamofire (~> 4.5)
|
||||
- RxSwift (~> 3.4.1)
|
||||
- RxSwift (3.4.1)
|
||||
- Alamofire (~> 4.5.0)
|
||||
- RxSwift (~> 4.0)
|
||||
- RxSwift (4.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- PetstoreClient (from `../`)
|
||||
@@ -13,10 +13,10 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Alamofire: f28cdffd29de33a7bfa022cbd63ae95a27fae140
|
||||
PetstoreClient: 23a1f7941fd65b9ebc1806a1646b3ff415371e34
|
||||
RxSwift: 656f8fbeca5bc372121a72d9ebdd3cd3bc0ffade
|
||||
Alamofire: 2d95912bf4c34f164fdfc335872e8c312acaea4a
|
||||
PetstoreClient: 321849311dc2fb14d6801d393b57c016953b6319
|
||||
RxSwift: fd680d75283beb5e2559486f3c0ff852f0d35334
|
||||
|
||||
PODFILE CHECKSUM: 417049e9ed0e4680602b34d838294778389bd418
|
||||
PODFILE CHECKSUM: cedb3058b02f4776d7c31f6d92ae2f674fdf424d
|
||||
|
||||
COCOAPODS: 1.1.1
|
||||
COCOAPODS: 1.3.1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||

|
||||

|
||||
|
||||
[](https://travis-ci.org/Alamofire/Alamofire)
|
||||
[](https://img.shields.io/cocoapods/v/Alamofire.svg)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
[](http://cocoadocs.org/docsets/Alamofire)
|
||||
[](https://alamofire.github.io/Alamofire)
|
||||
[](http://twitter.com/AlamofireSF)
|
||||
[](https://gitter.im/Alamofire/Alamofire?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
@@ -45,7 +45,7 @@ Alamofire is an HTTP networking library written in Swift.
|
||||
- [x] TLS Certificate and Public Key Pinning
|
||||
- [x] Network Reachability
|
||||
- [x] Comprehensive Unit and Integration Test Coverage
|
||||
- [x] [Complete Documentation](http://cocoadocs.org/docsets/Alamofire)
|
||||
- [x] [Complete Documentation](https://alamofire.github.io/Alamofire)
|
||||
|
||||
## Component Libraries
|
||||
|
||||
@@ -57,8 +57,8 @@ In order to keep Alamofire focused specifically on core networking implementatio
|
||||
## Requirements
|
||||
|
||||
- iOS 8.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+
|
||||
- Xcode 8.1, 8.2, 8.3, and 9.0
|
||||
- Swift 3.0, 3.1, 3.2, and 4.0
|
||||
- Xcode 8.3+
|
||||
- Swift 3.1+
|
||||
|
||||
## Migration Guides
|
||||
|
||||
@@ -84,7 +84,7 @@ In order to keep Alamofire focused specifically on core networking implementatio
|
||||
$ gem install cocoapods
|
||||
```
|
||||
|
||||
> CocoaPods 1.1.0+ is required to build Alamofire 4.0.0+.
|
||||
> CocoaPods 1.1+ is required to build Alamofire 4.0+.
|
||||
|
||||
To integrate Alamofire into your Xcode project using CocoaPods, specify it in your `Podfile`:
|
||||
|
||||
@@ -94,7 +94,7 @@ platform :ios, '10.0'
|
||||
use_frameworks!
|
||||
|
||||
target '<Your Target Name>' do
|
||||
pod 'Alamofire', '~> 4.4'
|
||||
pod 'Alamofire', '~> 4.5'
|
||||
end
|
||||
```
|
||||
|
||||
@@ -118,7 +118,7 @@ $ brew install carthage
|
||||
To integrate Alamofire into your Xcode project using Carthage, specify it in your `Cartfile`:
|
||||
|
||||
```ogdl
|
||||
github "Alamofire/Alamofire" ~> 4.4
|
||||
github "Alamofire/Alamofire" ~> 4.5
|
||||
```
|
||||
|
||||
Run `carthage update` to build the framework and drag the built `Alamofire.framework` into your Xcode project.
|
||||
@@ -736,7 +736,7 @@ When sending relatively small amounts of data to a server using JSON or URL enco
|
||||
#### Uploading Data
|
||||
|
||||
```swift
|
||||
let imageData = UIPNGRepresentation(image)!
|
||||
let imageData = UIImagePNGRepresentation(image)!
|
||||
|
||||
Alamofire.upload(imageData, to: "https://httpbin.org/post").responseJSON { response in
|
||||
debugPrint(response)
|
||||
@@ -1812,10 +1812,15 @@ There are some important things to remember when using network reachability to d
|
||||
The following radars have some effect on the current implementation of Alamofire.
|
||||
|
||||
- [`rdar://21349340`](http://www.openradar.me/radar?id=5517037090635776) - Compiler throwing warning due to toll-free bridging issue in test case
|
||||
- [`rdar://26761490`](http://www.openradar.me/radar?id=5010235949318144) - Swift string interpolation causing memory leak with common usage
|
||||
- `rdar://26870455` - Background URL Session Configurations do not work in the simulator
|
||||
- `rdar://26849668` - Some URLProtocol APIs do not properly handle `URLRequest`
|
||||
|
||||
## Resolved Radars
|
||||
|
||||
The following radars have been resolved over time after being filed against the Alamofire project.
|
||||
|
||||
- [`rdar://26761490`](http://www.openradar.me/radar?id=5010235949318144) - Swift string interpolation causing memory leak with common usage (Resolved on 9/1/17 in Xcode 9 beta 6).
|
||||
|
||||
## FAQ
|
||||
|
||||
### What's the origin of the name Alamofire?
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// AFError.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Alamofire.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// DispatchQueue+Alamofire.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// MultipartFormData.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// NetworkReachabilityManager.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Notifications.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// ParameterEncoding.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -223,9 +223,9 @@ public struct URLEncoding: ParameterEncoding {
|
||||
let endIndex = string.index(index, offsetBy: batchSize, limitedBy: string.endIndex) ?? string.endIndex
|
||||
let range = startIndex..<endIndex
|
||||
|
||||
let substring = string.substring(with: range)
|
||||
let substring = string[range]
|
||||
|
||||
escaped += substring.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? substring
|
||||
escaped += substring.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? String(substring)
|
||||
|
||||
index = endIndex
|
||||
}
|
||||
@@ -241,11 +241,7 @@ public struct URLEncoding: ParameterEncoding {
|
||||
let value = parameters[key]!
|
||||
components += queryComponents(fromKey: key, value: value)
|
||||
}
|
||||
#if swift(>=4.0)
|
||||
return components.map { "\($0.0)=\($0.1)" }.joined(separator: "&")
|
||||
#else
|
||||
return components.map { "\($0)=\($1)" }.joined(separator: "&")
|
||||
#endif
|
||||
}
|
||||
|
||||
private func encodesParametersInURL(with method: HTTPMethod) -> Bool {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Request.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -293,11 +293,12 @@ extension Request: CustomDebugStringConvertible {
|
||||
|
||||
if let credentials = credentialStorage.credentials(for: protectionSpace)?.values {
|
||||
for credential in credentials {
|
||||
components.append("-u \(credential.user!):\(credential.password!)")
|
||||
guard let user = credential.user, let password = credential.password else { continue }
|
||||
components.append("-u \(user):\(password)")
|
||||
}
|
||||
} else {
|
||||
if let credential = delegate.credential {
|
||||
components.append("-u \(credential.user!):\(credential.password!)")
|
||||
if let credential = delegate.credential, let user = credential.user, let password = credential.password {
|
||||
components.append("-u \(user):\(password)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +309,12 @@ extension Request: CustomDebugStringConvertible {
|
||||
let cookies = cookieStorage.cookies(for: url), !cookies.isEmpty
|
||||
{
|
||||
let string = cookies.reduce("") { $0 + "\($1.name)=\($1.value);" }
|
||||
|
||||
#if swift(>=3.2)
|
||||
components.append("-b \"\(string[..<string.index(before: string.endIndex)])\"")
|
||||
#else
|
||||
components.append("-b \"\(string.substring(to: string.characters.index(before: string.endIndex)))\"")
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Response.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// ResponseSerialization.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Result.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// ServerTrustPolicy.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// SessionDelegate.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// SessionManager.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -58,18 +58,10 @@ open class SessionManager {
|
||||
let acceptEncoding: String = "gzip;q=1.0, compress;q=0.5"
|
||||
|
||||
// Accept-Language HTTP Header; see https://tools.ietf.org/html/rfc7231#section-5.3.5
|
||||
#if swift(>=4.0)
|
||||
let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { enumeratedLanguage in
|
||||
let (index, languageCode) = enumeratedLanguage
|
||||
let quality = 1.0 - (Double(index) * 0.1)
|
||||
return "\(languageCode);q=\(quality)"
|
||||
}.joined(separator: ", ")
|
||||
#else
|
||||
let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { index, languageCode in
|
||||
let quality = 1.0 - (Double(index) * 0.1)
|
||||
return "\(languageCode);q=\(quality)"
|
||||
}.joined(separator: ", ")
|
||||
#endif
|
||||
|
||||
// User-Agent Header; see https://tools.ietf.org/html/rfc7231#section-5.5.3
|
||||
// Example: `iOS Example/1.0 (org.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// TaskDelegate.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -40,17 +40,30 @@ open class TaskDelegate: NSObject {
|
||||
public var error: Error?
|
||||
|
||||
var task: URLSessionTask? {
|
||||
didSet { reset() }
|
||||
set {
|
||||
taskLock.lock(); defer { taskLock.unlock() }
|
||||
_task = newValue
|
||||
}
|
||||
get {
|
||||
taskLock.lock(); defer { taskLock.unlock() }
|
||||
return _task
|
||||
}
|
||||
}
|
||||
|
||||
var initialResponseTime: CFAbsoluteTime?
|
||||
var credential: URLCredential?
|
||||
var metrics: AnyObject? // URLSessionTaskMetrics
|
||||
|
||||
private var _task: URLSessionTask? {
|
||||
didSet { reset() }
|
||||
}
|
||||
|
||||
private let taskLock = NSLock()
|
||||
|
||||
// MARK: Lifecycle
|
||||
|
||||
init(task: URLSessionTask?) {
|
||||
self.task = task
|
||||
_task = task
|
||||
|
||||
self.queue = {
|
||||
let operationQueue = OperationQueue()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Timeline.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Validation.swift
|
||||
//
|
||||
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -48,7 +48,13 @@ extension Request {
|
||||
init?(_ string: String) {
|
||||
let components: [String] = {
|
||||
let stripped = string.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
#if swift(>=3.2)
|
||||
let split = stripped[..<(stripped.range(of: ";")?.lowerBound ?? stripped.endIndex)]
|
||||
#else
|
||||
let split = stripped.substring(to: stripped.range(of: ";")?.lowerBound ?? stripped.endIndex)
|
||||
#endif
|
||||
|
||||
return split.components(separatedBy: "/")
|
||||
}()
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
"license": "Proprietary",
|
||||
"homepage": "https://github.com/swagger-api/swagger-codegen",
|
||||
"summary": "PetstoreClient",
|
||||
"source_files": "PetstoreClient/Classes/Swaggers/**/*.swift",
|
||||
"source_files": "PetstoreClient/Classes/**/*.swift",
|
||||
"dependencies": {
|
||||
"RxSwift": [
|
||||
"~> 3.4.1"
|
||||
"~> 4.0"
|
||||
],
|
||||
"Alamofire": [
|
||||
"~> 4.5"
|
||||
"~> 4.5.0"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
PODS:
|
||||
- Alamofire (4.5.0)
|
||||
- Alamofire (4.5.1)
|
||||
- PetstoreClient (0.0.1):
|
||||
- Alamofire (~> 4.5)
|
||||
- RxSwift (~> 3.4.1)
|
||||
- RxSwift (3.4.1)
|
||||
- Alamofire (~> 4.5.0)
|
||||
- RxSwift (~> 4.0)
|
||||
- RxSwift (4.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- PetstoreClient (from `../`)
|
||||
@@ -13,10 +13,10 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Alamofire: f28cdffd29de33a7bfa022cbd63ae95a27fae140
|
||||
PetstoreClient: 23a1f7941fd65b9ebc1806a1646b3ff415371e34
|
||||
RxSwift: 656f8fbeca5bc372121a72d9ebdd3cd3bc0ffade
|
||||
Alamofire: 2d95912bf4c34f164fdfc335872e8c312acaea4a
|
||||
PetstoreClient: 321849311dc2fb14d6801d393b57c016953b6319
|
||||
RxSwift: fd680d75283beb5e2559486f3c0ff852f0d35334
|
||||
|
||||
PODFILE CHECKSUM: 417049e9ed0e4680602b34d838294778389bd418
|
||||
PODFILE CHECKSUM: cedb3058b02f4776d7c31f6d92ae2f674fdf424d
|
||||
|
||||
COCOAPODS: 1.1.1
|
||||
COCOAPODS: 1.3.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -80,7 +80,7 @@ struct Bag<T> : CustomDebugStringConvertible {
|
||||
}
|
||||
|
||||
if _pairs.count < arrayDictionaryMaxSize {
|
||||
_pairs.append(key: key, value: element)
|
||||
_pairs.append((key: key, value: element))
|
||||
return key
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ struct PriorityQueue<Element> {
|
||||
private mutating func removeAt(_ index: Int) {
|
||||
let removingLast = index == _elements.count - 1
|
||||
if !removingLast {
|
||||
#if swift(>=3.2)
|
||||
_elements.swapAt(index, _elements.count - 1)
|
||||
#else
|
||||
swap(&_elements[index], &_elements[_elements.count - 1])
|
||||
#endif
|
||||
}
|
||||
|
||||
_ = _elements.popLast()
|
||||
@@ -72,8 +76,11 @@ struct PriorityQueue<Element> {
|
||||
while unbalancedIndex > 0 {
|
||||
let parentIndex = (unbalancedIndex - 1) / 2
|
||||
guard _hasHigherPriority(_elements[unbalancedIndex], _elements[parentIndex]) else { break }
|
||||
|
||||
#if swift(>=3.2)
|
||||
_elements.swapAt(unbalancedIndex, parentIndex)
|
||||
#else
|
||||
swap(&_elements[unbalancedIndex], &_elements[parentIndex])
|
||||
#endif
|
||||
unbalancedIndex = parentIndex
|
||||
}
|
||||
}
|
||||
@@ -99,7 +106,11 @@ struct PriorityQueue<Element> {
|
||||
|
||||
guard highestPriorityIndex != unbalancedIndex else { break }
|
||||
|
||||
#if swift(>=3.2)
|
||||
_elements.swapAt(highestPriorityIndex, unbalancedIndex)
|
||||
#else
|
||||
swap(&_elements[highestPriorityIndex], &_elements[unbalancedIndex])
|
||||
#endif
|
||||
unbalancedIndex = highestPriorityIndex
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,8 @@
|
||||
|
||||
[](https://travis-ci.org/ReactiveX/RxSwift)   [](https://github.com/Carthage/Carthage) [](https://github.com/apple/swift-package-manager)
|
||||
|
||||
## About Rx
|
||||
|
||||
**:warning: This readme describes RxSwift 3.0 version that requires Swift 3.0.**
|
||||
|
||||
**:warning: If you are looking for Swift 2.3 compatible version, please take a look at RxSwift ~> 2.0 versions and [swift-2.3](https://github.com/ReactiveX/RxSwift/tree/rxswift-2.0) branch.**
|
||||
* RxSwift 4.x / Swift 4.x can be found in [**rxswift4.0-swift4.0** branch](https://github.com/ReactiveX/RxSwift/tree/rxswift4.0-swift4.0).
|
||||
* RxSwift 3.x / Swift 3.x can be found in [**master** branch](https://github.com/ReactiveX/RxSwift/tree/master).
|
||||
|
||||
Rx is a [generic abstraction of computation](https://youtu.be/looJcaeboBY) expressed through `Observable<Element>` interface.
|
||||
|
||||
@@ -110,6 +107,7 @@ searchResults
|
||||
|
||||
* Xcode 8.0
|
||||
* Swift 3.0
|
||||
* Swift 2.3 ([use `rxswift-2.0` branch](https://github.com/ReactiveX/RxSwift/tree/rxswift-2.0) instead)
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -183,6 +181,12 @@ let package = Package(
|
||||
$ swift build
|
||||
```
|
||||
|
||||
To build or test a module with RxTest dependency, set `TEST=1`. ([RxSwift >= 3.4.2](https://github.com/ReactiveX/RxSwift/releases/tag/3.4.2))
|
||||
|
||||
```bash
|
||||
$ TEST=1 swift test
|
||||
```
|
||||
|
||||
### Manually using git submodules
|
||||
|
||||
* Add RxSwift as a submodule
|
||||
@@ -199,6 +203,8 @@ $ git submodule add git@github.com:ReactiveX/RxSwift.git
|
||||
|
||||
* [http://reactivex.io/](http://reactivex.io/)
|
||||
* [Reactive Extensions GitHub (GitHub)](https://github.com/Reactive-Extensions)
|
||||
* [RxSwift RayWenderlich.com Book](https://store.raywenderlich.com/products/rxswift)
|
||||
* [Boxue.io RxSwift Online Course](https://boxueio.com/series/rxswift-101) (Chinese 🇨🇳)
|
||||
* [Erik Meijer (Wikipedia)](http://en.wikipedia.org/wiki/Erik_Meijer_%28computer_scientist%29)
|
||||
* [Expert to Expert: Brian Beckman and Erik Meijer - Inside the .NET Reactive Framework (Rx) (video)](https://youtu.be/looJcaeboBY)
|
||||
* [Reactive Programming Overview (Jafar Husain from Netflix)](https://www.youtube.com/watch?v=dwP1TNXE6fc)
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
//
|
||||
// SynchronizedSubscribeType.swift
|
||||
// RxSwift
|
||||
//
|
||||
// Created by Krunoslav Zaher on 10/25/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
protocol SynchronizedSubscribeType : class, ObservableType, Lock {
|
||||
func _synchronized_subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E
|
||||
}
|
||||
|
||||
extension SynchronizedSubscribeType {
|
||||
func synchronizedSubscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E {
|
||||
lock(); defer { unlock() }
|
||||
return _synchronized_subscribe(observer)
|
||||
}
|
||||
}
|
||||
@@ -35,15 +35,179 @@ extension Observable {
|
||||
}
|
||||
}
|
||||
|
||||
extension ObservableType {
|
||||
/**
|
||||
|
||||
Projects each element of an observable sequence into a new form by incorporating the element's index.
|
||||
|
||||
- seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html)
|
||||
|
||||
- parameter selector: A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
|
||||
- returns: An observable sequence whose elements are the result of invoking the transform function on each element of source.
|
||||
*/
|
||||
@available(*, deprecated, message: "Please use enumerated().map()")
|
||||
public func mapWithIndex<R>(_ selector: @escaping (E, Int) throws -> R)
|
||||
-> Observable<R> {
|
||||
return enumerated().map { try selector($0.element, $0.index) }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Projects each element of an observable sequence to an observable sequence by incorporating the element's index and merges the resulting observable sequences into one observable sequence.
|
||||
|
||||
- seealso: [flatMap operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html)
|
||||
|
||||
- parameter selector: A transform function to apply to each element; the second parameter of the function represents the index of the source element.
|
||||
- returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence.
|
||||
*/
|
||||
@available(*, deprecated, message: "Please use enumerated().flatMap()")
|
||||
public func flatMapWithIndex<O: ObservableConvertibleType>(_ selector: @escaping (E, Int) throws -> O)
|
||||
-> Observable<O.E> {
|
||||
return enumerated().flatMap { try selector($0.element, $0.index) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
|
||||
The element's index is used in the logic of the predicate function.
|
||||
|
||||
- seealso: [skipWhile operator on reactivex.io](http://reactivex.io/documentation/operators/skipwhile.html)
|
||||
|
||||
- parameter predicate: A function to test each element for a condition; the second parameter of the function represents the index of the source element.
|
||||
- returns: An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
|
||||
*/
|
||||
@available(*, deprecated, message: "Please use enumerated().skipWhile().map()")
|
||||
public func skipWhileWithIndex(_ predicate: @escaping (E, Int) throws -> Bool) -> Observable<E> {
|
||||
return enumerated().skipWhile { try predicate($0.element, $0.index) }.map { $0.element }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Returns elements from an observable sequence as long as a specified condition is true.
|
||||
|
||||
The element's index is used in the logic of the predicate function.
|
||||
|
||||
- seealso: [takeWhile operator on reactivex.io](http://reactivex.io/documentation/operators/takewhile.html)
|
||||
|
||||
- parameter predicate: A function to test each element for a condition; the second parameter of the function represents the index of the source element.
|
||||
- returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes.
|
||||
*/
|
||||
@available(*, deprecated, message: "Please use enumerated().takeWhile().map()")
|
||||
public func takeWhileWithIndex(_ predicate: @escaping (E, Int) throws -> Bool) -> Observable<E> {
|
||||
return enumerated().takeWhile { try predicate($0.element, $0.index) }.map { $0.element }
|
||||
}
|
||||
}
|
||||
|
||||
extension Disposable {
|
||||
/// Deprecated in favor of `disposed(by:)`
|
||||
///
|
||||
/// **@available(\*, deprecated, message="use disposed(by:) instead")**
|
||||
///
|
||||
/// Adds `self` to `bag`.
|
||||
///
|
||||
/// - parameter bag: `DisposeBag` to add `self` to.
|
||||
@available(*, deprecated, message: "use disposed(by:) instead", renamed: "disposed(by:)")
|
||||
public func addDisposableTo(_ bag: DisposeBag) {
|
||||
disposed(by: bag)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension ObservableType {
|
||||
|
||||
/**
|
||||
Returns an observable sequence that shares a single subscription to the underlying sequence, and immediately upon subscription replays latest element in buffer.
|
||||
|
||||
This operator is a specialization of replay which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
|
||||
|
||||
- seealso: [shareReplay operator on reactivex.io](http://reactivex.io/documentation/operators/replay.html)
|
||||
|
||||
- returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
|
||||
*/
|
||||
@available(*, deprecated, message: "use share(replay: 1) instead", renamed: "share(replay:)")
|
||||
public func shareReplayLatestWhileConnected()
|
||||
-> Observable<E> {
|
||||
return share(replay: 1, scope: .whileConnected)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension ObservableType {
|
||||
|
||||
/**
|
||||
Returns an observable sequence that shares a single subscription to the underlying sequence, and immediately upon subscription replays maximum number of elements in buffer.
|
||||
|
||||
This operator is a specialization of replay which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
|
||||
|
||||
- seealso: [shareReplay operator on reactivex.io](http://reactivex.io/documentation/operators/replay.html)
|
||||
|
||||
- parameter bufferSize: Maximum element count of the replay buffer.
|
||||
- returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
|
||||
*/
|
||||
@available(*, deprecated, message: "Suggested replacement is `share(replay: 1)`. In case old 3.x behavior of `shareReplay` is required please use `share(replay: 1, scope: .forever)` instead.", renamed: "share(replay:)")
|
||||
public func shareReplay(_ bufferSize: Int)
|
||||
-> Observable<E> {
|
||||
return self.share(replay: bufferSize, scope: .forever)
|
||||
}
|
||||
}
|
||||
|
||||
/// Variable is a wrapper for `BehaviorSubject`.
|
||||
///
|
||||
/// Unlike `BehaviorSubject` it can't terminate with error, and when variable is deallocated
|
||||
/// it will complete its observable sequence (`asObservable`).
|
||||
public final class Variable<Element> {
|
||||
|
||||
public typealias E = Element
|
||||
|
||||
private let _subject: BehaviorSubject<Element>
|
||||
|
||||
private var _lock = SpinLock()
|
||||
|
||||
// state
|
||||
private var _value: E
|
||||
|
||||
#if DEBUG
|
||||
fileprivate let _synchronizationTracker = SynchronizationTracker()
|
||||
#endif
|
||||
|
||||
/// Gets or sets current value of variable.
|
||||
///
|
||||
/// Whenever a new value is set, all the observers are notified of the change.
|
||||
///
|
||||
/// Even if the newly set value is same as the old value, observers are still notified for change.
|
||||
public var value: E {
|
||||
get {
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
return _value
|
||||
}
|
||||
set(newValue) {
|
||||
#if DEBUG
|
||||
_synchronizationTracker.register(synchronizationErrorMessage: .variable)
|
||||
defer { _synchronizationTracker.unregister() }
|
||||
#endif
|
||||
_lock.lock()
|
||||
_value = newValue
|
||||
_lock.unlock()
|
||||
|
||||
_subject.on(.next(newValue))
|
||||
}
|
||||
}
|
||||
|
||||
/// Initializes variable with initial value.
|
||||
///
|
||||
/// - parameter value: Initial variable value.
|
||||
public init(_ value: Element) {
|
||||
_value = value
|
||||
_subject = BehaviorSubject(value: value)
|
||||
}
|
||||
|
||||
/// - returns: Canonical interface for push style sequence
|
||||
public func asObservable() -> Observable<E> {
|
||||
return _subject
|
||||
}
|
||||
|
||||
deinit {
|
||||
_subject.on(.completed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ let RxCompositeFailures = "RxCompositeFailures"
|
||||
public enum RxError
|
||||
: Swift.Error
|
||||
, CustomDebugStringConvertible {
|
||||
/// Unknown error occured.
|
||||
/// Unknown error occurred.
|
||||
case unknown
|
||||
/// Performing an action on disposed object.
|
||||
case disposed(object: AnyObject)
|
||||
@@ -34,11 +34,11 @@ extension RxError {
|
||||
public var debugDescription: String {
|
||||
switch self {
|
||||
case .unknown:
|
||||
return "Unknown error occured."
|
||||
return "Unknown error occurred."
|
||||
case .disposed(let object):
|
||||
return "Object `\(object)` was already disposed."
|
||||
case .overflow:
|
||||
return "Arithmetic overflow occured."
|
||||
return "Arithmetic overflow occurred."
|
||||
case .argumentOutOfRange:
|
||||
return "Argument out of range."
|
||||
case .noElements:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Represents an object that immediately schedules units of work.
|
||||
public protocol ImmediateSchedulerType {
|
||||
/**
|
||||
Schedules an action to be executed immediatelly.
|
||||
Schedules an action to be executed immediately.
|
||||
|
||||
- parameter state: State passed to the action to be executed.
|
||||
- parameter action: Action to be executed.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
/// Type that can be converted to observable sequence (`Observer<E>`).
|
||||
/// Type that can be converted to observable sequence (`Observable<E>`).
|
||||
public protocol ObservableConvertibleType {
|
||||
/// Type of elements in sequence.
|
||||
associatedtype E
|
||||
|
||||
@@ -6,112 +6,136 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if DEBUG
|
||||
import Foundation
|
||||
#endif
|
||||
|
||||
extension ObservableType {
|
||||
/**
|
||||
Subscribes an event handler to an observable sequence.
|
||||
|
||||
- parameter on: Action to invoke for each event in the observable sequence.
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
Subscribes an event handler to an observable sequence.
|
||||
|
||||
- parameter on: Action to invoke for each event in the observable sequence.
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func subscribe(_ on: @escaping (Event<E>) -> Void)
|
||||
-> Disposable {
|
||||
let observer = AnonymousObserver { e in
|
||||
on(e)
|
||||
}
|
||||
return self.subscribeSafe(observer)
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
/**
|
||||
Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence.
|
||||
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- parameter onError: Action to invoke upon errored termination of the observable sequence.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
|
||||
gracefully completed, errored, or if the generation is cancelled by disposing subscription).
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func subscribe(file: String = #file, line: UInt = #line, function: String = #function, onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
|
||||
-> Disposable {
|
||||
|
||||
let disposable: Disposable
|
||||
|
||||
if let disposed = onDisposed {
|
||||
disposable = Disposables.create(with: disposed)
|
||||
}
|
||||
else {
|
||||
disposable = Disposables.create()
|
||||
}
|
||||
|
||||
let observer = AnonymousObserver<E> { e in
|
||||
switch e {
|
||||
case .next(let value):
|
||||
onNext?(value)
|
||||
case .error(let e):
|
||||
if let onError = onError {
|
||||
onError(e)
|
||||
}
|
||||
else {
|
||||
print("Received unhandled error: \(file):\(line):\(function) -> \(e)")
|
||||
}
|
||||
disposable.dispose()
|
||||
case .completed:
|
||||
onCompleted?()
|
||||
disposable.dispose()
|
||||
let observer = AnonymousObserver { e in
|
||||
on(e)
|
||||
}
|
||||
}
|
||||
return Disposables.create(
|
||||
self.subscribeSafe(observer),
|
||||
disposable
|
||||
)
|
||||
return self.asObservable().subscribe(observer)
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
/**
|
||||
Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence.
|
||||
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- parameter onError: Action to invoke upon errored termination of the observable sequence.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
|
||||
gracefully completed, errored, or if the generation is cancelled by disposing subscription).
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence.
|
||||
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- parameter onError: Action to invoke upon errored termination of the observable sequence.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription).
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
|
||||
-> Disposable {
|
||||
#if DEBUG
|
||||
let disposable: Disposable
|
||||
|
||||
if let disposed = onDisposed {
|
||||
disposable = Disposables.create(with: disposed)
|
||||
}
|
||||
else {
|
||||
disposable = Disposables.create()
|
||||
}
|
||||
|
||||
let synchronizationTracker = SynchronizationTracker()
|
||||
|
||||
let disposable: Disposable
|
||||
let callStack = Thread.callStackSymbols
|
||||
|
||||
if let disposed = onDisposed {
|
||||
disposable = Disposables.create(with: disposed)
|
||||
}
|
||||
else {
|
||||
disposable = Disposables.create()
|
||||
}
|
||||
|
||||
let observer = AnonymousObserver<E> { e in
|
||||
switch e {
|
||||
case .next(let value):
|
||||
onNext?(value)
|
||||
case .error(let e):
|
||||
onError?(e)
|
||||
disposable.dispose()
|
||||
case .completed:
|
||||
onCompleted?()
|
||||
disposable.dispose()
|
||||
}
|
||||
}
|
||||
return Disposables.create(
|
||||
self.subscribeSafe(observer),
|
||||
disposable
|
||||
)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extension ObservableType {
|
||||
/// All internal subscribe calls go through this method.
|
||||
fileprivate func subscribeSafe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E {
|
||||
return self.asObservable().subscribe(observer)
|
||||
let observer = AnonymousObserver<E> { event in
|
||||
|
||||
synchronizationTracker.register(synchronizationErrorMessage: .default)
|
||||
defer { synchronizationTracker.unregister() }
|
||||
|
||||
switch event {
|
||||
case .next(let value):
|
||||
onNext?(value)
|
||||
case .error(let error):
|
||||
if let onError = onError {
|
||||
onError(error)
|
||||
}
|
||||
else {
|
||||
Hooks.defaultErrorHandler(callStack, error)
|
||||
}
|
||||
disposable.dispose()
|
||||
case .completed:
|
||||
onCompleted?()
|
||||
disposable.dispose()
|
||||
}
|
||||
}
|
||||
return Disposables.create(
|
||||
self.asObservable().subscribe(observer),
|
||||
disposable
|
||||
)
|
||||
#else
|
||||
let disposable: Disposable
|
||||
|
||||
if let disposed = onDisposed {
|
||||
disposable = Disposables.create(with: disposed)
|
||||
}
|
||||
else {
|
||||
disposable = Disposables.create()
|
||||
}
|
||||
|
||||
let observer = AnonymousObserver<E> { event in
|
||||
switch event {
|
||||
case .next(let value):
|
||||
onNext?(value)
|
||||
case .error(let error):
|
||||
if let onError = onError {
|
||||
onError(error)
|
||||
}
|
||||
else {
|
||||
Hooks.defaultErrorHandler([], error)
|
||||
}
|
||||
disposable.dispose()
|
||||
case .completed:
|
||||
onCompleted?()
|
||||
disposable.dispose()
|
||||
}
|
||||
}
|
||||
return Disposables.create(
|
||||
self.asObservable().subscribe(observer),
|
||||
disposable
|
||||
)
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
import class Foundation.NSRecursiveLock
|
||||
|
||||
extension Hooks {
|
||||
public typealias DefaultErrorHandler = (_ subscriptionCallStack: [String], _ error: Error) -> ()
|
||||
|
||||
fileprivate static let _lock = RecursiveLock()
|
||||
fileprivate static var _defaultErrorHandler: DefaultErrorHandler = { subscriptionCallStack, error in
|
||||
#if DEBUG
|
||||
let serializedCallStack = subscriptionCallStack.joined(separator: "\n")
|
||||
print("Unhandled error happened: \(error)\n subscription called from:\n\(serializedCallStack)")
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Error handler called in case onError handler wasn't provided.
|
||||
public static var defaultErrorHandler: DefaultErrorHandler {
|
||||
get {
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
return _defaultErrorHandler
|
||||
}
|
||||
set {
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
_defaultErrorHandler = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
|
||||
/// Represents a push style sequence.
|
||||
public protocol ObservableType : ObservableConvertibleType {
|
||||
/// Type of elements in sequence.
|
||||
associatedtype E
|
||||
|
||||
/**
|
||||
Subscribes `observer` to receive events for this sequence.
|
||||
|
||||
@@ -29,7 +26,7 @@ public protocol ObservableType : ObservableConvertibleType {
|
||||
When sequence sends `Complete` or `Error` event all internal resources that compute sequence elements
|
||||
will be freed.
|
||||
|
||||
To cancel production of sequence elements and free resources immediatelly, call `dispose` on returned
|
||||
To cancel production of sequence elements and free resources immediately, call `dispose` on returned
|
||||
subscription.
|
||||
|
||||
- returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Propagates the observable sequence that reacts first.
|
||||
|
||||
@@ -14,8 +14,8 @@ extension Observable {
|
||||
|
||||
- returns: An observable sequence that surfaces any of the given sequences, whichever reacted first.
|
||||
*/
|
||||
public static func amb<S: Sequence>(_ sequence: S) -> Observable<Element>
|
||||
where S.Iterator.Element == Observable<Element> {
|
||||
public static func amb<S: Sequence>(_ sequence: S) -> Observable<E>
|
||||
where S.Iterator.Element == Observable<E> {
|
||||
return sequence.reduce(Observable<S.Iterator.Element.E>.never()) { a, o in
|
||||
return a.amb(o.asObservable())
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ extension ObservableType {
|
||||
|
||||
}
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Continues an observable sequence that is terminated by an error with the next observable sequence.
|
||||
|
||||
@@ -44,8 +44,8 @@ extension Observable {
|
||||
|
||||
- returns: An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully.
|
||||
*/
|
||||
public static func catchError<S: Sequence>(_ sequence: S) -> Observable<Element>
|
||||
where S.Iterator.Element == Observable<Element> {
|
||||
public static func catchError<S: Sequence>(_ sequence: S) -> Observable<E>
|
||||
where S.Iterator.Element == Observable<E> {
|
||||
return CatchSequence(sources: sequence)
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ extension ObservableType {
|
||||
*/
|
||||
public func retry(_ maxAttemptCount: Int)
|
||||
-> Observable<E> {
|
||||
return CatchSequence(sources: repeatElement(self.asObservable(), count: maxAttemptCount))
|
||||
return CatchSequence(sources: Swift.repeatElement(self.asObservable(), count: maxAttemptCount))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
@@ -15,7 +15,7 @@ extension Observable {
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<C: Collection>(_ collection: C, _ resultSelector: @escaping ([C.Iterator.Element.E]) throws -> Element) -> Observable<Element>
|
||||
public static func combineLatest<C: Collection>(_ collection: C, _ resultSelector: @escaping ([C.Iterator.Element.E]) throws -> E) -> Observable<E>
|
||||
where C.Iterator.Element: ObservableType {
|
||||
return CombineLatestCollectionType(sources: collection, resultSelector: resultSelector)
|
||||
}
|
||||
@@ -27,8 +27,8 @@ extension Observable {
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<C: Collection>(_ collection: C) -> Observable<[Element]>
|
||||
where C.Iterator.Element: ObservableType, C.Iterator.Element.E == Element {
|
||||
public static func combineLatest<C: Collection>(_ collection: C) -> Observable<[E]>
|
||||
where C.Iterator.Element: ObservableType, C.Iterator.Element.E == E {
|
||||
return CombineLatestCollectionType(sources: collection, resultSelector: { $0 })
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,7 @@ final fileprivate class CombineLatestCollectionType<C: Collection, R> : Producer
|
||||
init(sources: C, resultSelector: @escaping ResultSelector) {
|
||||
_sources = sources
|
||||
_resultSelector = resultSelector
|
||||
_count = Int(self._sources.count.toIntMax())
|
||||
_count = Int(Int64(self._sources.count))
|
||||
}
|
||||
|
||||
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
// 2
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
@@ -109,7 +109,7 @@ final class CombineLatest2<E1, E2, R> : Producer<R> {
|
||||
|
||||
// 3
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
@@ -214,7 +214,7 @@ final class CombineLatest3<E1, E2, E3, R> : Producer<R> {
|
||||
|
||||
// 4
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
@@ -326,7 +326,7 @@ final class CombineLatest4<E1, E2, E3, E4, R> : Producer<R> {
|
||||
|
||||
// 5
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
@@ -445,7 +445,7 @@ final class CombineLatest5<E1, E2, E3, E4, E5, R> : Producer<R> {
|
||||
|
||||
// 6
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
@@ -571,7 +571,7 @@ final class CombineLatest6<E1, E2, E3, E4, E5, E6, R> : Producer<R> {
|
||||
|
||||
// 7
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
@@ -704,7 +704,7 @@ final class CombineLatest7<E1, E2, E3, E4, E5, E6, E7, R> : Producer<R> {
|
||||
|
||||
// 8
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ extension ObservableType {
|
||||
}
|
||||
}
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully.
|
||||
|
||||
@@ -35,8 +35,8 @@ extension Observable {
|
||||
|
||||
- returns: An observable sequence that contains the elements of each given sequence, in sequential order.
|
||||
*/
|
||||
public static func concat<S: Sequence >(_ sequence: S) -> Observable<Element>
|
||||
where S.Iterator.Element == Observable<Element> {
|
||||
public static func concat<S: Sequence >(_ sequence: S) -> Observable<E>
|
||||
where S.Iterator.Element == Observable<E> {
|
||||
return Concat(sources: sequence, count: nil)
|
||||
}
|
||||
|
||||
@@ -53,9 +53,9 @@ extension Observable {
|
||||
|
||||
- returns: An observable sequence that contains the elements of each given sequence, in sequential order.
|
||||
*/
|
||||
public static func concat<S: Collection >(_ collection: S) -> Observable<Element>
|
||||
where S.Iterator.Element == Observable<Element> {
|
||||
return Concat(sources: collection, count: collection.count.toIntMax())
|
||||
public static func concat<S: Collection >(_ collection: S) -> Observable<E>
|
||||
where S.Iterator.Element == Observable<E> {
|
||||
return Concat(sources: collection, count: Int64(collection.count))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,8 +71,8 @@ extension Observable {
|
||||
|
||||
- returns: An observable sequence that contains the elements of each given sequence, in sequential order.
|
||||
*/
|
||||
public static func concat(_ sources: Observable<Element> ...) -> Observable<Element> {
|
||||
return Concat(sources: sources, count: sources.count.toIntMax())
|
||||
public static func concat(_ sources: Observable<E> ...) -> Observable<E> {
|
||||
return Concat(sources: sources, count: Int64(sources.count))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,3 +128,4 @@ final fileprivate class Concat<S: Sequence> : Producer<S.Iterator.Element.E> whe
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
//
|
||||
// ConnectableObservable.swift
|
||||
// RxSwift
|
||||
//
|
||||
// Created by Krunoslav Zaher on 3/1/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
extension ObservableType {
|
||||
|
||||
/**
|
||||
Multicasts the source sequence notifications through the specified subject to the resulting connectable observable.
|
||||
|
||||
Upon connection of the connectable observable, the subject is subscribed to the source exactly one, and messages are forwarded to the observers registered with the connectable observable.
|
||||
|
||||
For specializations with fixed subject types, see `publish` and `replay`.
|
||||
|
||||
- seealso: [multicast operator on reactivex.io](http://reactivex.io/documentation/operators/publish.html)
|
||||
|
||||
- parameter subject: Subject to push source elements into.
|
||||
- returns: A connectable observable sequence that upon connection causes the source sequence to push results into the specified subject.
|
||||
*/
|
||||
public func multicast<S: SubjectType>(_ subject: S)
|
||||
-> ConnectableObservable<S.E> where S.SubjectObserverType.E == E {
|
||||
return ConnectableObservableAdapter(source: self.asObservable(), subject: subject)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Represents an observable wrapper that can be connected and disconnected from its underlying observable sequence.
|
||||
*/
|
||||
public class ConnectableObservable<Element>
|
||||
: Observable<Element>
|
||||
, ConnectableObservableType {
|
||||
|
||||
/**
|
||||
Connects the observable wrapper to its source. All subscribed observers will receive values from the underlying observable sequence as long as the connection is established.
|
||||
|
||||
- returns: Disposable used to disconnect the observable wrapper from its source, causing subscribed observer to stop receiving values from the underlying observable sequence.
|
||||
*/
|
||||
public func connect() -> Disposable {
|
||||
rxAbstractMethod()
|
||||
}
|
||||
}
|
||||
|
||||
final class Connection<S: SubjectType> : ObserverType, Disposable {
|
||||
typealias E = S.SubjectObserverType.E
|
||||
|
||||
private var _lock: RecursiveLock
|
||||
// state
|
||||
private var _parent: ConnectableObservableAdapter<S>?
|
||||
private var _subscription : Disposable?
|
||||
private var _subjectObserver: S.SubjectObserverType
|
||||
|
||||
private var _disposed: Bool = false
|
||||
|
||||
init(parent: ConnectableObservableAdapter<S>, subjectObserver: S.SubjectObserverType, lock: RecursiveLock, subscription: Disposable) {
|
||||
_parent = parent
|
||||
_subscription = subscription
|
||||
_lock = lock
|
||||
_subjectObserver = subjectObserver
|
||||
}
|
||||
|
||||
func on(_ event: Event<S.SubjectObserverType.E>) {
|
||||
if _disposed {
|
||||
return
|
||||
}
|
||||
_subjectObserver.on(event)
|
||||
if event.isStopEvent {
|
||||
self.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
func dispose() {
|
||||
_lock.lock(); defer { _lock.unlock() } // {
|
||||
_disposed = true
|
||||
guard let parent = _parent else {
|
||||
return
|
||||
}
|
||||
|
||||
if parent._connection === self {
|
||||
parent._connection = nil
|
||||
}
|
||||
_parent = nil
|
||||
|
||||
_subscription?.dispose()
|
||||
_subscription = nil
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
final class ConnectableObservableAdapter<S: SubjectType>
|
||||
: ConnectableObservable<S.E> {
|
||||
typealias ConnectionType = Connection<S>
|
||||
|
||||
fileprivate let _subject: S
|
||||
fileprivate let _source: Observable<S.SubjectObserverType.E>
|
||||
|
||||
fileprivate let _lock = RecursiveLock()
|
||||
|
||||
// state
|
||||
fileprivate var _connection: ConnectionType?
|
||||
|
||||
init(source: Observable<S.SubjectObserverType.E>, subject: S) {
|
||||
_source = source
|
||||
_subject = subject
|
||||
_connection = nil
|
||||
}
|
||||
|
||||
override func connect() -> Disposable {
|
||||
return _lock.calculateLocked {
|
||||
if let connection = _connection {
|
||||
return connection
|
||||
}
|
||||
|
||||
let singleAssignmentDisposable = SingleAssignmentDisposable()
|
||||
let connection = Connection(parent: self, subjectObserver: _subject.asObserver(), lock: _lock, subscription: singleAssignmentDisposable)
|
||||
_connection = connection
|
||||
let subscription = _source.subscribe(connection)
|
||||
singleAssignmentDisposable.setDisposable(subscription)
|
||||
return connection
|
||||
}
|
||||
}
|
||||
|
||||
override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == S.E {
|
||||
return _subject.subscribe(observer)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
// MARK: create
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ final fileprivate class AnonymousObservableSink<O: ObserverType> : Sink<O>, Obse
|
||||
private var _isStopped: AtomicInt = 0
|
||||
|
||||
#if DEBUG
|
||||
fileprivate var _numberOfConcurrentCalls: AtomicInt = 0
|
||||
fileprivate let _synchronizationTracker = SynchronizationTracker()
|
||||
#endif
|
||||
|
||||
override init(observer: O, cancel: Cancelable) {
|
||||
@@ -39,13 +39,8 @@ final fileprivate class AnonymousObservableSink<O: ObserverType> : Sink<O>, Obse
|
||||
|
||||
func on(_ event: Event<E>) {
|
||||
#if DEBUG
|
||||
if AtomicIncrement(&_numberOfConcurrentCalls) > 1 {
|
||||
rxFatalError("Warning: Recursive call or synchronization error!")
|
||||
}
|
||||
|
||||
defer {
|
||||
_ = AtomicDecrement(&_numberOfConcurrentCalls)
|
||||
}
|
||||
_synchronizationTracker.register(synchronizationErrorMessage: .default)
|
||||
defer { _synchronizationTracker.unregister() }
|
||||
#endif
|
||||
switch event {
|
||||
case .next:
|
||||
|
||||
@@ -52,8 +52,8 @@ final fileprivate class DebugSink<Source: ObservableType, O: ObserverType> : Sin
|
||||
let maxEventTextLength = 40
|
||||
let eventText = "\(event)"
|
||||
|
||||
let eventNormalized = (eventText.characters.count > maxEventTextLength) && _parent._trimOutput
|
||||
? String(eventText.characters.prefix(maxEventTextLength / 2)) + "..." + String(eventText.characters.suffix(maxEventTextLength / 2))
|
||||
let eventNormalized = (eventText.count > maxEventTextLength) && _parent._trimOutput
|
||||
? String(eventText.prefix(maxEventTextLength / 2)) + "..." + String(eventText.suffix(maxEventTextLength / 2))
|
||||
: eventText
|
||||
|
||||
logEvent(_parent._identifier, dateFormat: _timestampFormatter, content: "Event \(eventNormalized)")
|
||||
@@ -85,7 +85,7 @@ final fileprivate class Debug<Source: ObservableType> : Producer<Source.E> {
|
||||
else {
|
||||
let trimmedFile: String
|
||||
if let lastIndex = file.lastIndexOf("/") {
|
||||
trimmedFile = file[file.index(after: lastIndex) ..< file.endIndex]
|
||||
trimmedFile = String(file[file.index(after: lastIndex) ..< file.endIndex])
|
||||
}
|
||||
else {
|
||||
trimmedFile = file
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ final fileprivate class DelaySink<O: ObserverType>
|
||||
}
|
||||
|
||||
// All of these complications in this method are caused by the fact that
|
||||
// error should be propagated immediatelly. Error can bepotentially received on different
|
||||
// error should be propagated immediately. Error can be potentially received on different
|
||||
// scheduler so this process needs to be synchronized somehow.
|
||||
//
|
||||
// Another complication is that scheduler is potentially concurrent so internal queue is used.
|
||||
|
||||
@@ -37,18 +37,18 @@ extension ObservableType {
|
||||
|
||||
final fileprivate class DoSink<O: ObserverType> : Sink<O>, ObserverType {
|
||||
typealias Element = O.E
|
||||
typealias Parent = Do<Element>
|
||||
typealias EventHandler = (Event<Element>) throws -> Void
|
||||
|
||||
private let _parent: Parent
|
||||
private let _eventHandler: EventHandler
|
||||
|
||||
init(parent: Parent, observer: O, cancel: Cancelable) {
|
||||
_parent = parent
|
||||
init(eventHandler: @escaping EventHandler, observer: O, cancel: Cancelable) {
|
||||
_eventHandler = eventHandler
|
||||
super.init(observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
func on(_ event: Event<Element>) {
|
||||
do {
|
||||
try _parent._eventHandler(event)
|
||||
try _eventHandler(event)
|
||||
forwardOn(event)
|
||||
if event.isStopEvent {
|
||||
dispose()
|
||||
@@ -80,7 +80,7 @@ final fileprivate class Do<Element> : Producer<Element> {
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
|
||||
_onSubscribe?()
|
||||
let sink = DoSink(parent: self, observer: observer, cancel: cancel)
|
||||
let sink = DoSink(eventHandler: _eventHandler, observer: observer, cancel: cancel)
|
||||
let subscription = _source.subscribe(sink)
|
||||
_onSubscribed?()
|
||||
let onDispose = _onDispose
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message.
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// Enumerated.swift
|
||||
// RxSwift
|
||||
//
|
||||
// Created by Krunoslav Zaher on 8/6/17.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension ObservableType {
|
||||
|
||||
/**
|
||||
Enumerates the elements of an observable sequence.
|
||||
|
||||
- seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html)
|
||||
|
||||
- returns: An observable sequence that contains tuples of source sequence elements and their indexes.
|
||||
*/
|
||||
public func enumerated()
|
||||
-> Observable<(index: Int, element: E)> {
|
||||
return Enumerated(source: self.asObservable())
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class EnumeratedSink<Element, O : ObserverType>: Sink<O>, ObserverType where O.E == (index: Int, element: Element) {
|
||||
typealias E = Element
|
||||
var index = 0
|
||||
|
||||
func on(_ event: Event<Element>) {
|
||||
switch event {
|
||||
case .next(let value):
|
||||
do {
|
||||
let nextIndex = try incrementChecked(&index)
|
||||
let next = (index: nextIndex, element: value)
|
||||
forwardOn(.next(next))
|
||||
}
|
||||
catch let e {
|
||||
forwardOn(.error(e))
|
||||
dispose()
|
||||
}
|
||||
case .completed:
|
||||
forwardOn(.completed)
|
||||
dispose()
|
||||
case .error(let error):
|
||||
forwardOn(.error(error))
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class Enumerated<Element> : Producer<(index: Int, element: Element)> {
|
||||
private let _source: Observable<Element>
|
||||
|
||||
init(source: Observable<Element>) {
|
||||
_source = source
|
||||
}
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == (index: Int, element: Element) {
|
||||
let sink = EnumeratedSink<Element, O>(observer: observer, cancel: cancel)
|
||||
let subscription = _source.subscribe(sink)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Returns an observable sequence that terminates with an `error`.
|
||||
|
||||
|
||||
@@ -32,10 +32,11 @@ extension ObservableType {
|
||||
- returns: An observable sequence that skips all elements of the source sequence.
|
||||
*/
|
||||
public func ignoreElements()
|
||||
-> Observable<E> {
|
||||
return filter { _ -> Bool in
|
||||
return false
|
||||
-> Completable {
|
||||
return flatMap { _ in
|
||||
return Observable<Never>.empty()
|
||||
}
|
||||
.asCompletable()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// First.swift
|
||||
// RxSwift
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/31/17.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
fileprivate final class FirstSink<Element, O: ObserverType> : Sink<O>, ObserverType where O.E == Element? {
|
||||
typealias E = Element
|
||||
typealias Parent = First<E>
|
||||
|
||||
func on(_ event: Event<E>) {
|
||||
switch event {
|
||||
case .next(let value):
|
||||
forwardOn(.next(value))
|
||||
forwardOn(.completed)
|
||||
dispose()
|
||||
case .error(let error):
|
||||
forwardOn(.error(error))
|
||||
dispose()
|
||||
case .completed:
|
||||
forwardOn(.next(nil))
|
||||
forwardOn(.completed)
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class First<Element>: Producer<Element?> {
|
||||
fileprivate let _source: Observable<Element>
|
||||
|
||||
init(source: Observable<Element>) {
|
||||
_source = source
|
||||
}
|
||||
|
||||
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element? {
|
||||
let sink = FirstSink(observer: observer, cancel: cancel)
|
||||
let subscription = _source.subscribe(sink)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler
|
||||
to run the loop send out observer messages.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Returns an observable sequence that contains a single element.
|
||||
|
||||
|
||||
@@ -21,19 +21,6 @@ extension ObservableType {
|
||||
-> Observable<R> {
|
||||
return self.asObservable().composeMap(transform)
|
||||
}
|
||||
|
||||
/**
|
||||
Projects each element of an observable sequence into a new form by incorporating the element's index.
|
||||
|
||||
- seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html)
|
||||
|
||||
- parameter selector: A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
|
||||
- returns: An observable sequence whose elements are the result of invoking the transform function on each element of source.
|
||||
*/
|
||||
public func mapWithIndex<R>(_ selector: @escaping (E, Int) throws -> R)
|
||||
-> Observable<R> {
|
||||
return MapWithIndex(source: asObservable(), selector: selector)
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class MapSink<SourceType, O : ObserverType> : Sink<O>, ObserverType {
|
||||
@@ -70,62 +57,6 @@ final fileprivate class MapSink<SourceType, O : ObserverType> : Sink<O>, Observe
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class MapWithIndexSink<SourceType, O : ObserverType> : Sink<O>, ObserverType {
|
||||
typealias Selector = (SourceType, Int) throws -> ResultType
|
||||
|
||||
typealias ResultType = O.E
|
||||
typealias Element = SourceType
|
||||
typealias Parent = MapWithIndex<SourceType, ResultType>
|
||||
|
||||
private let _selector: Selector
|
||||
|
||||
private var _index = 0
|
||||
|
||||
init(selector: @escaping Selector, observer: O, cancel: Cancelable) {
|
||||
_selector = selector
|
||||
super.init(observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
func on(_ event: Event<SourceType>) {
|
||||
switch event {
|
||||
case .next(let element):
|
||||
do {
|
||||
let mappedElement = try _selector(element, try incrementChecked(&_index))
|
||||
forwardOn(.next(mappedElement))
|
||||
}
|
||||
catch let e {
|
||||
forwardOn(.error(e))
|
||||
dispose()
|
||||
}
|
||||
case .error(let error):
|
||||
forwardOn(.error(error))
|
||||
dispose()
|
||||
case .completed:
|
||||
forwardOn(.completed)
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class MapWithIndex<SourceType, ResultType> : Producer<ResultType> {
|
||||
typealias Selector = (SourceType, Int) throws -> ResultType
|
||||
|
||||
private let _source: Observable<SourceType>
|
||||
|
||||
private let _selector: Selector
|
||||
|
||||
init(source: Observable<SourceType>, selector: @escaping Selector) {
|
||||
_source = source
|
||||
_selector = selector
|
||||
}
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == ResultType {
|
||||
let sink = MapWithIndexSink(selector: _selector, observer: observer, cancel: cancel)
|
||||
let subscription = _source.subscribe(sink)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
}
|
||||
|
||||
#if TRACE_RESOURCES
|
||||
fileprivate var _numberOfMapOperators: AtomicInt = 0
|
||||
extension Resources {
|
||||
|
||||
@@ -21,18 +21,6 @@ extension ObservableType {
|
||||
return FlatMap(source: asObservable(), selector: selector)
|
||||
}
|
||||
|
||||
/**
|
||||
Projects each element of an observable sequence to an observable sequence by incorporating the element's index and merges the resulting observable sequences into one observable sequence.
|
||||
|
||||
- seealso: [flatMap operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html)
|
||||
|
||||
- parameter selector: A transform function to apply to each element; the second parameter of the function represents the index of the source element.
|
||||
- returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence.
|
||||
*/
|
||||
public func flatMapWithIndex<O: ObservableConvertibleType>(_ selector: @escaping (E, Int) throws -> O)
|
||||
-> Observable<O.E> {
|
||||
return FlatMapWithIndex(source: asObservable(), selector: selector)
|
||||
}
|
||||
}
|
||||
|
||||
extension ObservableType {
|
||||
@@ -93,7 +81,7 @@ extension ObservableType where E : ObservableConvertibleType {
|
||||
}
|
||||
}
|
||||
|
||||
extension Observable {
|
||||
extension ObservableType {
|
||||
/**
|
||||
Merges elements from all observable sequences from collection into a single observable sequence.
|
||||
|
||||
@@ -131,13 +119,30 @@ extension Observable {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate final class MergeLimitedSinkIter<S: ObservableConvertibleType, O: ObserverType>
|
||||
// MARK: concatMap
|
||||
|
||||
extension ObservableType {
|
||||
/**
|
||||
Projects each element of an observable sequence to an observable sequence and concatenates the resulting observable sequences into one observable sequence.
|
||||
|
||||
- seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html)
|
||||
|
||||
- returns: An observable sequence that contains the elements of each observed inner sequence, in sequential order.
|
||||
*/
|
||||
|
||||
public func concatMap<O: ObservableConvertibleType>(_ selector: @escaping (E) throws -> O)
|
||||
-> Observable<O.E> {
|
||||
return ConcatMap(source: asObservable(), selector: selector)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate final class MergeLimitedSinkIter<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType>
|
||||
: ObserverType
|
||||
, LockOwnerType
|
||||
, SynchronizedOnType where S.E == O.E {
|
||||
typealias E = O.E
|
||||
, SynchronizedOnType where SourceSequence.E == Observer.E {
|
||||
typealias E = Observer.E
|
||||
typealias DisposeKey = CompositeDisposable.DisposeKey
|
||||
typealias Parent = MergeLimitedSink<S, O>
|
||||
typealias Parent = MergeLimitedSink<SourceElement, SourceSequence, Observer>
|
||||
|
||||
private let _parent: Parent
|
||||
private let _disposeKey: DisposeKey
|
||||
@@ -179,13 +184,32 @@ fileprivate final class MergeLimitedSinkIter<S: ObservableConvertibleType, O: Ob
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate final class MergeLimitedSink<S: ObservableConvertibleType, O: ObserverType>
|
||||
: Sink<O>
|
||||
, ObserverType
|
||||
, LockOwnerType
|
||||
, SynchronizedOnType where S.E == O.E {
|
||||
typealias E = S
|
||||
typealias QueueType = Queue<S>
|
||||
fileprivate final class ConcatMapSink<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType>: MergeLimitedSink<SourceElement, SourceSequence, Observer> where Observer.E == SourceSequence.E {
|
||||
typealias Selector = (SourceElement) throws -> SourceSequence
|
||||
|
||||
private let _selector: Selector
|
||||
|
||||
init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) {
|
||||
_selector = selector
|
||||
super.init(maxConcurrent: 1, observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
override func performMap(_ element: SourceElement) throws -> SourceSequence {
|
||||
return try _selector(element)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate final class MergeLimitedBasicSink<SourceSequence: ObservableConvertibleType, Observer: ObserverType>: MergeLimitedSink<SourceSequence, SourceSequence, Observer> where Observer.E == SourceSequence.E {
|
||||
|
||||
override func performMap(_ element: SourceSequence) throws -> SourceSequence {
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate class MergeLimitedSink<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType>
|
||||
: Sink<Observer>
|
||||
, ObserverType where Observer.E == SourceSequence.E {
|
||||
typealias QueueType = Queue<SourceSequence>
|
||||
|
||||
let _maxConcurrent: Int
|
||||
|
||||
@@ -199,14 +223,14 @@ fileprivate final class MergeLimitedSink<S: ObservableConvertibleType, O: Observ
|
||||
let _sourceSubscription = SingleAssignmentDisposable()
|
||||
let _group = CompositeDisposable()
|
||||
|
||||
init(maxConcurrent: Int, observer: O, cancel: Cancelable) {
|
||||
init(maxConcurrent: Int, observer: Observer, cancel: Cancelable) {
|
||||
_maxConcurrent = maxConcurrent
|
||||
|
||||
let _ = _group.insert(_sourceSubscription)
|
||||
super.init(observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
func run(_ source: Observable<S>) -> Disposable {
|
||||
func run(_ source: Observable<SourceElement>) -> Disposable {
|
||||
let _ = _group.insert(_sourceSubscription)
|
||||
|
||||
let disposable = source.subscribe(self)
|
||||
@@ -214,7 +238,7 @@ fileprivate final class MergeLimitedSink<S: ObservableConvertibleType, O: Observ
|
||||
return _group
|
||||
}
|
||||
|
||||
func subscribe(_ innerSource: E, group: CompositeDisposable) {
|
||||
func subscribe(_ innerSource: SourceSequence, group: CompositeDisposable) {
|
||||
let subscription = SingleAssignmentDisposable()
|
||||
|
||||
let key = group.insert(subscription)
|
||||
@@ -227,30 +251,56 @@ fileprivate final class MergeLimitedSink<S: ObservableConvertibleType, O: Observ
|
||||
}
|
||||
}
|
||||
|
||||
func on(_ event: Event<E>) {
|
||||
synchronizedOn(event)
|
||||
func performMap(_ element: SourceElement) throws -> SourceSequence {
|
||||
rxAbstractMethod()
|
||||
}
|
||||
|
||||
func _synchronized_on(_ event: Event<E>) {
|
||||
switch event {
|
||||
case .next(let value):
|
||||
@inline(__always)
|
||||
final private func nextElementArrived(element: SourceElement) -> SourceSequence? {
|
||||
_lock.lock(); defer { _lock.unlock() } // {
|
||||
let subscribe: Bool
|
||||
if _activeCount < _maxConcurrent {
|
||||
_activeCount += 1
|
||||
subscribe = true
|
||||
}
|
||||
else {
|
||||
_queue.enqueue(value)
|
||||
do {
|
||||
let value = try performMap(element)
|
||||
_queue.enqueue(value)
|
||||
} catch {
|
||||
forwardOn(.error(error))
|
||||
dispose()
|
||||
}
|
||||
subscribe = false
|
||||
}
|
||||
|
||||
if subscribe {
|
||||
self.subscribe(value, group: _group)
|
||||
do {
|
||||
return try performMap(element)
|
||||
} catch {
|
||||
forwardOn(.error(error))
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
// }
|
||||
}
|
||||
|
||||
func on(_ event: Event<SourceElement>) {
|
||||
switch event {
|
||||
case .next(let element):
|
||||
if let sequence = self.nextElementArrived(element: element) {
|
||||
self.subscribe(sequence, group: _group)
|
||||
}
|
||||
case .error(let error):
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
|
||||
forwardOn(.error(error))
|
||||
dispose()
|
||||
case .completed:
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
|
||||
if _activeCount == 0 {
|
||||
forwardOn(.completed)
|
||||
dispose()
|
||||
@@ -264,17 +314,17 @@ fileprivate final class MergeLimitedSink<S: ObservableConvertibleType, O: Observ
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class MergeLimited<S: ObservableConvertibleType> : Producer<S.E> {
|
||||
private let _source: Observable<S>
|
||||
final fileprivate class MergeLimited<SourceSequence: ObservableConvertibleType> : Producer<SourceSequence.E> {
|
||||
private let _source: Observable<SourceSequence>
|
||||
private let _maxConcurrent: Int
|
||||
|
||||
init(source: Observable<S>, maxConcurrent: Int) {
|
||||
init(source: Observable<SourceSequence>, maxConcurrent: Int) {
|
||||
_source = source
|
||||
_maxConcurrent = maxConcurrent
|
||||
}
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E {
|
||||
let sink = MergeLimitedSink<S, O>(maxConcurrent: _maxConcurrent, observer: observer, cancel: cancel)
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E {
|
||||
let sink = MergeLimitedBasicSink<SourceSequence, O>(maxConcurrent: _maxConcurrent, observer: observer, cancel: cancel)
|
||||
let subscription = sink.run(_source)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
@@ -283,10 +333,6 @@ final fileprivate class MergeLimited<S: ObservableConvertibleType> : Producer<S.
|
||||
// MARK: Merge
|
||||
|
||||
fileprivate final class MergeBasicSink<S: ObservableConvertibleType, O: ObserverType> : MergeSink<S, S, O> where O.E == S.E {
|
||||
override init(observer: O, cancel: Cancelable) {
|
||||
super.init(observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
override func performMap(_ element: S) throws -> S {
|
||||
return element
|
||||
}
|
||||
@@ -294,41 +340,25 @@ fileprivate final class MergeBasicSink<S: ObservableConvertibleType, O: Observer
|
||||
|
||||
// MARK: flatMap
|
||||
|
||||
fileprivate final class FlatMapSink<SourceType, S: ObservableConvertibleType, O: ObserverType> : MergeSink<SourceType, S, O> where O.E == S.E {
|
||||
typealias Selector = (SourceType) throws -> S
|
||||
fileprivate final class FlatMapSink<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType> : MergeSink<SourceElement, SourceSequence, Observer> where Observer.E == SourceSequence.E {
|
||||
typealias Selector = (SourceElement) throws -> SourceSequence
|
||||
|
||||
private let _selector: Selector
|
||||
|
||||
init(selector: @escaping Selector, observer: O, cancel: Cancelable) {
|
||||
init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) {
|
||||
_selector = selector
|
||||
super.init(observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
override func performMap(_ element: SourceType) throws -> S {
|
||||
override func performMap(_ element: SourceElement) throws -> SourceSequence {
|
||||
return try _selector(element)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate final class FlatMapWithIndexSink<SourceType, S: ObservableConvertibleType, O: ObserverType> : MergeSink<SourceType, S, O> where O.E == S.E {
|
||||
typealias Selector = (SourceType, Int) throws -> S
|
||||
|
||||
private var _index = 0
|
||||
private let _selector: Selector
|
||||
|
||||
init(selector: @escaping Selector, observer: O, cancel: Cancelable) {
|
||||
_selector = selector
|
||||
super.init(observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
override func performMap(_ element: SourceType) throws -> S {
|
||||
return try _selector(element, try incrementChecked(&_index))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: FlatMapFirst
|
||||
|
||||
fileprivate final class FlatMapFirstSink<SourceType, S: ObservableConvertibleType, O: ObserverType> : MergeSink<SourceType, S, O> where O.E == S.E {
|
||||
typealias Selector = (SourceType) throws -> S
|
||||
fileprivate final class FlatMapFirstSink<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType> : MergeSink<SourceElement, SourceSequence, Observer> where Observer.E == SourceSequence.E {
|
||||
typealias Selector = (SourceElement) throws -> SourceSequence
|
||||
|
||||
private let _selector: Selector
|
||||
|
||||
@@ -336,20 +366,20 @@ fileprivate final class FlatMapFirstSink<SourceType, S: ObservableConvertibleTyp
|
||||
return _activeCount == 0
|
||||
}
|
||||
|
||||
init(selector: @escaping Selector, observer: O, cancel: Cancelable) {
|
||||
init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) {
|
||||
_selector = selector
|
||||
super.init(observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
override func performMap(_ element: SourceType) throws -> S {
|
||||
override func performMap(_ element: SourceElement) throws -> SourceSequence {
|
||||
return try _selector(element)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate final class MergeSinkIter<SourceType, S: ObservableConvertibleType, O: ObserverType> : ObserverType where O.E == S.E {
|
||||
typealias Parent = MergeSink<SourceType, S, O>
|
||||
fileprivate final class MergeSinkIter<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType> : ObserverType where Observer.E == SourceSequence.E {
|
||||
typealias Parent = MergeSink<SourceElement, SourceSequence, Observer>
|
||||
typealias DisposeKey = CompositeDisposable.DisposeKey
|
||||
typealias E = O.E
|
||||
typealias E = Observer.E
|
||||
|
||||
private let _parent: Parent
|
||||
private let _disposeKey: DisposeKey
|
||||
@@ -377,11 +407,11 @@ fileprivate final class MergeSinkIter<SourceType, S: ObservableConvertibleType,
|
||||
}
|
||||
|
||||
|
||||
fileprivate class MergeSink<SourceType, S: ObservableConvertibleType, O: ObserverType>
|
||||
: Sink<O>
|
||||
, ObserverType where O.E == S.E {
|
||||
typealias ResultType = O.E
|
||||
typealias Element = SourceType
|
||||
fileprivate class MergeSink<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType>
|
||||
: Sink<Observer>
|
||||
, ObserverType where Observer.E == SourceSequence.E {
|
||||
typealias ResultType = Observer.E
|
||||
typealias Element = SourceElement
|
||||
|
||||
let _lock = RecursiveLock()
|
||||
|
||||
@@ -396,55 +426,66 @@ fileprivate class MergeSink<SourceType, S: ObservableConvertibleType, O: Observe
|
||||
var _activeCount = 0
|
||||
var _stopped = false
|
||||
|
||||
override init(observer: O, cancel: Cancelable) {
|
||||
override init(observer: Observer, cancel: Cancelable) {
|
||||
super.init(observer: observer, cancel: cancel)
|
||||
}
|
||||
|
||||
func performMap(_ element: SourceType) throws -> S {
|
||||
func performMap(_ element: SourceElement) throws -> SourceSequence {
|
||||
rxAbstractMethod()
|
||||
}
|
||||
|
||||
func on(_ event: Event<SourceType>) {
|
||||
_lock.lock(); defer { _lock.unlock() } // lock {
|
||||
switch event {
|
||||
case .next(let element):
|
||||
if !subscribeNext {
|
||||
return
|
||||
}
|
||||
do {
|
||||
let value = try performMap(element)
|
||||
subscribeInner(value.asObservable())
|
||||
}
|
||||
catch let e {
|
||||
forwardOn(.error(e))
|
||||
dispose()
|
||||
}
|
||||
case .error(let error):
|
||||
forwardOn(.error(error))
|
||||
dispose()
|
||||
case .completed:
|
||||
_stopped = true
|
||||
_sourceSubscription.dispose()
|
||||
checkCompleted()
|
||||
|
||||
@inline(__always)
|
||||
final private func nextElementArrived(element: SourceElement) -> SourceSequence? {
|
||||
_lock.lock(); defer { _lock.unlock() } // {
|
||||
if !subscribeNext {
|
||||
return nil
|
||||
}
|
||||
//}
|
||||
|
||||
do {
|
||||
let value = try performMap(element)
|
||||
_activeCount += 1
|
||||
return value
|
||||
}
|
||||
catch let e {
|
||||
forwardOn(.error(e))
|
||||
dispose()
|
||||
return nil
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
func on(_ event: Event<SourceElement>) {
|
||||
switch event {
|
||||
case .next(let element):
|
||||
if let value = nextElementArrived(element: element) {
|
||||
subscribeInner(value.asObservable())
|
||||
}
|
||||
case .error(let error):
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
forwardOn(.error(error))
|
||||
dispose()
|
||||
case .completed:
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
_stopped = true
|
||||
_sourceSubscription.dispose()
|
||||
checkCompleted()
|
||||
}
|
||||
}
|
||||
|
||||
func subscribeInner(_ source: Observable<O.E>) {
|
||||
func subscribeInner(_ source: Observable<Observer.E>) {
|
||||
let iterDisposable = SingleAssignmentDisposable()
|
||||
if let disposeKey = _group.insert(iterDisposable) {
|
||||
_activeCount += 1
|
||||
let iter = MergeSinkIter(parent: self, disposeKey: disposeKey)
|
||||
let subscription = source.subscribe(iter)
|
||||
iterDisposable.setDisposable(subscription)
|
||||
}
|
||||
}
|
||||
|
||||
func run(_ sources: [SourceType]) -> Disposable {
|
||||
let _ = _group.insert(_sourceSubscription)
|
||||
func run(_ sources: [Observable<Observer.E>]) -> Disposable {
|
||||
_activeCount += sources.count
|
||||
|
||||
for source in sources {
|
||||
self.on(.next(source))
|
||||
subscribeInner(source)
|
||||
}
|
||||
|
||||
_stopped = true
|
||||
@@ -462,7 +503,7 @@ fileprivate class MergeSink<SourceType, S: ObservableConvertibleType, O: Observe
|
||||
}
|
||||
}
|
||||
|
||||
func run(_ source: Observable<SourceType>) -> Disposable {
|
||||
func run(_ source: Observable<SourceElement>) -> Disposable {
|
||||
let _ = _group.insert(_sourceSubscription)
|
||||
|
||||
let subscription = source.subscribe(self)
|
||||
@@ -474,82 +515,80 @@ fileprivate class MergeSink<SourceType, S: ObservableConvertibleType, O: Observe
|
||||
|
||||
// MARK: Producers
|
||||
|
||||
final fileprivate class FlatMap<SourceType, S: ObservableConvertibleType>: Producer<S.E> {
|
||||
typealias Selector = (SourceType) throws -> S
|
||||
final fileprivate class FlatMap<SourceElement, SourceSequence: ObservableConvertibleType>: Producer<SourceSequence.E> {
|
||||
typealias Selector = (SourceElement) throws -> SourceSequence
|
||||
|
||||
private let _source: Observable<SourceType>
|
||||
private let _source: Observable<SourceElement>
|
||||
|
||||
private let _selector: Selector
|
||||
|
||||
init(source: Observable<SourceType>, selector: @escaping Selector) {
|
||||
init(source: Observable<SourceElement>, selector: @escaping Selector) {
|
||||
_source = source
|
||||
_selector = selector
|
||||
}
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E {
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E {
|
||||
let sink = FlatMapSink(selector: _selector, observer: observer, cancel: cancel)
|
||||
let subscription = sink.run(_source)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class FlatMapWithIndex<SourceType, S: ObservableConvertibleType>: Producer<S.E> {
|
||||
typealias Selector = (SourceType, Int) throws -> S
|
||||
final fileprivate class FlatMapFirst<SourceElement, SourceSequence: ObservableConvertibleType>: Producer<SourceSequence.E> {
|
||||
typealias Selector = (SourceElement) throws -> SourceSequence
|
||||
|
||||
private let _source: Observable<SourceType>
|
||||
|
||||
private let _selector: Selector
|
||||
|
||||
init(source: Observable<SourceType>, selector: @escaping Selector) {
|
||||
_source = source
|
||||
_selector = selector
|
||||
}
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E {
|
||||
let sink = FlatMapWithIndexSink<SourceType, S, O>(selector: _selector, observer: observer, cancel: cancel)
|
||||
let subscription = sink.run(_source)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final fileprivate class FlatMapFirst<SourceType, S: ObservableConvertibleType>: Producer<S.E> {
|
||||
typealias Selector = (SourceType) throws -> S
|
||||
|
||||
private let _source: Observable<SourceType>
|
||||
private let _source: Observable<SourceElement>
|
||||
|
||||
private let _selector: Selector
|
||||
|
||||
init(source: Observable<SourceType>, selector: @escaping Selector) {
|
||||
init(source: Observable<SourceElement>, selector: @escaping Selector) {
|
||||
_source = source
|
||||
_selector = selector
|
||||
}
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E {
|
||||
let sink = FlatMapFirstSink<SourceType, S, O>(selector: _selector, observer: observer, cancel: cancel)
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E {
|
||||
let sink = FlatMapFirstSink<SourceElement, SourceSequence, O>(selector: _selector, observer: observer, cancel: cancel)
|
||||
let subscription = sink.run(_source)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class Merge<S: ObservableConvertibleType> : Producer<S.E> {
|
||||
private let _source: Observable<S>
|
||||
final class ConcatMap<SourceElement, SourceSequence: ObservableConvertibleType>: Producer<SourceSequence.E> {
|
||||
typealias Selector = (SourceElement) throws -> SourceSequence
|
||||
|
||||
private let _source: Observable<SourceElement>
|
||||
private let _selector: Selector
|
||||
|
||||
init(source: Observable<SourceElement>, selector: @escaping Selector) {
|
||||
_source = source
|
||||
_selector = selector
|
||||
}
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E {
|
||||
let sink = ConcatMapSink<SourceElement, SourceSequence, O>(selector: _selector, observer: observer, cancel: cancel)
|
||||
let subscription = sink.run(_source)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
}
|
||||
|
||||
init(source: Observable<S>) {
|
||||
final class Merge<SourceSequence: ObservableConvertibleType> : Producer<SourceSequence.E> {
|
||||
private let _source: Observable<SourceSequence>
|
||||
|
||||
init(source: Observable<SourceSequence>) {
|
||||
_source = source
|
||||
}
|
||||
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E {
|
||||
let sink = MergeBasicSink<S, O>(observer: observer, cancel: cancel)
|
||||
override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E {
|
||||
let sink = MergeBasicSink<SourceSequence, O>(observer: observer, cancel: cancel)
|
||||
let subscription = sink.run(_source)
|
||||
return (sink: sink, subscription: subscription)
|
||||
}
|
||||
}
|
||||
|
||||
final fileprivate class MergeArray<E> : Producer<E> {
|
||||
private let _sources: [Observable<E>]
|
||||
final fileprivate class MergeArray<Element> : Producer<Element> {
|
||||
private let _sources: [Observable<Element>]
|
||||
|
||||
init(sources: [Observable<E>]) {
|
||||
init(sources: [Observable<Element>]) {
|
||||
_sources = sources
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user