0001    // ResponseSerialization.swift
0002    //
0003    // Copyright (c) 2014–2016 Alamofire Software Foundation (http://alamofire.org/)
0004    //
0005    // Permission is hereby granted, free of charge, to any person obtaining a copy
0006    // of this software and associated documentation files (the "Software"), to deal
0007    // in the Software without restriction, including without limitation the rights
0008    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0009    // copies of the Software, and to permit persons to whom the Software is
0010    // furnished to do so, subject to the following conditions:
0011    //
0012    // The above copyright notice and this permission notice shall be included in
0013    // all copies or substantial portions of the Software.
0014    //
0015    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0018    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0021    // THE SOFTWARE.
0022    
0023    import Foundation
0024    
0025    // MARK: ResponseSerializer
0026    
0027    /**
0028        The type in which all response serializers must conform to in order to serialize a response.
0029    */
0030    public protocol ResponseSerializerType
ResponseSerialization.swift:48
public struct ResponseSerializer<Value, Error: ErrorType>: ResponseSerializerType {
ResponseSerialization.swift:108
    public func response<T: ResponseSerializerType>(
{ 0031 /// The type of serialized object to be created by this `ResponseSerializerType`. 0032 typealias SerializedObject
ResponseSerialization.swift:40
    var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<SerializedObject, ErrorObject> { get }
ResponseSerialization.swift:111
        completionHandler: Response<T.SerializedObject, T.ErrorObject> -> Void)
ResponseSerialization.swift:132
            let response = Response<T.SerializedObject, T.ErrorObject>(
0033 0034 /// The type of error to be created by this `ResponseSerializer` if serialization fails. 0035 typealias ErrorObject
ResponseSerialization.swift:40
    var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<SerializedObject, ErrorObject> { get }
ResponseSerialization.swift:111
        completionHandler: Response<T.SerializedObject, T.ErrorObject> -> Void)
ResponseSerialization.swift:132
            let response = Response<T.SerializedObject, T.ErrorObject>(
: ErrorType 0036 0037 /** 0038 A closure used by response handlers that takes a request, response, data and error and returns a result. 0039 */ 0040 var serializeResponse
ResponseSerialization.swift:115
            let result = responseSerializer.serializeResponse(
: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<SerializedObject, ErrorObject> { get } 0041 } 0042 0043 // MARK: - 0044 0045 /** 0046 A generic `ResponseSerializerType` used to serialize a request, response, and data into a serialized object. 0047 */ 0048 public struct ResponseSerializer
ResponseSerialization.swift:156
    public static func dataResponseSerializer() -> ResponseSerializer<NSData, NSError> {
ResponseSerialization.swift:157
        return ResponseSerializer { _, response, data, error in
ResponseSerialization.swift:199
        -> ResponseSerializer<String, NSError>
ResponseSerialization.swift:201
        return ResponseSerializer { _, response, data, error in
ResponseSerialization.swift:268
        -> ResponseSerializer<AnyObject, NSError>
ResponseSerialization.swift:270
        return ResponseSerializer { _, response, data, error in
ResponseSerialization.swift:324
        -> ResponseSerializer<AnyObject, NSError>
ResponseSerialization.swift:326
        return ResponseSerializer { _, response, data, error in
<Value
ResponseSerialization.swift:50
    public typealias SerializedObject = Value
ResponseSerialization.swift:58
    public var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>
ResponseSerialization.swift:67
    public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>) {
, Error
ResponseSerialization.swift:53
    public typealias ErrorObject = Error
ResponseSerialization.swift:58
    public var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>
ResponseSerialization.swift:67
    public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>) {
: ErrorType>: ResponseSerializerType { 0049 /// The type of serialized object to be created by this `ResponseSerializer`. 0050 public typealias SerializedObject = Value 0051 0052 /// The type of error to be created by this `ResponseSerializer` if serialization fails. 0053 public typealias ErrorObject = Error 0054 0055 /** 0056 A closure used by response handlers that takes a request, response, data and error and returns a result. 0057 */ 0058 public var serializeResponse
ResponseSerialization.swift:68
        self.serializeResponse = serializeResponse
: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error> 0059 0060 /** 0061 Initializes the `ResponseSerializer` instance with the given serialize response closure. 0062 0063 - parameter serializeResponse: The closure used to serialize the response. 0064 0065 - returns: The new generic response serializer instance. 0066 */ 0067 public init
ResponseSerialization.swift:157
        return ResponseSerializer { _, response, data, error in
ResponseSerialization.swift:201
        return ResponseSerializer { _, response, data, error in
ResponseSerialization.swift:270
        return ResponseSerializer { _, response, data, error in
ResponseSerialization.swift:326
        return ResponseSerializer { _, response, data, error in
(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>) { 0068 self.serializeResponse = serializeResponse 0069 } 0070 } 0071 0072 // MARK: - Default 0073 0074 extension Request { 0075 0076 /** 0077 Adds a handler to be called once the request has finished. 0078 0079 - parameter queue: The queue on which the completion handler is dispatched. 0080 - parameter completionHandler: The code to be executed once the request has finished. 0081 0082 - returns: The request. 0083 */ 0084 public func response( 0085 queue queue: dispatch_queue_t? = nil, 0086 completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Void) 0087 -> Self 0088 { 0089 delegate.queue.addOperationWithBlock { 0090 dispatch_async(queue ?? dispatch_get_main_queue()) { 0091 completionHandler(self.request, self.response, self.delegate.data, self.delegate.error) 0092 } 0093 } 0094 0095 return self 0096 } 0097 0098 /** 0099 Adds a handler to be called once the request has finished. 0100 0101 - parameter queue: The queue on which the completion handler is dispatched. 0102 - parameter responseSerializer: The response serializer responsible for serializing the request, response, 0103 and data. 0104 - parameter completionHandler: The code to be executed once the request has finished. 0105 0106 - returns: The request. 0107 */ 0108 public func response
ResponseSerialization.swift:180
        return response(responseSerializer: Request.dataResponseSerializer(), completionHandler: completionHandler)
ResponseSerialization.swift:247
        return response(
ResponseSerialization.swift:303
        return response(
ResponseSerialization.swift:361
        return response(
<T: ResponseSerializerType>( 0109 queue queue: dispatch_queue_t? = nil, 0110 responseSerializer: T, 0111 completionHandler: Response<T.SerializedObject, T.ErrorObject> -> Void) 0112 -> Self 0113 { 0114 delegate.queue.addOperationWithBlock { 0115 let result = responseSerializer.serializeResponse( 0116 self.request, 0117 self.response, 0118 self.delegate.data, 0119 self.delegate.error 0120 ) 0121 0122 let requestCompletedTime = self.endTime ?? CFAbsoluteTimeGetCurrent() 0123 let initialResponseTime = self.delegate.initialResponseTime ?? requestCompletedTime 0124 0125 let timeline = Timeline( 0126 requestStartTime: self.startTime ?? CFAbsoluteTimeGetCurrent(), 0127 initialResponseTime: initialResponseTime, 0128 requestCompletedTime: requestCompletedTime, 0129 serializationCompletedTime: CFAbsoluteTimeGetCurrent() 0130 ) 0131 0132 let response = Response<T.SerializedObject, T.ErrorObject>( 0133 request: self.request, 0134 response: self.response, 0135 data: self.delegate.data, 0136 result: result, 0137 timeline: timeline 0138 ) 0139 0140 dispatch_async(queue ?? dispatch_get_main_queue()) { completionHandler(response) } 0141 } 0142 0143 return self 0144 } 0145 } 0146 0147 // MARK: - Data 0148 0149 extension Request { 0150 0151 /** 0152 Creates a response serializer that returns the associated data as-is. 0153 0154 - returns: A data response serializer. 0155 */ 0156 public static func dataResponseSerializer
ResponseSerialization.swift:180
        return response(responseSerializer: Request.dataResponseSerializer(), completionHandler: completionHandler)
() -> ResponseSerializer<NSData, NSError> { 0157 return ResponseSerializer { _, response, data, error in 0158 guard error == nil else { return .Failure(error!) } 0159 0160 if let response = response where response.statusCode == 204 { return .Success(NSData()) } 0161 0162 guard let validData = data else { 0163 let failureReason = "Data could not be serialized. Input data was nil." 0164 let error = Error.errorWithCode(.DataSerializationFailed, failureReason: failureReason) 0165 return .Failure(error) 0166 } 0167 0168 return .Success(validData) 0169 } 0170 } 0171 0172 /** 0173 Adds a handler to be called once the request has finished. 0174 0175 - parameter completionHandler: The code to be executed once the request has finished. 0176 0177 - returns: The request. 0178 */ 0179 public func responseData(completionHandler: Response<NSData, NSError> -> Void) -> Self { 0180 return response(responseSerializer: Request.dataResponseSerializer(), completionHandler: completionHandler) 0181 } 0182 } 0183 0184 // MARK: - String 0185 0186 extension Request { 0187 0188 /** 0189 Creates a response serializer that returns a string initialized from the response data with the specified 0190 string encoding. 0191 0192 - parameter encoding: The string encoding. If `nil`, the string encoding will be determined from the server 0193 response, falling back to the default HTTP default character set, ISO-8859-1. 0194 0195 - returns: A string response serializer. 0196 */ 0197 public static func stringResponseSerializer
ResponseSerialization.swift:248
            responseSerializer: Request.stringResponseSerializer(encoding: encoding),
( 0198 encoding encoding: NSStringEncoding? = nil) 0199 -> ResponseSerializer<String, NSError> 0200 { 0201 return ResponseSerializer { _, response, data, error in 0202 guard error == nil else { return .Failure(error!) } 0203 0204 if let response = response where response.statusCode == 204 { return .Success("") } 0205 0206 guard let validData = data else { 0207 let failureReason = "String could not be serialized. Input data was nil." 0208 let error = Error.errorWithCode(.StringSerializationFailed, failureReason: failureReason) 0209 return .Failure(error) 0210 } 0211 0212 var convertedEncoding = encoding 0213 0214 if let encodingName = response?.textEncodingName where convertedEncoding == nil { 0215 convertedEncoding = CFStringConvertEncodingToNSStringEncoding( 0216 CFStringConvertIANACharSetNameToEncoding(encodingName) 0217 ) 0218 } 0219 0220 let actualEncoding = convertedEncoding ?? NSISOLatin1StringEncoding 0221 0222 if let string = String(data: validData, encoding: actualEncoding) { 0223 return .Success(string) 0224 } else { 0225 let failureReason = "String could not be serialized with encoding: \(actualEncoding)" 0226 let error = Error.errorWithCode(.StringSerializationFailed, failureReason: failureReason) 0227 return .Failure(error) 0228 } 0229 } 0230 } 0231 0232 /** 0233 Adds a handler to be called once the request has finished. 0234 0235 - parameter encoding: The string encoding. If `nil`, the string encoding will be determined from the 0236 server response, falling back to the default HTTP default character set, 0237 ISO-8859-1. 0238 - parameter completionHandler: A closure to be executed once the request has finished. 0239 0240 - returns: The request. 0241 */ 0242 public func responseString( 0243 encoding encoding: NSStringEncoding? = nil, 0244 completionHandler: Response<String, NSError> -> Void) 0245 -> Self 0246 { 0247 return response( 0248 responseSerializer: Request.stringResponseSerializer(encoding: encoding), 0249 completionHandler: completionHandler 0250 ) 0251 } 0252 } 0253 0254 // MARK: - JSON 0255 0256 extension Request { 0257 0258 /** 0259 Creates a response serializer that returns a JSON object constructed from the response data using 0260 `NSJSONSerialization` with the specified reading options. 0261 0262 - parameter options: The JSON serialization reading options. `.AllowFragments` by default. 0263 0264 - returns: A JSON object response serializer. 0265 */ 0266 public static func JSONResponseSerializer
ResponseSerialization.swift:304
            responseSerializer: Request.JSONResponseSerializer(options: options),
( 0267 options options: NSJSONReadingOptions = .AllowFragments) 0268 -> ResponseSerializer<AnyObject, NSError> 0269 { 0270 return ResponseSerializer { _, response, data, error in 0271 guard error == nil else { return .Failure(error!) } 0272 0273 if let response = response where response.statusCode == 204 { return .Success(NSNull()) } 0274 0275 guard let validData = data where validData.length > 0 else { 0276 let failureReason = "JSON could not be serialized. Input data was nil or zero length." 0277 let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason) 0278 return .Failure(error) 0279 } 0280 0281 do { 0282 let JSON = try NSJSONSerialization.JSONObjectWithData(validData, options: options) 0283 return .Success(JSON) 0284 } catch { 0285 return .Failure(error as NSError) 0286 } 0287 } 0288 } 0289 0290 /** 0291 Adds a handler to be called once the request has finished. 0292 0293 - parameter options: The JSON serialization reading options. `.AllowFragments` by default. 0294 - parameter completionHandler: A closure to be executed once the request has finished. 0295 0296 - returns: The request. 0297 */ 0298 public func responseJSON( 0299 options options: NSJSONReadingOptions = .AllowFragments, 0300 completionHandler: Response<AnyObject, NSError> -> Void) 0301 -> Self 0302 { 0303 return response( 0304 responseSerializer: Request.JSONResponseSerializer(options: options), 0305 completionHandler: completionHandler 0306 ) 0307 } 0308 } 0309 0310 // MARK: - Property List 0311 0312 extension Request { 0313 0314 /** 0315 Creates a response serializer that returns an object constructed from the response data using 0316 `NSPropertyListSerialization` with the specified reading options. 0317 0318 - parameter options: The property list reading options. `NSPropertyListReadOptions()` by default. 0319 0320 - returns: A property list object response serializer. 0321 */ 0322 public static func propertyListResponseSerializer
ResponseSerialization.swift:362
            responseSerializer: Request.propertyListResponseSerializer(options: options),
( 0323 options options: NSPropertyListReadOptions = NSPropertyListReadOptions()) 0324 -> ResponseSerializer<AnyObject, NSError> 0325 { 0326 return ResponseSerializer { _, response, data, error in 0327 guard error == nil else { return .Failure(error!) } 0328 0329 if let response = response where response.statusCode == 204 { return .Success(NSNull()) } 0330 0331 guard let validData = data where validData.length > 0 else { 0332 let failureReason = "Property list could not be serialized. Input data was nil or zero length." 0333 let error = Error.errorWithCode(.PropertyListSerializationFailed, failureReason: failureReason) 0334 return .Failure(error) 0335 } 0336 0337 do { 0338 let plist = try NSPropertyListSerialization.propertyListWithData(validData, options: options, format: nil) 0339 return .Success(plist) 0340 } catch { 0341 return .Failure(error as NSError) 0342 } 0343 } 0344 } 0345 0346 /** 0347 Adds a handler to be called once the request has finished. 0348 0349 - parameter options: The property list reading options. `0` by default. 0350 - parameter completionHandler: A closure to be executed once the request has finished. The closure takes 3 0351 arguments: the URL request, the URL response, the server data and the result 0352 produced while creating the property list. 0353 0354 - returns: The request. 0355 */ 0356 public func responsePropertyList( 0357 options options: NSPropertyListReadOptions = NSPropertyListReadOptions(), 0358 completionHandler: Response<AnyObject, NSError> -> Void) 0359 -> Self 0360 { 0361 return response( 0362 responseSerializer: Request.propertyListResponseSerializer(options: options), 0363 completionHandler: completionHandler 0364 ) 0365 } 0366 } 0367