Could not get the server error message from Alamofire 3.3.0
I managed to get it to work exactly the way I want is by dropping the status validation and check for the statusCode manually
Alamofire.request(.POST, "\(self.authBaseURL)/signup", parameters: params, headers: headers, encoding: .JSON)
.validate(contentType: ["application/json"])
.responseJSON { response in
if response.response?.statusCode == 200 {
print("Success with JSON: \(response.result.value)")
success(updatedUser)
}
else {
let error = response.result.value as! NSDictionary
let errorMessage = error.objectForKey("message") as! String
print(errorMessage)
failure(errorMessage)
}
}
Accessing the error in Alamofire causes EXC_BAD_ACCESS
So as to continue my previous comment on cnoon's answer : I replaced NSLog()
with println()
and voilà! It works! No more EXC_BAD_ACCESS.
However I don't know why it was a bad access. Is NSLog
somehow so slow or does it not copy the value so it's nil when it finally logs? I have no idea...
EDIT : As I said in my question, it only crashed when the query contained a space. And error.description, which is added as-is to the string, contains the URL String. A space encoded in a URL is "%20" so NSLog
interpreted it as the string formatter %2
, so it went looking for the second optional argument in NSLog
which of course, did not exist! Haha! So to really beautifully fix it I replaced the line with :
NSLog("Error: %@", error)
Now it's a beautiful log, without any hiccups! That's what I get for copying some default code which combines Swift string interpolation with Objective-C string formatting!
How to access alamofire response
It seems that the output is in Json, so i'll need to map it into an object(or class,whatever you call it). If you think its not worth it, you can convert it into an Dictionary, i think it will work as well
Error when grabbing data from API using Alamofire
That happens because you are not using a secure site(https), but a http.
Add this in your info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>example.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
Getting an error when calling the Alamofire in a class function
You need to add Do-Catch Statement
catch – If the throwing method fails and raises an error, the execution will fall into this catch block.
class NetworkLayer{
class func requested(_ request:Router,completion:@escaping(Result<Data,Error>) -> Void){
ProgressHUD.show() //if response comes that loader run
AF.request(request).responseJSON{ (response) in
switch response.result{
case .success(let data):
do{
let getDishesData = data as? [String:Any]
let resp = try JSONSerialization.data(withJSONObject: getDishesData?["data"], options: .prettyPrinted)
completion(.success(response))
}catch{
print(error)
completion(.failure(error))
}
case .failure(let error):
completion(.failure(error))
}
}
}
}
One more suggestion for you here no need to do JSONSerialization because responseJSON gives you direct response(That Alamofire will do JSONSerialization).
Final code
class NetworkLayer{
class func requested(_ request:Router,completion:@escaping(Result<Data,Error>) -> Void){
ProgressHUD.show() //if response comes that loader run
AF.request(request).responseJSON{ (response) in
switch response.result{
case .success(let response):
do{
print(response)
completion(.success(response))
}catch{
print(error)
completion(.failure(error))
}
case .failure(let error):
completion(.failure(error))
}
}
}
}
Alamofire error is always nil, while request fails
Need to add .validate() because of by default, Alamofire treats any completed request to be successful, regardless of the content of the response.
From Alamofire documentation:
Validation
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.Manual Validation
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.validate(statusCode: 200..<300)
.validate(contentType: ["application/json"])
.response { _, _, _, error in
println(error)
}
Automatic Validation
Automatically validates status code within 200...299 range, and that
the Content-Type header of the response matches the Accept header of
the request, if one is provided.Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.validate()
.response { _, _, _, error in
println(error)
}
Related Topics
Why How to Make Same-Type Requirement in Swift with Generics? Is There Any Way
Navigation Bar Items After Push from Swiftui to UIkit
Nstoolbarflexiblespaceitem Is Constraint to Nssplitviewitem in Swift
Naming Convention for Private Properties
Swift Difference Between Double and Float64
How to Find Realm File Location of a MAC App
How to Access The Firebase Topics a User Is Subscribed To
Mapping Swift Combine Future to Another Future
How to Create Generic Convenience Initializer in Swift
Can't Load Images on MAC Screensaver Release Build (It Works on Xcode Debug Build)
How to Check If a Variable Is Nil
Why Does Cabasicanimation Try to Initialize Another Instance of My Custom Calayer
Avaudioconverter with Avaudioconverterinputblock Stutters Audio After Processing
When How to Start Submitting Apps to The iOS App Store Written Using The Swift Programming Language