@@ -38,21 +38,12 @@ internal final class BaseAPIClient: APIClient {
3838 endpoint: Endpoint ,
3939 completion: @escaping CompletionCallback < T >
4040 ) -> Cancellable {
41- let apiEndpoint = APIEndpoint ( endpoint : endpoint , headersProvider : headersProvider )
42-
43- return networkProvider . request ( endpoint : apiEndpoint ) { [ weak self] result in
41+ networkProvider . request (
42+ endpoint : buildAPIEndpoint ( from : endpoint )
43+ ) { [ weak self] result in
4444 guard let self = self else { return }
45-
46- switch result {
47- case . success( let response) :
48- self . validateResult (
49- response: response,
50- customDecodingConfiguration: endpoint. decodingConfiguration,
51- completion: completion
52- )
53- case . failure( let error) :
54- completion ( . failure( error) , [ : ] )
55- }
45+
46+ self . handle ( result, for: endpoint, completion: completion)
5647 }
5748 }
5849
@@ -63,69 +54,72 @@ internal final class BaseAPIClient: APIClient {
6354 media: [ MultipartMedia ] ,
6455 completion: @escaping CompletionCallback < T >
6556 ) -> Cancellable {
66- let apiEndpoint = APIEndpoint ( endpoint: endpoint, headersProvider: headersProvider)
67-
68- return networkProvider. multipartRequest (
69- endpoint: apiEndpoint,
57+ networkProvider. multipartRequest (
58+ endpoint: buildAPIEndpoint ( from: endpoint) ,
7059 multipartFormKey: paramsRootKey,
7160 media: media
7261 ) { [ weak self] result in
7362 guard let self = self else { return }
74-
75- switch result {
76- case . success( let response) :
77- self . validateResult (
78- response: response,
79- customDecodingConfiguration: endpoint. decodingConfiguration,
80- completion: completion
81- )
82- case . failure( let error) :
83- completion ( . failure( error) , [ : ] )
84- }
85- }
86- }
87-
88- private func handleCustomAPIError( from response: Network . Response ) -> APIError ? {
89- if response. statusCode == Network . StatusCode. unauthorized {
90- AppDelegate . shared. unexpectedLogout ( )
63+
64+ self . handle ( result, for: endpoint, completion: completion)
9165 }
92-
93- return APIError ( response: response, decodingConfiguration: decodingConfiguration)
9466 }
9567
96- private func validateResult < T: Decodable > (
97- response : Network . Response ,
98- customDecodingConfiguration : DecodingConfiguration ? ,
68+ private func handle < T: Decodable > (
69+ _ result : Result < Network . Response , Error > ,
70+ for endpoint : Endpoint ,
9971 completion: CompletionCallback < T >
10072 ) {
101- let responseData = response. data
102-
103- guard let data = responseData, !data. isEmpty else {
104- if emptyDataStatusCodes. contains ( response. statusCode) {
105- completion ( . success( . none) , response. headers)
106- } else {
107- let emptyResponseInvalidError = App . error (
108- domain: . network,
109- localizedDescription: " Unexpected empty response " . localized
110- )
111- completion ( . failure( emptyResponseInvalidError) , response. headers)
112- }
113-
114- return
73+ switch result {
74+ case . success( let response) : handle ( response, with: endpoint. decodingConfiguration, completion: completion)
75+ case . failure( let error) : completion ( . failure( error) , [ : ] )
11576 }
116-
117- let decoder = JSONDecoder (
118- decodingConfig: customDecodingConfiguration ?? decodingConfiguration
77+ }
78+
79+ private func buildAPIEndpoint( from endpoint: Endpoint ) -> APIEndpoint {
80+ APIEndpoint ( endpoint: endpoint, headersProvider: headersProvider)
81+ }
82+
83+ private var unexpectedResponseError : NSError {
84+ App . error (
85+ domain: . network,
86+ localizedDescription: " Unexpected empty response " . localized
11987 )
88+ }
89+
90+ private func handle< T: Decodable > (
91+ _ response: Network . Response ,
92+ with configuration: DecodingConfiguration ? ,
93+ completion: CompletionCallback < T >
94+ ) {
12095 do {
121- let decodedObject = try decoder. decode ( T . self, from: data)
96+ guard let data = response. data, !data. isEmpty else {
97+ guard emptyDataStatusCodes. contains ( response. statusCode) else { throw unexpectedResponseError }
98+
99+ return completion ( . success( . none) , response. headers)
100+ }
122101
123- completion ( . success( decodedObject ) , response. headers)
102+ completion ( . success( try decode ( data , with : configuration ) ) , response. headers)
124103 } catch let error {
125104 completion (
126105 . failure( handleCustomAPIError ( from: response) ?? error) ,
127106 response. headers
128107 )
129108 }
130109 }
110+
111+ private func decode< M: Decodable > ( _ data: Data , with configuration: DecodingConfiguration ? ) throws -> M {
112+ let decoder = JSONDecoder ( decodingConfig: configuration ?? decodingConfiguration)
113+
114+ return try decoder. decode ( M . self, from: data)
115+ }
116+
117+ private func handleCustomAPIError( from response: Network . Response ) -> APIError ? {
118+ if response. statusCode == Network . StatusCode. unauthorized {
119+ AppDelegate . shared. unexpectedLogout ( )
120+ }
121+
122+ return APIError ( response: response, decodingConfiguration: decodingConfiguration)
123+ }
124+
131125}
0 commit comments