@@ -38,21 +38,12 @@ internal final class BaseAPIClient: APIClient {
38
38
endpoint: Endpoint ,
39
39
completion: @escaping CompletionCallback < T >
40
40
) -> 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
44
44
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)
56
47
}
57
48
}
58
49
@@ -63,69 +54,72 @@ internal final class BaseAPIClient: APIClient {
63
54
media: [ MultipartMedia ] ,
64
55
completion: @escaping CompletionCallback < T >
65
56
) -> 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) ,
70
59
multipartFormKey: paramsRootKey,
71
60
media: media
72
61
) { [ weak self] result in
73
62
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)
91
65
}
92
-
93
- return APIError ( response: response, decodingConfiguration: decodingConfiguration)
94
66
}
95
67
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 ,
99
71
completion: CompletionCallback < T >
100
72
) {
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) , [ : ] )
115
76
}
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
119
87
)
88
+ }
89
+
90
+ private func handle< T: Decodable > (
91
+ _ response: Network . Response ,
92
+ with configuration: DecodingConfiguration ? ,
93
+ completion: CompletionCallback < T >
94
+ ) {
120
95
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
+ }
122
101
123
- completion ( . success( decodedObject ) , response. headers)
102
+ completion ( . success( try decode ( data , with : configuration ) ) , response. headers)
124
103
} catch let error {
125
104
completion (
126
105
. failure( handleCustomAPIError ( from: response) ?? error) ,
127
106
response. headers
128
107
)
129
108
}
130
109
}
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
+
131
125
}
0 commit comments