1

I'm trying to create an async method in my project that takes some input parameters. If the parameters are correct it will then do some stuff and then call a completion block.

However, if the input parameters are not correct then it won't do the stuff (and so the completion block won't run and I'd have to call it myself).

Anyway, I'm wondering what the best approach would be for this...

I'm thinking I could have the method return a Status enum that includes what is wrong with the input and then also have the completion block.

The problem is that there could also be an error from the completion block. So maybe that should be a different Error type?

Something like this... (Using login as an example).

enum LoginRequestStatus {
    case missingEmail
    case missingPassword
    case requestingLogin
}

And then the error from the completion might be...

enum LoginError: Error {
    case noUserFound
    case invalidPassword
    case success
}

Then the function might look something like this...

func login(withEmail email: String, password: String, completion: (LoginError?) -> ()) -> LoginStatus {
    if email.isEmpty() {
        return LoginStatus.missingEmail
    }
    if password.isEmpty() {
        return LoginStatus.missingPassword
    }

    //make some async request here or something...

    //... if error...
    completion(LoginError.invalidPassword)

    return LoginStatus.requestingLogin
}

Does that make sense? Is that Swifty (I hate that word but it portrays what I mean)? Is there a different way I could approach this altogether?

Thanks

2
  • I think If I got your question correctly, there are two types of error which you want to manage. You can manage it by setting another variable (let say int type) in the completion block without using the return type. like if the error is "LoginRequestStatus" type pass 100 and for other one pass 101. Then in the completion method check if the int value is 100 then it is "LoginRequestStatus" type or else the other one. And manage accordingly. Does that make sense?? Commented Sep 22, 2016 at 11:19
  • Your way is not wrong also, using throws is not wrong also, each way also can be use fine, Alamofire use completion block and some other use throws to handle error, beside, return LoginStatus doesnt seems really needed here, since it always return LoginStatus.requestingLogin, what's the point of calling? Commented Sep 22, 2016 at 11:30

1 Answer 1

2

From my point of view it is possible to use throws to simplify interaction with method. I write small example. With this implementation it is quite easy not to miss error because of the exceptions. And clear response status will show if request is successful.

Throws errors:

enum LoginError: ErrorType {
    case missingEmail
    case missingPassword
}

Response status:

enum LoginRequestStatus {
    case noUserFound
    case invalidPassword
    case success
}

Function implementation:

func login(withEmail email: String, password: String) throws -> LoginRequestStatus {

    guard email.characters.count > 0 else{
        throw LoginError.missingEmail
    }

    guard password.characters.count > 0 else{
        throw LoginError.missingPassword
    }

    // do some request

    return LoginRequestStatus.success
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I'm going to combine the throwing errors with the completion block.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.