简体   繁体   中英

Swift async method and return / completion block

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

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM