[swift5] [alamofire] adds ability to inject custom response serializers (#13542)

* adjust templates to allow injecting ResponseSerializers

* generate samples

* swift < 5.5 compatibility
This commit is contained in:
Jonas Reichert 2022-09-28 18:34:17 +02:00 committed by GitHub
parent 6a631b4cc0
commit 00604aff59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 16 deletions

View File

@ -5,7 +5,8 @@
//
import Foundation{{#useVapor}}
import Vapor{{/useVapor}}
import Vapor{{/useVapor}}{{#useAlamofire}}
import Alamofire{{/useAlamofire}}
{{#swiftUseApiNamespace}}
@available(*, deprecated, renamed: "{{projectName}}API.Configuration")
@ -20,9 +21,32 @@ extension {{projectName}}API {
// This value is used to configure the date formatter that is used to serialize dates into JSON format.
// You must set it prior to encoding any dates, and it will only be read once.
@available(*, unavailable, message: "To set a different date format, use CodableHelper.dateFormatter instead.")
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} static var dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"{{/useVapor}}
}
{{#swiftUseApiNamespace}}
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} static var dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"{{/useVapor}}{{#useAlamofire}}
/// ResponseSerializer that will be used by the generator for `Data` responses
///
/// If unchanged, Alamofires default `DataResponseSerializer` will be used.
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} static var dataResponseSerializer: AnyResponseSerializer<Data> = AnyResponseSerializer(DataResponseSerializer())
/// ResponseSerializer that will be used by the generator for `String` responses
///
/// If unchanged, Alamofires default `StringResponseSerializer` will be used.
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} static var stringResponseSerializer: AnyResponseSerializer<String> = AnyResponseSerializer(StringResponseSerializer()){{/useAlamofire}}
}
{{#useAlamofire}}
/// Type-erased response serializer
///
/// This is needed in order to use `ResponseSerializer` as a Type in `Configuration`. Obsolete with `any` keyword in Swift >= 5.7
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} struct AnyResponseSerializer<T>: ResponseSerializer {
let _serialize: (URLRequest?, HTTPURLResponse?, Data?, Error?) throws -> T
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} init<V: ResponseSerializer>(_ delegatee: V) where V.SerializedObject == T {
_serialize = delegatee.serialize
}
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> T {
try _serialize(request, response, data, error)
}
}{{/useAlamofire}}{{#swiftUseApiNamespace}}}
{{/swiftUseApiNamespace}}

View File

@ -169,7 +169,9 @@ private var managerStore = SynchronizedDictionary<String, Alamofire.Session>()
switch T.self {
case is Void.Type:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { voidResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { voidResponse in
cleanupRequest()
switch voidResponse.result {
@ -261,7 +263,9 @@ private var managerStore = SynchronizedDictionary<String, Alamofire.Session>()
switch T.self {
case is String.Type:
validatedRequest.responseString(queue: apiResponseQueue, completionHandler: { stringResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.stringResponseSerializer,
completionHandler: { stringResponse in
cleanupRequest()
switch stringResponse.result {
@ -273,7 +277,9 @@ private var managerStore = SynchronizedDictionary<String, Alamofire.Session>()
})
case is URL.Type:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { dataResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { dataResponse in
cleanupRequest()
do {
@ -319,7 +325,9 @@ private var managerStore = SynchronizedDictionary<String, Alamofire.Session>()
return
})
case is Void.Type:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { voidResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { voidResponse in
cleanupRequest()
switch voidResponse.result {
@ -331,7 +339,9 @@ private var managerStore = SynchronizedDictionary<String, Alamofire.Session>()
})
case is Data.Type:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { dataResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { dataResponse in
cleanupRequest()
switch dataResponse.result {
@ -343,7 +353,9 @@ private var managerStore = SynchronizedDictionary<String, Alamofire.Session>()
})
default:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { dataResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { dataResponse in
cleanupRequest()
if case let .failure(error) = dataResponse.result {

View File

@ -169,7 +169,9 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
switch T.self {
case is Void.Type:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { voidResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { voidResponse in
cleanupRequest()
switch voidResponse.result {
@ -261,7 +263,9 @@ open class AlamofireDecodableRequestBuilder<T: Decodable>: AlamofireRequestBuild
switch T.self {
case is String.Type:
validatedRequest.responseString(queue: apiResponseQueue, completionHandler: { stringResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.stringResponseSerializer,
completionHandler: { stringResponse in
cleanupRequest()
switch stringResponse.result {
@ -273,7 +277,9 @@ open class AlamofireDecodableRequestBuilder<T: Decodable>: AlamofireRequestBuild
})
case is URL.Type:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { dataResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { dataResponse in
cleanupRequest()
do {
@ -319,7 +325,9 @@ open class AlamofireDecodableRequestBuilder<T: Decodable>: AlamofireRequestBuild
return
})
case is Void.Type:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { voidResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { voidResponse in
cleanupRequest()
switch voidResponse.result {
@ -331,7 +339,9 @@ open class AlamofireDecodableRequestBuilder<T: Decodable>: AlamofireRequestBuild
})
case is Data.Type:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { dataResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { dataResponse in
cleanupRequest()
switch dataResponse.result {
@ -343,7 +353,9 @@ open class AlamofireDecodableRequestBuilder<T: Decodable>: AlamofireRequestBuild
})
default:
validatedRequest.responseData(queue: apiResponseQueue, completionHandler: { dataResponse in
validatedRequest.response(queue: apiResponseQueue,
responseSerializer: Configuration.dataResponseSerializer,
completionHandler: { dataResponse in
cleanupRequest()
if case let .failure(error) = dataResponse.result {

View File

@ -5,6 +5,7 @@
//
import Foundation
import Alamofire
open class Configuration {
@ -12,4 +13,28 @@ open class Configuration {
// You must set it prior to encoding any dates, and it will only be read once.
@available(*, unavailable, message: "To set a different date format, use CodableHelper.dateFormatter instead.")
public static var dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
/// ResponseSerializer that will be used by the generator for `Data` responses
///
/// If unchanged, Alamofires default `DataResponseSerializer` will be used.
public static var dataResponseSerializer: AnyResponseSerializer<Data> = AnyResponseSerializer(DataResponseSerializer())
/// ResponseSerializer that will be used by the generator for `String` responses
///
/// If unchanged, Alamofires default `StringResponseSerializer` will be used.
public static var stringResponseSerializer: AnyResponseSerializer<String> = AnyResponseSerializer(StringResponseSerializer())
}
/// Type-erased response serializer
///
/// This is needed in order to use `ResponseSerializer` as a Type in `Configuration`. Obsolete with `any` keyword in Swift >= 5.7
public struct AnyResponseSerializer<T>: ResponseSerializer {
let _serialize: (URLRequest?, HTTPURLResponse?, Data?, Error?) throws -> T
public init<V: ResponseSerializer>(_ delegatee: V) where V.SerializedObject == T {
_serialize = delegatee.serialize
}
public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> T {
try _serialize(request, response, data, error)
}
}