Alamofire 4.0 error from server - ios

Hi I just migrated to alamofire 4 and I just want to send the error coming from the server, I found a couple ways but I just want to make sure that this is the correct way, here is my custom responseobject class
public protocol ResponseObject {
init?(response: HTTPURLResponse, representation: Any)
}
enum BackendError: Error {
case network(error: Error)
case dataSerialization(error: Error)
case jsonSerialization(error: Error)
case xmlSerialization(error: Error)
case objectSerialization(reason: String)
}
extension DataRequest {
public typealias Validation = (URLRequest?, HTTPURLResponse, Data?) -> ValidationResult
func responseObject<T: ResponseObject>(
queue: DispatchQueue? = nil,
completionHandler: #escaping (DataResponse<T>) -> Void)
-> Self
{
let responseSerializer = DataResponseSerializer<T> { request, response, data, error in
guard error == nil else {
let jsonResponseSerializer = DataRequest.jsonResponseSerializer(options: .allowFragments)
let result = jsonResponseSerializer.serializeResponse(request, response, data, nil)
debugPrint(result)
return .failure(BackendError.network(error: error!))
}
let jsonResponseSerializer = DataRequest.jsonResponseSerializer(options: .allowFragments)
let result = jsonResponseSerializer.serializeResponse(request, response, data, nil)
guard case let .success(jsonObject) = result else {
return .failure(BackendError.jsonSerialization(error: result.error!))
}
guard let response = response, let responseObject = T(response: response, representation: jsonObject) else {
return .failure(BackendError.objectSerialization(reason: "JSON could not be serialized: \(jsonObject)"))
}
return .success(responseObject)
}
return response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
}
}
I add a debugprint so see the error from the server and I see it but do I have to serialize de data again inside the error?? and how can I pass the message to my custom error?

Related

In retrieving JSON data, whats the point of having a completion block return Void?

So we have this function that retrieves JSON data and presents it in its completion block, what I'm trying to understand is why use the signature: ((Data) -> Void) instead of just (Data), is the void really necessary? Here is the function:
typealias JSONData = ((Data) -> Void)
func getJSONData(type: String, urlExtension: String, completion: #escaping JSONData) {
let request = URLRequest(url: URL(string:"\(baseURL)\(type)/\(urlExtension)?api_key=\(apiKey)&region=US&append_to_response=videos,images,releases")! )
let dataTask = session.dataTask(with: request, completionHandler: { (data, response, error) in
if error == nil {
if let httpResponse = response as? HTTPURLResponse {
switch (httpResponse.statusCode) {
case 200:
if let data = data {
completion(data)
}
default:
print(httpResponse.statusCode)
}
}
} else {
DispatchQueue.main.async {
if let error = error {
print("Error: \(error.localizedDescription)") }
return
}
}
})
dataTask.resume()
}
Swift syntax dictates that you must declare closures with a return type after the ->.
You have two options:
typealias JSONData = (Data) -> Void
typealias JSONData = (Data) -> ()
I see Apple using #1 most frequently.

error in return response 'cannot call value of non-function type 'NSHTTPURLResponse?' with Swift 3

I read answer from other questions also but not able to solve:
I tried with following way but getting same error at the line of
return response(responseSerializer: responseSerializer,completionHandler: completionHandler)
please help us in how you add #escaping in following method.
public func JSONResponseObject<T: ResponseObjectSerializable>(_ completionHandler: #escaping (DataResponse<T>) -> Void) -> Self {
let responseSerializer = DataResponseSerializer<T> { request, response, data, error in
guard error == nil else { return .failure(error!) }
let jsonResponseSerializer = DataRequest.jsonResponseSerializer(options: .allowFragments)
let result = jsonResponseSerializer.serializeResponse(request, response, data, nil)
print("result: \(result.value)")
switch result {
case .success(let value):
let json = JSON(value)
print("JSON: \(json)")
if let
response = response,
let responseObject = T(response: response, representation: value as AnyObject)
{
return .success(responseObject)
} else {
let error = Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(error: -6006 as! Error)
return .failure(error as! Error)
}
case .failure(let error):
let json = JSON(error)
print("JSON: \(json)")
return .failure(error)
}
}
return response(responseSerializer: responseSerializer,completionHandler: completionHandler)
}
I solved now in following way
I set extension DataRequest { } instead in extension Request { }

Alamofire4 trouble with JSONResponseSerializer & HTTPURLResponse Swift 3.0

Since I updated Alamofire I get the errors: Type Request has no member JSONResponseSerializer and cannot call value of non-function type HTTPURLResponse
I have already switched Response to DataResponse but I still get the error.
Code:
extension Alamofire.Request {
func responseUserEventsArray(_ completionHandler: #escaping (DataResponse<UserEventsWrapper>) -> Void) -> Self {
let responseSerializer = DataResponseSerializer<UserEventsWrapper> { request, response, data, error in
guard error == nil else
{
return .failure(error!)
}
guard let responseData = data else {
return .failure(AFError.responseSerializationFailed(reason: .inputDataNil))
}
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .allowFragments)
let result = JSONResponseSerializer.serializeResponse(request, response, responseData, error)
switch result {
case .Success(let value):
let json = JSON(value)
let wrapper = UserEventsWrapper()
wrapper.next = json["eventhistory"]["next_page_url"].stringValue
wrapper.previous = json["eventhistory"]["prev_page_url"].stringValue
wrapper.count = json["eventhistory"]["total"].intValue
var allUserEvents:Array = Array<UserEvents>()
print(json)
let results = json["eventhistory"]["data"]
print(results)
for jsonAds in results
{
print(jsonAds.1)
let adsData = UserEvents(json: jsonAds.1, id: Int(jsonAds.0))
allUserEvents.append(adsData)
}
wrapper.usereventsitems = allUserEvents
return .success(wrapper)
case .Failure(let error):
return .Failure(error)
}
}
return response(responseSerializer: responseSerializer,completionHandler: completionHandler)
}
}
EDITED
Change
Request.JSONResponseSerializer to DataRequest.jsonResponseSerializer
extension Alamofire.Request to extension Alamofire.DataRequest – Mat0
.success and .failure - FranMowinckel

Alamofire Use of undeclared type 'Serializer'

I have updated to XCode 7 beta 6 and Alamofire needed to be updated to beta 3. In doing so, I'm having to update areas of the code that use Alamofire. One area in particular that I'm having difficulty updating is the code which is used to retrieve an image from a specified URL and load it into a UIImageView.
Previously, the extension for Alamofire that handled that was:
extension Alamofire.Request {
class func imageResponseSerializer() -> Serializer {
return { request, response, data in
if data == nil {
return (nil, nil)
}
let image = UIImage(data: data!, scale: UIScreen.mainScreen().scale)
return (image, nil)
}
}
func responseImage(completionHandler: (NSURLRequest, NSHTTPURLResponse?, UIImage?, NSError?) -> Void) -> Self {
return response(serializer: Request.imageResponseSerializer(), completionHandler: { (request, response, image, error) in
completionHandler(request!, response, image as? UIImage, error)
})
}
}
But not that is throwing the error
Use of undeclared type 'Serializer'
I do realize that Alamofire doesn't use Serializer anymore, but does anyone know where I can find some documentation or examples what to do now when retrieving images?
As you can find in the readme the serialization was rewritten.
You shoudl be able to use the method below:
public protocol ResponseObjectSerializable {
init?(response: NSHTTPURLResponse, representation: AnyObject)
}
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!) }
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let result = JSONResponseSerializer.serializeResponse(request, response, data, error)
switch result {
case .Success(let value):
if let
response = response,
responseObject = T(response: response, representation: value)
{
return .Success(responseObject)
} else {
let failureReason = "JSON could not be serialized into response object: \(value)"
let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
return .Failure(error)
}
case .Failure(let error):
return .Failure(error)
}
}
return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
}
}
UIImage serializer for Alamofire, updated for Alamofire 2.0 and Swift 2
Alamofire 2.0 and Swift 2.0

Error serializer for Alamofire

I'm trying to write generic serializers for Alamofire and I'm trying to understand how I can make the generic response serializers determine if there was an error and return a custom error object instead (The server returns an error dictionary in that situation).
Any input would be appreciated!
Here's the example code that I'm currently using:
#objc public protocol ResponseObjectSerializable {
init?(response: NSHTTPURLResponse, representation: AnyObject)
}
extension Alamofire.Request {
public func responseObject<T: ResponseObjectSerializable>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void) -> Self {
let serializer: Serializer = { (request, response, data) in
let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let (JSON: AnyObject?, serializationError) = JSONSerializer(request, response, data)
if response != nil && JSON != nil {
return (T(response: response!, representation: JSON!), nil)
} else {
return (nil, serializationError)
}
}
return response(serializer: serializer, completionHandler: { (request, response, object, error) in
completionHandler(request, response, object, error)
})
}
}

Resources