skip to Main Content

I’m new in iOS development, so maybe I’m thinking in the wrong way. I coded a view model with a function that calls an API, and everything works fine.

class SearchCityViewModel : ViewModelProtocol {
//OBSERVABLES
var cities = PublishSubject<[City]>()
var networkError = PublishSubject<Void>()
var generalError = PublishSubject<Void>()

init(){
    print("Init SearchCityViewModel")
    reinit()
}

func reinit(){}

func searchCity(stringToSearch: String){
    async {
        do {
            if stringToSearch.count>=2 {
                let cities = try await(api.getCities(cityToSearch: stringToSearch)).payload!
                self.cities.onNext(cities)
            }
            else {
                self.cities.onNext([])
            }
        }
        catch {
            self.generalError.onNext(Void())
        }
    }
}

Now I want to handle errors. In the catch block I want to distinguish all the errors I want to handle gracefully, and for the other ones I just want to emit a general error. To do that, firstly I need to know which error is thrown when the situation I want to handle occurs. I usually do this with the debugger. For instance, I disable the internet connection, and i create a breakpoint inside the catch block. The idea is to check which error is thrown when the internet connection is disabled, in order to create a catch block for that kind of error.

Image of the debugger

I’m struggling because with the debugger I only see that is an AFError instance, but it’s not telling me nothing more that can help me to catch it.

What is wrong with my workflow? Do I really need to read all the docs every time? For each library I use?

Thank you!

2

Answers


  1. Chosen as BEST ANSWER

    I found the way. What I was missing is casting the error as NSError. In this way, with the debugger is possible to see the domain and the code of the error. In the case of Alamofire, the real error is wrapped, and it's accessible through the underlyingError attribute. Once I had the domain and the code of the error, I wrote the following code:

    class SearchCityViewModel : ViewModelProtocol {
        //OBSERVABLES
        var cities = PublishSubject<[City]>()
        var networkError = PublishSubject<Void>()
        var generalError = PublishSubject<Void>()
    
        init(){
            print("Init SearchCityViewModel")
            reinit()
        }
    
        func reinit(){}
    
        func searchCity(stringToSearch: String){
            async {
                do {
                    if stringToSearch.count>=2 {
                        let cities = try await(api.getCities(cityToSearch: stringToSearch)).payload!
                        self.cities.onNext(cities)
                    }
                    else {
                        self.cities.onNext([])
                    }
                }
                catch {
                    if let afError = asAFError, let underlyingError = afError.underlyingError as NSError?, underlyingError.domain == NSURLErrorDomain, underlyingError.code == NSURLErrorNotConnectedToInternet || underlyingError.code == NSURLErrorTimedOut {
                        self.networkError.onNext(Void())
                    }
                    else {
                        self.generalError.onNext(Void())
                    }
                }
            }
    }
    

  2. Perhaps you can read the articles and then you will know how to do it better, you can use the framework -oslog instead of using print function.
    debugging your logging info

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search