2

I'm trying to write a series of functions that will validate the user's information before asking them to confirm something. (Imagine a shopping app).

  1. I first have to check that the user has added a card.
  2. Then I have to check that they have sufficient balance.
  3. Then I can ask them to confirm the payment.

I can write the async method to check the card something like ...

func checkHasCard(completion: (Bool) -> ()) {
    // go to the inter webs
    // get the card
    // process data
    let hasCard: Bool = // the user has a card or not.
    completion(hasCard)
}

This can be run like this...

checkHasCard {
    hasCard in
    if hasCard {
        print("YAY!")
    } else {
        print("BOO!")
    }
}

But... now, based off that I have to do various things. If the user does have a card I then need to continue onwards and check there is sufficient balance (in much the same way). If the user does not have a card I present a screen for them to add their card.

But it gets messy...

checkHasCard {
    hasCard in
    if hasCard {
        // check balance
        print("YAY!")
        checkBalance {
            hasBalance in
            if hasBalance {
                // WHAT IS GOING ON?!
                print("")
            } else {
                // ask to top up the account
                print("BOO!")
            }
        }
    } else {
        // ask for card details
        print("BOO!")
    }
}

What I'd like instead is something along the lines of this...

checkHasCard() // if no card then show card details screen
    .checkBalance() // only run if there is a card ... if no balance ask for top up
    .confirmPayment()

This looks much more "swifty" but I'm not sure how to get closer to something like this.

Is there a way?

2
  • 1
    You can use something like github.com/mxcl/PromiseKit Commented Jul 13, 2016 at 14:50
  • 1
    Take also a look to the reactive paradigm (with both ReactiveCocoa and RXSwift library), it is useful for this kind of abstractions. Obviously it brings to the table a lot more functionalities than the one you need here. Commented Jul 13, 2016 at 14:55

1 Answer 1

6

Asynchronous operations, ordered and with dependencies? You're describing NSOperation.

Certainly you can chain tasks using GCD:

DispatchQueue.main.async {
    // do something
    // check something...
    // and then:
    DispatchQueue.main.async {
        // receive info from higher closure
        // and so on
    }
}

But if your operations are complex, e.g. they have delegates, that architecture completely breaks down. NSOperation allows complex operations to be encapsulated in just the way you're after.

Sign up to request clarification or add additional context in comments.

11 Comments

In particular, there is a wonderful wonderful video from last year on advanced NSOperation that tells you how to do this sort of thing coherently.
Ah, I've done this before with NSOperation and had forgotten about it. I'll have another look at it. Was hoping it might be within the realms of Swift with it's fancy closures and whatnot. Will take a look at the WWDC videos. Thansk
This is the one: asciiwwdc.com/2015/sessions/226 And there is an incredibly great code sample project that goes with it. This will totally blow your mind.
Haha, great. Thanks :D
OK, my mind is sufficiently blown and now I wish I could scrap the app and start again with NSOperations from the ground up. HAHA! Actually though, it's not too bad. I can use this new method for this entire system. Thanks :D
|

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.