409 is success in Alamofire? - ios

Strange thing happened to me while implementing networking based on Alamofire. So, my backend can return me 409 and when I get it I want to react properly, so I went for a regular solution:
Alamofire.request(someRequest).responseJSON { response in
switch response.result {
case .Success(let value):
// I get 409 here...
if response.response?.statusCode == 409 {
// ...
}
case .Failure(let error):
// While it should be here...
}
}
Why is it happening? Is it some sort of backend issue or what? I can only thing of one explanation: Request completed, so it's .Success even though you got 409, but this explanation doesn't convince me 😅

HTTP 4.xx class of status codes are intended for situations in which the client seems to have erred, so in normal cases you are to show some kind of error message to the user when it was generated by the server.
In Alamofire world, you can tap into .validate() method if you want response to generate an error if it had an unacceptable status code:
Alamofire.request(someRequest)
.validate(statusCode: 200..<300)
.responseJSON { response in
switch response.result {
case .Success(let value):
...
case .Failure(let error):
// You'll handle HTTP 409 error here...
}
}

Related

Incorrect response from Alamofire?

I am making a request to a server using Alamofire. Here is how i am doing it:
Alamofire.request(url, method: .post, parameters: [:] ,encoding: JSONEncoding.default).responseJSON { response in
print("response=\(response)")
print("Response=:\((response.response?.statusCode)!)")
switch response.result{
case .success :
let passList = AuthenticateSuccess(nibName: "AuthenticateSuccess", bundle: nil)
self.navigationController?.pushViewController(passList, animated: true)
print("connected")
case .failure(let error):
self.showAlertTost("", msg: "Authentication Failed. Authenticate again!", Controller: self)
}
}
This is what prints:
response=SUCCESS: {
message = "Access denied.";
}
Response=:401
connected
I want to know that if 401 is error why is success block being executed? Is failure case in Alamofire handled differently?
As the documentation says:
By default, Alamofire treats any completed request to be successful, regardless of the content of the response. Calling validate() before a response handler causes an error to be generated if the response had an unacceptable status code or MIME type.
E.g.
Alamofire.request(url, method: .post, encoding: JSONEncoding.default)
.validate()
.responseJSON { response in
...
}
With validate, non 2xx responses will now be treated as errors.
response.success depicts that the server has returned the response. Whereas 401 is something that is related to the REST response which your backend system generated. Hence add the check to response code after verifying that you have received the response to provide better information to the end-user.

Handling errors properly in swift

I am trying to learn swift and I have hit a wall... I want to be able to switch the type of error i get back so I can do different things. It works fine in the .success but not in the .failure
exporter.export(progressHandler: { (progress) in
print(progress)
}, completionHandler: { result in
switch result {
case .success(let status):
switch status {
case .completed:
break
default:
break
}
break
case .failure(let error):
// I want to check what the error is
// e.g. the debugger says its "cancelled"
break
}
})
}
Can somebody help me with this?
Thanks
If you just want to see what happened, print the error object's localizedDescription.
print(error.localizedDescription)
If you have a decision to make, cast to NSError and examine the domain and code. That is more reliable though not as user-friendly. Only actual testing will tell you what the possible values are.
let error = error as NSError
if error.domain == ... && error.code == ... {
You can work out the corresponding Swift Error type by looking in the FoundationErrors.h header file. Once you do, you can refine your case structure to filter the error type into its own case:
case .failure(let error as NextLevelSessionExporterError):
// do something
case .failure(let error):
// do something else

Alamofire post request returning "<?xml version="1.0" encoding="utf-8"?>"

Using swift 4, I am doing a post request to a web api. The api has correct JSON data but whenever i call it is returning the following response: 
<?xml version="1.0" encoding="utf-8"?>
My code is:
let urlString = "XXXXXXXXXX/ArticlesByListofIds"
Alamofire.request(urlString, method: .post, parameters: ["ids": "160, 145"],encoding: JSONEncoding.default, headers: nil).responseString { response in
switch response.result {
case .success(let responseString1):
print("the response is: \(responseString1)")
break
case .failure(let error):
print("The error is: \(error)")
}
}
Any idea why is this happening?
I see two things happening. First, the API seems to respond with XML rather than JSON, so probably your request is not what you intended it to be. Second, there seems to be an issue with character encoding. This could be anything; maybe a fault in the server configuration, maybe you are decoding the file incorrectly.

Alamofire - responseSerializationFailed

I really need help with this one. I'm trying to do POST request using Alamofire, but for some reason I'm always getting an error from the title. When I test in POSTMAN, I'm getting okay response. Here is screenshot from POSTMAN, just to get things clearer:
And this is how I'm calling this API in code:
let parameters: Parameters = [
"data": [
"action":"homeimages"
]
]
print("Params: \(parameters)")
Alamofire.request(Constants.API_URL_2, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON {
response in
print("Response: \(response)")
switch response.result {
case .success(let value):
print("Response: \(value)")
break
case .failure(let error):
print(error)
}
}
As far as I know responseserializationfailed error, mostly error with API itself however as you stated, you are getting response in POSTMAN please check below things :
URL(check small/caps well), parameters are correct(check caps and dictionary format as well)
Sometimes we don't need below (optional) parameter , delete this parameter and check
encoding: JSONEncoding.default

Display user friendly message for json serialisation error

Iam working on an ios application which uses Alamofire for networking. Some times i get json serialization error. I need to display some user friendly messsage when this error comes. How can I do this by checking Nserror code.
Any help will be appreciated.
If your response gives serialization error then you can get status isFailure You can display some custom message or can user response.result.error object.
Alamofire.request(url, method: .post, parameters: param, encoding: URLEncoding.httpBody, headers: nil).responseSwiftyJSON { (response) in
if response.result.isSuccess {
// Handle your json
} else {
// display message Something went Wrong
}
}
You can actually check AFError.swift file to get familiar with possible values.
switch responseJson.result.error as? AFError{
case .responseSerializationFailed(let reason)?:
switch reason {
case .inputDataNil:
break
case .inputDataNilOrZeroLength:
break
case .inputFileNil:
break
case .inputFileReadFailed(let at):
break
case .stringSerializationFailed(let encoding):
break
case .jsonSerializationFailed(let error): break
***////// DO What ever you want here //////////////////***
case .propertyListSerializationFailed(let error):
break
}
case .some(.multipartEncodingFailed(let reason)):
break
case .some(.responseValidationFailed(let reason)):
break
case .some(.responseSerializationFailed(let reason)):
break
case .none:
<#code#>
case .some(.invalidURL(let url)):
<#code#>
}

Resources