@@ -15,18 +15,32 @@ import FoundationNetworking
15
15
extension URLSession {
16
16
static let parse : URLSession = {
17
17
if !ParseSwift. configuration. isTestingSDK {
18
- return URLSession ( configuration: . default,
18
+ let configuration = URLSessionConfiguration . default
19
+ configuration. urlCache = URLCache . parse
20
+ configuration. requestCachePolicy = ParseSwift . configuration. requestCachePolicy
21
+ configuration. httpAdditionalHeaders = ParseSwift . configuration. httpAdditionalHeaders
22
+ return URLSession ( configuration: configuration,
19
23
delegate: ParseSwift . sessionDelegate,
20
24
delegateQueue: nil )
21
25
} else {
26
+ let session = URLSession . shared
27
+ session. configuration. urlCache = URLCache . parse
22
28
return URLSession . shared
23
29
}
24
30
} ( )
25
31
26
- internal func makeResult< U> ( responseData: Data ? ,
32
+ internal func makeResult< U> ( request: URLRequest ,
33
+ responseData: Data ? ,
27
34
urlResponse: URLResponse ? ,
28
35
responseError: Error ? ,
29
36
mapper: @escaping ( Data ) throws -> U ) -> Result < U , ParseError > {
37
+ guard let response = urlResponse else {
38
+ guard let parseError = responseError as? ParseError else {
39
+ return . failure( ParseError ( code: . unknownError,
40
+ message: " No response from server " ) )
41
+ }
42
+ return . failure( parseError)
43
+ }
30
44
if let responseError = responseError {
31
45
guard let parseError = responseError as? ParseError else {
32
46
return . failure( ParseError ( code: . unknownError,
@@ -37,6 +51,11 @@ extension URLSession {
37
51
38
52
if let responseData = responseData {
39
53
do {
54
+ if URLSession . parse. configuration. urlCache? . cachedResponse ( for: request) == nil {
55
+ URLSession . parse. configuration. urlCache? . storeCachedResponse ( . init( response: response,
56
+ data: responseData) ,
57
+ for: request)
58
+ }
40
59
return try . success( mapper ( responseData) )
41
60
} catch {
42
61
if let error = try ? ParseCoding . jsonDecoder ( ) . decode ( ParseError . self, from: responseData) {
@@ -49,11 +68,11 @@ extension URLSession {
49
68
options: . prettyPrinted) else {
50
69
return . failure( ParseError ( code: . unknownError,
51
70
// swiftlint:disable:next line_length
52
- message: " Error decoding parse-server response: \( String ( describing : urlResponse ) ) with error: \( error. localizedDescription) Format: \( String ( describing: String ( data: responseData, encoding: . utf8) ) ) " ) )
71
+ message: " Error decoding parse-server response: \( response ) with error: \( error. localizedDescription) Format: \( String ( describing: String ( data: responseData, encoding: . utf8) ) ) " ) )
53
72
}
54
73
return . failure( ParseError ( code: . unknownError,
55
74
// swiftlint:disable:next line_length
56
- message: " Error decoding parse-server response: \( String ( describing : urlResponse ) ) with error: \( error. localizedDescription) Format: \( String ( describing: String ( data: json, encoding: . utf8) ) ) " ) )
75
+ message: " Error decoding parse-server response: \( response ) with error: \( error. localizedDescription) Format: \( String ( describing: String ( data: json, encoding: . utf8) ) ) " ) )
57
76
}
58
77
return . failure( parseError)
59
78
}
@@ -63,10 +82,18 @@ extension URLSession {
63
82
message: " Unable to sync with parse-server: \( String ( describing: urlResponse) ) . " ) )
64
83
}
65
84
66
- internal func makeResult< U> ( location: URL ? ,
85
+ internal func makeResult< U> ( request: URLRequest ,
86
+ location: URL ? ,
67
87
urlResponse: URLResponse ? ,
68
88
responseError: Error ? ,
69
89
mapper: @escaping ( Data ) throws -> U ) -> Result < U , ParseError > {
90
+ guard let response = urlResponse else {
91
+ guard let parseError = responseError as? ParseError else {
92
+ return . failure( ParseError ( code: . unknownError,
93
+ message: " No response from server " ) )
94
+ }
95
+ return . failure( parseError)
96
+ }
70
97
if let responseError = responseError {
71
98
guard let parseError = responseError as? ParseError else {
72
99
return . failure( ParseError ( code: . unknownError,
@@ -78,19 +105,24 @@ extension URLSession {
78
105
if let location = location {
79
106
do {
80
107
let data = try ParseCoding . jsonEncoder ( ) . encode ( location)
108
+ if URLSession . parse. configuration. urlCache? . cachedResponse ( for: request) == nil {
109
+ URLSession . parse. configuration. urlCache? . storeCachedResponse ( . init( response: response,
110
+ data: data) ,
111
+ for: request)
112
+ }
81
113
return try . success( mapper ( data) )
82
114
} catch {
83
115
guard let parseError = error as? ParseError else {
84
116
return . failure( ParseError ( code: . unknownError,
85
117
// swiftlint:disable:next line_length
86
- message: " Error decoding parse-server response: \( String ( describing : urlResponse ) ) with error: \( error. localizedDescription) " ) )
118
+ message: " Error decoding parse-server response: \( response ) with error: \( error. localizedDescription) " ) )
87
119
}
88
120
return . failure( parseError)
89
121
}
90
122
}
91
123
92
124
return . failure( ParseError ( code: . unknownError,
93
- message: " Unable to sync with parse-server: \( String ( describing : urlResponse ) ) . " ) )
125
+ message: " Unable to sync with parse-server: \( response ) . " ) )
94
126
}
95
127
96
128
internal func dataTask< U> (
@@ -100,9 +132,10 @@ extension URLSession {
100
132
) {
101
133
102
134
dataTask ( with: request) { ( responseData, urlResponse, responseError) in
103
- completion ( self . makeResult ( responseData: responseData,
104
- urlResponse: urlResponse,
105
- responseError: responseError, mapper: mapper) )
135
+ completion ( self . makeResult ( request: request,
136
+ responseData: responseData,
137
+ urlResponse: urlResponse,
138
+ responseError: responseError, mapper: mapper) )
106
139
} . resume ( )
107
140
}
108
141
}
@@ -120,15 +153,17 @@ extension URLSession {
120
153
var task : URLSessionTask ?
121
154
if let data = data {
122
155
task = uploadTask ( with: request, from: data) { ( responseData, urlResponse, responseError) in
123
- completion ( self . makeResult ( responseData: responseData,
124
- urlResponse: urlResponse,
125
- responseError: responseError, mapper: mapper) )
156
+ completion ( self . makeResult ( request: request,
157
+ responseData: responseData,
158
+ urlResponse: urlResponse,
159
+ responseError: responseError, mapper: mapper) )
126
160
}
127
161
} else if let file = file {
128
162
task = uploadTask ( with: request, fromFile: file) { ( responseData, urlResponse, responseError) in
129
- completion ( self . makeResult ( responseData: responseData,
130
- urlResponse: urlResponse,
131
- responseError: responseError, mapper: mapper) )
163
+ completion ( self . makeResult ( request: request,
164
+ responseData: responseData,
165
+ urlResponse: urlResponse,
166
+ responseError: responseError, mapper: mapper) )
132
167
}
133
168
} else {
134
169
completion ( . failure( ParseError ( code: . unknownError, message: " data and file both can't be nil " ) ) )
@@ -148,23 +183,23 @@ extension URLSession {
148
183
completion: @escaping ( Result < U , ParseError > ) -> Void
149
184
) {
150
185
let task = downloadTask ( with: request) { ( location, urlResponse, responseError) in
151
- completion ( self . makeResult ( location: location,
152
- urlResponse: urlResponse,
153
- responseError: responseError, mapper: mapper) )
186
+ completion ( self . makeResult ( request: request,
187
+ location: location,
188
+ urlResponse: urlResponse,
189
+ responseError: responseError, mapper: mapper) )
154
190
}
155
191
ParseSwift . sessionDelegate. downloadDelegates [ task] = progress
156
192
ParseSwift . sessionDelegate. taskCallbackQueues [ task] = callbackQueue
157
193
task. resume ( )
158
194
}
159
195
160
196
internal func downloadTask< U> (
161
- with url : URL ,
197
+ with request : URLRequest ,
162
198
mapper: @escaping ( Data ) throws -> U ,
163
199
completion: @escaping ( Result < U , ParseError > ) -> Void
164
200
) {
165
-
166
- downloadTask ( with: url) { ( location, urlResponse, responseError) in
167
- completion ( self . makeResult ( location: location,
201
+ downloadTask ( with: request) { ( location, urlResponse, responseError) in
202
+ completion ( self . makeResult ( request: request, location: location,
168
203
urlResponse: urlResponse,
169
204
responseError: responseError,
170
205
mapper: mapper) )
0 commit comments