added iOS source code
[wl-app.git] / iOS / Pods / Alamofire / Source / Response.swift
1 //
2 //  Response.swift
3 //
4 //  Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
5 //
6 //  Permission is hereby granted, free of charge, to any person obtaining a copy
7 //  of this software and associated documentation files (the "Software"), to deal
8 //  in the Software without restriction, including without limitation the rights
9 //  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 //  copies of the Software, and to permit persons to whom the Software is
11 //  furnished to do so, subject to the following conditions:
12 //
13 //  The above copyright notice and this permission notice shall be included in
14 //  all copies or substantial portions of the Software.
15 //
16 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 //  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 //  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 //  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 //  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 //  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 //  THE SOFTWARE.
23 //
24
25 import Foundation
26
27 /// Used to store all data associated with an non-serialized response of a data or upload request.
28 public struct DefaultDataResponse {
29     /// The URL request sent to the server.
30     public let request: URLRequest?
31
32     /// The server's response to the URL request.
33     public let response: HTTPURLResponse?
34
35     /// The data returned by the server.
36     public let data: Data?
37
38     /// The error encountered while executing or validating the request.
39     public let error: Error?
40
41     /// The timeline of the complete lifecycle of the request.
42     public let timeline: Timeline
43
44     var _metrics: AnyObject?
45
46     /// Creates a `DefaultDataResponse` instance from the specified parameters.
47     ///
48     /// - Parameters:
49     ///   - request:  The URL request sent to the server.
50     ///   - response: The server's response to the URL request.
51     ///   - data:     The data returned by the server.
52     ///   - error:    The error encountered while executing or validating the request.
53     ///   - timeline: The timeline of the complete lifecycle of the request. `Timeline()` by default.
54     ///   - metrics:  The task metrics containing the request / response statistics. `nil` by default.
55     public init(
56         request: URLRequest?,
57         response: HTTPURLResponse?,
58         data: Data?,
59         error: Error?,
60         timeline: Timeline = Timeline(),
61         metrics: AnyObject? = nil)
62     {
63         self.request = request
64         self.response = response
65         self.data = data
66         self.error = error
67         self.timeline = timeline
68     }
69 }
70
71 // MARK: -
72
73 /// Used to store all data associated with a serialized response of a data or upload request.
74 public struct DataResponse<Value> {
75     /// The URL request sent to the server.
76     public let request: URLRequest?
77
78     /// The server's response to the URL request.
79     public let response: HTTPURLResponse?
80
81     /// The data returned by the server.
82     public let data: Data?
83
84     /// The result of response serialization.
85     public let result: Result<Value>
86
87     /// The timeline of the complete lifecycle of the request.
88     public let timeline: Timeline
89
90     /// Returns the associated value of the result if it is a success, `nil` otherwise.
91     public var value: Value? { return result.value }
92
93     /// Returns the associated error value if the result if it is a failure, `nil` otherwise.
94     public var error: Error? { return result.error }
95
96     var _metrics: AnyObject?
97
98     /// Creates a `DataResponse` instance with the specified parameters derived from response serialization.
99     ///
100     /// - parameter request:  The URL request sent to the server.
101     /// - parameter response: The server's response to the URL request.
102     /// - parameter data:     The data returned by the server.
103     /// - parameter result:   The result of response serialization.
104     /// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
105     ///
106     /// - returns: The new `DataResponse` instance.
107     public init(
108         request: URLRequest?,
109         response: HTTPURLResponse?,
110         data: Data?,
111         result: Result<Value>,
112         timeline: Timeline = Timeline())
113     {
114         self.request = request
115         self.response = response
116         self.data = data
117         self.result = result
118         self.timeline = timeline
119     }
120 }
121
122 // MARK: -
123
124 extension DataResponse: CustomStringConvertible, CustomDebugStringConvertible {
125     /// The textual representation used when written to an output stream, which includes whether the result was a
126     /// success or failure.
127     public var description: String {
128         return result.debugDescription
129     }
130
131     /// The debug textual representation used when written to an output stream, which includes the URL request, the URL
132     /// response, the server data, the response serialization result and the timeline.
133     public var debugDescription: String {
134         var output: [String] = []
135
136         output.append(request != nil ? "[Request]: \(request!.httpMethod ?? "GET") \(request!)" : "[Request]: nil")
137         output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
138         output.append("[Data]: \(data?.count ?? 0) bytes")
139         output.append("[Result]: \(result.debugDescription)")
140         output.append("[Timeline]: \(timeline.debugDescription)")
141
142         return output.joined(separator: "\n")
143     }
144 }
145
146 // MARK: -
147
148 extension DataResponse {
149     /// Evaluates the specified closure when the result of this `DataResponse` is a success, passing the unwrapped
150     /// result value as a parameter.
151     ///
152     /// Use the `map` method with a closure that does not throw. For example:
153     ///
154     ///     let possibleData: DataResponse<Data> = ...
155     ///     let possibleInt = possibleData.map { $0.count }
156     ///
157     /// - parameter transform: A closure that takes the success value of the instance's result.
158     ///
159     /// - returns: A `DataResponse` whose result wraps the value returned by the given closure. If this instance's
160     ///            result is a failure, returns a response wrapping the same failure.
161     public func map<T>(_ transform: (Value) -> T) -> DataResponse<T> {
162         var response = DataResponse<T>(
163             request: request,
164             response: self.response,
165             data: data,
166             result: result.map(transform),
167             timeline: timeline
168         )
169
170         response._metrics = _metrics
171
172         return response
173     }
174
175     /// Evaluates the given closure when the result of this `DataResponse` is a success, passing the unwrapped result
176     /// value as a parameter.
177     ///
178     /// Use the `flatMap` method with a closure that may throw an error. For example:
179     ///
180     ///     let possibleData: DataResponse<Data> = ...
181     ///     let possibleObject = possibleData.flatMap {
182     ///         try JSONSerialization.jsonObject(with: $0)
183     ///     }
184     ///
185     /// - parameter transform: A closure that takes the success value of the instance's result.
186     ///
187     /// - returns: A success or failure `DataResponse` depending on the result of the given closure. If this instance's
188     ///            result is a failure, returns the same failure.
189     public func flatMap<T>(_ transform: (Value) throws -> T) -> DataResponse<T> {
190         var response = DataResponse<T>(
191             request: request,
192             response: self.response,
193             data: data,
194             result: result.flatMap(transform),
195             timeline: timeline
196         )
197
198         response._metrics = _metrics
199
200         return response
201     }
202
203     /// Evaluates the specified closure when the `DataResponse` is a failure, passing the unwrapped error as a parameter.
204     ///
205     /// Use the `mapError` function with a closure that does not throw. For example:
206     ///
207     ///     let possibleData: DataResponse<Data> = ...
208     ///     let withMyError = possibleData.mapError { MyError.error($0) }
209     ///
210     /// - Parameter transform: A closure that takes the error of the instance.
211     /// - Returns: A `DataResponse` instance containing the result of the transform.
212     public func mapError<E: Error>(_ transform: (Error) -> E) -> DataResponse {
213         var response = DataResponse(
214             request: request,
215             response: self.response,
216             data: data,
217             result: result.mapError(transform),
218             timeline: timeline
219         )
220
221         response._metrics = _metrics
222
223         return response
224     }
225
226     /// Evaluates the specified closure when the `DataResponse` is a failure, passing the unwrapped error as a parameter.
227     ///
228     /// Use the `flatMapError` function with a closure that may throw an error. For example:
229     ///
230     ///     let possibleData: DataResponse<Data> = ...
231     ///     let possibleObject = possibleData.flatMapError {
232     ///         try someFailableFunction(taking: $0)
233     ///     }
234     ///
235     /// - Parameter transform: A throwing closure that takes the error of the instance.
236     ///
237     /// - Returns: A `DataResponse` instance containing the result of the transform.
238     public func flatMapError<E: Error>(_ transform: (Error) throws -> E) -> DataResponse {
239         var response = DataResponse(
240             request: request,
241             response: self.response,
242             data: data,
243             result: result.flatMapError(transform),
244             timeline: timeline
245         )
246
247         response._metrics = _metrics
248
249         return response
250     }
251 }
252
253 // MARK: -
254
255 /// Used to store all data associated with an non-serialized response of a download request.
256 public struct DefaultDownloadResponse {
257     /// The URL request sent to the server.
258     public let request: URLRequest?
259
260     /// The server's response to the URL request.
261     public let response: HTTPURLResponse?
262
263     /// The temporary destination URL of the data returned from the server.
264     public let temporaryURL: URL?
265
266     /// The final destination URL of the data returned from the server if it was moved.
267     public let destinationURL: URL?
268
269     /// The resume data generated if the request was cancelled.
270     public let resumeData: Data?
271
272     /// The error encountered while executing or validating the request.
273     public let error: Error?
274
275     /// The timeline of the complete lifecycle of the request.
276     public let timeline: Timeline
277
278     var _metrics: AnyObject?
279
280     /// Creates a `DefaultDownloadResponse` instance from the specified parameters.
281     ///
282     /// - Parameters:
283     ///   - request:        The URL request sent to the server.
284     ///   - response:       The server's response to the URL request.
285     ///   - temporaryURL:   The temporary destination URL of the data returned from the server.
286     ///   - destinationURL: The final destination URL of the data returned from the server if it was moved.
287     ///   - resumeData:     The resume data generated if the request was cancelled.
288     ///   - error:          The error encountered while executing or validating the request.
289     ///   - timeline:       The timeline of the complete lifecycle of the request. `Timeline()` by default.
290     ///   - metrics:        The task metrics containing the request / response statistics. `nil` by default.
291     public init(
292         request: URLRequest?,
293         response: HTTPURLResponse?,
294         temporaryURL: URL?,
295         destinationURL: URL?,
296         resumeData: Data?,
297         error: Error?,
298         timeline: Timeline = Timeline(),
299         metrics: AnyObject? = nil)
300     {
301         self.request = request
302         self.response = response
303         self.temporaryURL = temporaryURL
304         self.destinationURL = destinationURL
305         self.resumeData = resumeData
306         self.error = error
307         self.timeline = timeline
308     }
309 }
310
311 // MARK: -
312
313 /// Used to store all data associated with a serialized response of a download request.
314 public struct DownloadResponse<Value> {
315     /// The URL request sent to the server.
316     public let request: URLRequest?
317
318     /// The server's response to the URL request.
319     public let response: HTTPURLResponse?
320
321     /// The temporary destination URL of the data returned from the server.
322     public let temporaryURL: URL?
323
324     /// The final destination URL of the data returned from the server if it was moved.
325     public let destinationURL: URL?
326
327     /// The resume data generated if the request was cancelled.
328     public let resumeData: Data?
329
330     /// The result of response serialization.
331     public let result: Result<Value>
332
333     /// The timeline of the complete lifecycle of the request.
334     public let timeline: Timeline
335
336     /// Returns the associated value of the result if it is a success, `nil` otherwise.
337     public var value: Value? { return result.value }
338
339     /// Returns the associated error value if the result if it is a failure, `nil` otherwise.
340     public var error: Error? { return result.error }
341
342     var _metrics: AnyObject?
343
344     /// Creates a `DownloadResponse` instance with the specified parameters derived from response serialization.
345     ///
346     /// - parameter request:        The URL request sent to the server.
347     /// - parameter response:       The server's response to the URL request.
348     /// - parameter temporaryURL:   The temporary destination URL of the data returned from the server.
349     /// - parameter destinationURL: The final destination URL of the data returned from the server if it was moved.
350     /// - parameter resumeData:     The resume data generated if the request was cancelled.
351     /// - parameter result:         The result of response serialization.
352     /// - parameter timeline:       The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
353     ///
354     /// - returns: The new `DownloadResponse` instance.
355     public init(
356         request: URLRequest?,
357         response: HTTPURLResponse?,
358         temporaryURL: URL?,
359         destinationURL: URL?,
360         resumeData: Data?,
361         result: Result<Value>,
362         timeline: Timeline = Timeline())
363     {
364         self.request = request
365         self.response = response
366         self.temporaryURL = temporaryURL
367         self.destinationURL = destinationURL
368         self.resumeData = resumeData
369         self.result = result
370         self.timeline = timeline
371     }
372 }
373
374 // MARK: -
375
376 extension DownloadResponse: CustomStringConvertible, CustomDebugStringConvertible {
377     /// The textual representation used when written to an output stream, which includes whether the result was a
378     /// success or failure.
379     public var description: String {
380         return result.debugDescription
381     }
382
383     /// The debug textual representation used when written to an output stream, which includes the URL request, the URL
384     /// response, the temporary and destination URLs, the resume data, the response serialization result and the
385     /// timeline.
386     public var debugDescription: String {
387         var output: [String] = []
388
389         output.append(request != nil ? "[Request]: \(request!.httpMethod ?? "GET") \(request!)" : "[Request]: nil")
390         output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
391         output.append("[TemporaryURL]: \(temporaryURL?.path ?? "nil")")
392         output.append("[DestinationURL]: \(destinationURL?.path ?? "nil")")
393         output.append("[ResumeData]: \(resumeData?.count ?? 0) bytes")
394         output.append("[Result]: \(result.debugDescription)")
395         output.append("[Timeline]: \(timeline.debugDescription)")
396
397         return output.joined(separator: "\n")
398     }
399 }
400
401 // MARK: -
402
403 extension DownloadResponse {
404     /// Evaluates the given closure when the result of this `DownloadResponse` is a success, passing the unwrapped
405     /// result value as a parameter.
406     ///
407     /// Use the `map` method with a closure that does not throw. For example:
408     ///
409     ///     let possibleData: DownloadResponse<Data> = ...
410     ///     let possibleInt = possibleData.map { $0.count }
411     ///
412     /// - parameter transform: A closure that takes the success value of the instance's result.
413     ///
414     /// - returns: A `DownloadResponse` whose result wraps the value returned by the given closure. If this instance's
415     ///            result is a failure, returns a response wrapping the same failure.
416     public func map<T>(_ transform: (Value) -> T) -> DownloadResponse<T> {
417         var response = DownloadResponse<T>(
418             request: request,
419             response: self.response,
420             temporaryURL: temporaryURL,
421             destinationURL: destinationURL,
422             resumeData: resumeData,
423             result: result.map(transform),
424             timeline: timeline
425         )
426
427         response._metrics = _metrics
428
429         return response
430     }
431
432     /// Evaluates the given closure when the result of this `DownloadResponse` is a success, passing the unwrapped
433     /// result value as a parameter.
434     ///
435     /// Use the `flatMap` method with a closure that may throw an error. For example:
436     ///
437     ///     let possibleData: DownloadResponse<Data> = ...
438     ///     let possibleObject = possibleData.flatMap {
439     ///         try JSONSerialization.jsonObject(with: $0)
440     ///     }
441     ///
442     /// - parameter transform: A closure that takes the success value of the instance's result.
443     ///
444     /// - returns: A success or failure `DownloadResponse` depending on the result of the given closure. If this
445     /// instance's result is a failure, returns the same failure.
446     public func flatMap<T>(_ transform: (Value) throws -> T) -> DownloadResponse<T> {
447         var response = DownloadResponse<T>(
448             request: request,
449             response: self.response,
450             temporaryURL: temporaryURL,
451             destinationURL: destinationURL,
452             resumeData: resumeData,
453             result: result.flatMap(transform),
454             timeline: timeline
455         )
456
457         response._metrics = _metrics
458
459         return response
460     }
461
462     /// Evaluates the specified closure when the `DownloadResponse` is a failure, passing the unwrapped error as a parameter.
463     ///
464     /// Use the `mapError` function with a closure that does not throw. For example:
465     ///
466     ///     let possibleData: DownloadResponse<Data> = ...
467     ///     let withMyError = possibleData.mapError { MyError.error($0) }
468     ///
469     /// - Parameter transform: A closure that takes the error of the instance.
470     /// - Returns: A `DownloadResponse` instance containing the result of the transform.
471     public func mapError<E: Error>(_ transform: (Error) -> E) -> DownloadResponse {
472         var response = DownloadResponse(
473             request: request,
474             response: self.response,
475             temporaryURL: temporaryURL,
476             destinationURL: destinationURL,
477             resumeData: resumeData,
478             result: result.mapError(transform),
479             timeline: timeline
480         )
481
482         response._metrics = _metrics
483
484         return response
485     }
486
487     /// Evaluates the specified closure when the `DownloadResponse` is a failure, passing the unwrapped error as a parameter.
488     ///
489     /// Use the `flatMapError` function with a closure that may throw an error. For example:
490     ///
491     ///     let possibleData: DownloadResponse<Data> = ...
492     ///     let possibleObject = possibleData.flatMapError {
493     ///         try someFailableFunction(taking: $0)
494     ///     }
495     ///
496     /// - Parameter transform: A throwing closure that takes the error of the instance.
497     ///
498     /// - Returns: A `DownloadResponse` instance containing the result of the transform.
499     public func flatMapError<E: Error>(_ transform: (Error) throws -> E) -> DownloadResponse {
500         var response = DownloadResponse(
501             request: request,
502             response: self.response,
503             temporaryURL: temporaryURL,
504             destinationURL: destinationURL,
505             resumeData: resumeData,
506             result: result.flatMapError(transform),
507             timeline: timeline
508         )
509
510         response._metrics = _metrics
511
512         return response
513     }
514 }
515
516 // MARK: -
517
518 protocol Response {
519     /// The task metrics containing the request / response statistics.
520     var _metrics: AnyObject? { get set }
521     mutating func add(_ metrics: AnyObject?)
522 }
523
524 extension Response {
525     mutating func add(_ metrics: AnyObject?) {
526         #if !os(watchOS)
527             guard #available(iOS 10.0, macOS 10.12, tvOS 10.0, *) else { return }
528             guard let metrics = metrics as? URLSessionTaskMetrics else { return }
529
530             _metrics = metrics
531         #endif
532     }
533 }
534
535 // MARK: -
536
537 @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
538 extension DefaultDataResponse: Response {
539 #if !os(watchOS)
540     /// The task metrics containing the request / response statistics.
541     public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
542 #endif
543 }
544
545 @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
546 extension DataResponse: Response {
547 #if !os(watchOS)
548     /// The task metrics containing the request / response statistics.
549     public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
550 #endif
551 }
552
553 @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
554 extension DefaultDownloadResponse: Response {
555 #if !os(watchOS)
556     /// The task metrics containing the request / response statistics.
557     public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
558 #endif
559 }
560
561 @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
562 extension DownloadResponse: Response {
563 #if !os(watchOS)
564     /// The task metrics containing the request / response statistics.
565     public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
566 #endif
567 }