|
@@ -713,6 +713,20 @@ Requests can be suspended, resumed, and cancelled:
|
|
|
|
|
|
|
|
### Response Serialization
|
|
### Response Serialization
|
|
|
|
|
|
|
|
|
|
+#### Handling Errors
|
|
|
|
|
+
|
|
|
|
|
+Before implementing custom response serializers or object serialization methods, it's important to be prepared to handle any errors that may occur. Alamofire recommends handling these through the use of either your own `NSError` creation methods, or a simple `enum` that conforms to `ErrorType`. For example, this `BackendError` type, which will be used in later examples:
|
|
|
|
|
+
|
|
|
|
|
+```swift
|
|
|
|
|
+enum BackendError: ErrorType {
|
|
|
|
|
+ case Network(error: NSError)
|
|
|
|
|
+ case DataSerialization(reason: String)
|
|
|
|
|
+ case JSONSerialization(error: NSError)
|
|
|
|
|
+ case ObjectSerialization(reason: String)
|
|
|
|
|
+ case XMLSerialization(error: NSError)
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
#### Creating a Custom Response Serializer
|
|
#### Creating a Custom Response Serializer
|
|
|
|
|
|
|
|
Alamofire provides built-in response serialization for strings, JSON, and property lists, but others can be added in extensions on `Alamofire.Request`.
|
|
Alamofire provides built-in response serialization for strings, JSON, and property lists, but others can be added in extensions on `Alamofire.Request`.
|
|
@@ -721,26 +735,24 @@ For example, here's how a response handler using [Ono](https://github.com/mattt/
|
|
|
|
|
|
|
|
```swift
|
|
```swift
|
|
|
extension Request {
|
|
extension Request {
|
|
|
- public static func XMLResponseSerializer() -> ResponseSerializer<ONOXMLDocument, NSError> {
|
|
|
|
|
|
|
+ public static func XMLResponseSerializer() -> ResponseSerializer<ONOXMLDocument, BackendError> {
|
|
|
return ResponseSerializer { request, response, data, error in
|
|
return ResponseSerializer { request, response, data, error in
|
|
|
- guard error == nil else { return .Failure(error!) }
|
|
|
|
|
|
|
+ guard error == nil else { return .Failure(.Network(error: error!)) }
|
|
|
|
|
|
|
|
guard let validData = data else {
|
|
guard let validData = data else {
|
|
|
- let failureReason = "Data could not be serialized. Input data was nil."
|
|
|
|
|
- let error = Error.errorWithCode(.DataSerializationFailed, failureReason: failureReason)
|
|
|
|
|
- return .Failure(error)
|
|
|
|
|
|
|
+ return .Failure(.DataSerialization(reason: "Data could not be serialized. Input data was nil."))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
do {
|
|
|
let XML = try ONOXMLDocument(data: validData)
|
|
let XML = try ONOXMLDocument(data: validData)
|
|
|
return .Success(XML)
|
|
return .Success(XML)
|
|
|
} catch {
|
|
} catch {
|
|
|
- return .Failure(error as NSError)
|
|
|
|
|
|
|
+ return .Failure(.XMLSerialization(error: error as NSError))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public func responseXMLDocument(completionHandler: Response<ONOXMLDocument, NSError> -> Void) -> Self {
|
|
|
|
|
|
|
+ public func responseXMLDocument(completionHandler: Response<ONOXMLDocument, BackendError> -> Void) -> Self {
|
|
|
return response(responseSerializer: Request.XMLResponseSerializer(), completionHandler: completionHandler)
|
|
return response(responseSerializer: Request.XMLResponseSerializer(), completionHandler: completionHandler)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -756,9 +768,9 @@ public protocol ResponseObjectSerializable {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
extension Request {
|
|
extension Request {
|
|
|
- public func responseObject<T: ResponseObjectSerializable>(completionHandler: Response<T, NSError> -> Void) -> Self {
|
|
|
|
|
- let responseSerializer = ResponseSerializer<T, NSError> { request, response, data, error in
|
|
|
|
|
- guard error == nil else { return .Failure(error!) }
|
|
|
|
|
|
|
+ public func responseObject<T: ResponseObjectSerializable>(completionHandler: Response<T, BackendError> -> Void) -> Self {
|
|
|
|
|
+ let responseSerializer = ResponseSerializer<T, BackendError> { request, response, data, error in
|
|
|
|
|
+ guard error == nil else { return .Failure(.Network(error: error!)) }
|
|
|
|
|
|
|
|
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
|
|
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
|
|
|
let result = JSONResponseSerializer.serializeResponse(request, response, data, error)
|
|
let result = JSONResponseSerializer.serializeResponse(request, response, data, error)
|
|
@@ -771,12 +783,10 @@ extension Request {
|
|
|
{
|
|
{
|
|
|
return .Success(responseObject)
|
|
return .Success(responseObject)
|
|
|
} else {
|
|
} else {
|
|
|
- let failureReason = "JSON could not be serialized into response object: \(value)"
|
|
|
|
|
- let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
|
|
|
|
|
- return .Failure(error)
|
|
|
|
|
|
|
+ return .Failure(.ObjectSerialization(reason: "JSON could not be serialized into response object: \(value)"))
|
|
|
}
|
|
}
|
|
|
case .Failure(let error):
|
|
case .Failure(let error):
|
|
|
- return .Failure(error)
|
|
|
|
|
|
|
+ return .Failure(.JSONSerialization(error: error))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -799,7 +809,7 @@ final class User: ResponseObjectSerializable {
|
|
|
|
|
|
|
|
```swift
|
|
```swift
|
|
|
Alamofire.request(.GET, "https://example.com/users/mattt")
|
|
Alamofire.request(.GET, "https://example.com/users/mattt")
|
|
|
- .responseObject { (response: Response<User, NSError>) in
|
|
|
|
|
|
|
+ .responseObject { (response: Response<User, BackendError>) in
|
|
|
debugPrint(response)
|
|
debugPrint(response)
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
@@ -812,9 +822,9 @@ public protocol ResponseCollectionSerializable {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
extension Alamofire.Request {
|
|
extension Alamofire.Request {
|
|
|
- public func responseCollection<T: ResponseCollectionSerializable>(completionHandler: Response<[T], NSError> -> Void) -> Self {
|
|
|
|
|
- let responseSerializer = ResponseSerializer<[T], NSError> { request, response, data, error in
|
|
|
|
|
- guard error == nil else { return .Failure(error!) }
|
|
|
|
|
|
|
+ public func responseCollection<T: ResponseCollectionSerializable>(completionHandler: Response<[T], BackendError> -> Void) -> Self {
|
|
|
|
|
+ let responseSerializer = ResponseSerializer<[T], BackendError> { request, response, data, error in
|
|
|
|
|
+ guard error == nil else { return .Failure(.Network(error: error!)) }
|
|
|
|
|
|
|
|
let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
|
|
let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
|
|
|
let result = JSONSerializer.serializeResponse(request, response, data, error)
|
|
let result = JSONSerializer.serializeResponse(request, response, data, error)
|
|
@@ -824,12 +834,10 @@ extension Alamofire.Request {
|
|
|
if let response = response {
|
|
if let response = response {
|
|
|
return .Success(T.collection(response: response, representation: value))
|
|
return .Success(T.collection(response: response, representation: value))
|
|
|
} else {
|
|
} else {
|
|
|
- let failureReason = "Response collection could not be serialized due to nil response"
|
|
|
|
|
- let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
|
|
|
|
|
- return .Failure(error)
|
|
|
|
|
|
|
+ return .Failure(. ObjectSerialization(reason: "Response collection could not be serialized due to nil response"))
|
|
|
}
|
|
}
|
|
|
case .Failure(let error):
|
|
case .Failure(let error):
|
|
|
- return .Failure(error)
|
|
|
|
|
|
|
+ return .Failure(.JSONSerialization(error: error))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -866,7 +874,7 @@ final class User: ResponseObjectSerializable, ResponseCollectionSerializable {
|
|
|
|
|
|
|
|
```swift
|
|
```swift
|
|
|
Alamofire.request(.GET, "http://example.com/users")
|
|
Alamofire.request(.GET, "http://example.com/users")
|
|
|
- .responseCollection { (response: Response<[User], NSError>) in
|
|
|
|
|
|
|
+ .responseCollection { (response: Response<[User], BackendError>) in
|
|
|
debugPrint(response)
|
|
debugPrint(response)
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|