Search code examples
swiftswiftuialamofirealamofire-request

Get string value of Alamofire AFError error Swift


I'm making a request to my server with AlamoFire, and I have a setup something like this, where "self.error" is a String variable.

                    session.request("https://localhost:3000/my-route", method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
                        switch response.result {
                        case .success(let result):
                              print("nice", result)                         
                            
                        case .failure(let err):
                            self.error = err //self.error is a String state variable
                            print("failure")
                        }
                       }

However, I get the (sensible) error "Cannot assign value of type 'AFError' to type 'String'", because I'm trying to set self.error = err, and err is of type AFError, whereas self.error is a String state variable.

I realize I could just do something like self.error = "There was an error", but I'd like to provide the user with some feedback as to what the error actually was, and I can't seem to find the correct properties (i.e. something like err.stringValue, err.description, etc.) to do so. Seems like there's some source code here https://github.com/Alamofire/Alamofire/blob/master/Source/AFError.swift but I'm not sure how this relates to the string value I'd like to obtain.

Any help here would be much appreciated.


Solution

  • For such cases you can always use String interpolation e.g. self.error = "\(err)", but this is not a good idea because err is not just a string and could contain something like:

    sessionTaskFailed(error: Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server." UserInfo={_kCFStreamErrorCodeKey=61, NSUnderlyingError=0x280e37750 {Error Domain=kCFErrorDomainCFNetwork Code=-1004 "(null)" UserInfo={_kCFStreamErrorCodeKey=61, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <78576E38-D021-4ADC-87D4-1C9D81FF0E3A>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <78576E38-D021-4ADC-87D4-1C9D81FF0E3A>.<1>" ), NSLocalizedDescription=Could not connect to the server., NSErrorFailingURLStringKey=https://localhost:3000/my-route, NSErrorFailingURLKey=https://localhost:3000/my-route, _kCFStreamErrorDomainKey=1})

    Like @Menaim already mentioned, you can use err.localizedDescription, then you could get something like URLSessionTask failed with error: Could not connect to the server.

    Generally, I would not pass the error directly to the user. This depends at your users, but do they really should know what e.g. URLSessionTask is?

    In my opinion you should define error string for user, that every user can understand and you should log err.localizedDescription to the console, so you can know what is happening.

    If your app supports many languages, you can define localizable.strings files and translate the errors.

    If you do this print("failure"), every time you have an error, how can you distinguish the errors?

    My suggestion would be something like:

                    case .failure(let err):
                        self.error = "There was an error connecting to the server"
                        print("Failed to connect to backend: \(err.localizedDescription)")