How to elegantly handle errors in methods using NSURLSessionTask with closure?

I often have code like this when I have a class that handles communication with the REST API, with many methods inside that use NSURLSession tasks with closure as callbacks. I also give some of these callback closure methods so that I can bind different API calls one by one. I often call these methods from the View controller, for example, as an action after clicking a button or in viewDidLoad.

Take an example class that talks to the imaginary API with one method that sends a POST request to register a new user with the API:

class ApiConnection {
    var session: NSURLSession!

    init() {
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        config.URLCache = NSURLCache.sharedURLCache()
        self.session = NSURLSession(configuration: config)
    }


    func registerNewUser(user user: String, password: String, callback: (() -> Void)? ) {
        let data = ["email": user, "password": password]
        let url = NSURL(string: "https://backend.myapp.com/auth/register/")
        let request = NSMutableURLRequest(URL: url!)
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
        try! request.HTTPBody = NSJSONSerialization.dataWithJSONObject(data, options: NSJSONWritingOptions())

        let task = session.dataTaskWithRequest(request) {
            data, response, error in

            if (error != nil) {
                print("TODO do the right thing here for error: \(error!.localizedDescription)")
                return
            }

            if let httpResponse = response as? NSHTTPURLResponse {

                do {
                    let result = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions()) as? NSDictionary

                    if httpResponse.statusCode == 201 {

                        print("registration went successfully")
                        callback?()

                    } else {

                        print("registration went wrong, not registered new user: \(result)")

                    }



                }
                catch {
                    print("TODO something went wrong decoding the JSON response")
                }
            }


        }
        task.resume()
    }

}

Now I can, for example, in the view controller call this method with something like this:

let myAPI = ApiConnection()
myAPI.registerNewUser(user: "email@foo.bar", password: "testing") {
    // continue here, probably doing the next call
    print("user is registered")
}

, ( "TODO" , - . , , .

, , , if error != nil , .

, do-try-catch : , , - catch , - , , APIConnection. , , , , , , , .

? APIConnection , ? Plaese, .

+4
1

, promises. , , : get_server_respose | parse_json | execute_callback. / . , .

promises async , , .

promise -d :

let task =  session.dataTaskWithRequest(request)
task.promisify.then({response, data in        
    guard let httpResponse = response as? NSHTTPURLResponse else {
       return failedPromise(Error(...)}
    }
    guard response.statusCode == 201 else {
       return failedPromise(Error(...)}
    }
    return jsonParsePromise(data);
}).then({ parsedDict in
    print("Registration went successfully")
    callback?()
}).then(nil, { error in
    print("An error occured: \(error)")
})
task.resume()

, , json- .

P.S. registerNewUser:

func registerNewUser(user user: String, password: String) -> Promise {
    //... task setup
    return task.promisify.then({response, data in        
        guard let httpResponse = response as? NSHTTPURLResponse else {
           return failedPromise(Error(...)}
        }
        guard response.statusCode == 201 else {
           return failedPromise(Error(...)}
        }
        return jsonParsePromise(data);
    })
    task.resume()
}

:

registerNewUser(usernameTextfield.text, passwordTextfied.text).then({user in
    print("Registration succeeded with user \(user)")
}, {error in
    print("Registration failed with error \(error)")
})
+3

Source: https://habr.com/ru/post/1622106/


All Articles