2016-07-13 12 views
2

Ich versuche, eine Reihe von Funktionen zu schreiben, die die Benutzerinformationen validieren, bevor sie aufgefordert werden, etwas zu bestätigen. (Stellen Sie sich eine Shopping-App vor).Verketten mehrerer Async-Funktionen in Swift

  1. Ich muss zuerst überprüfen, dass der Benutzer eine Karte hinzugefügt hat.
  2. Dann muss ich überprüfen, ob sie ein ausreichendes Gleichgewicht haben.
  3. Dann kann ich sie bitten, die Zahlung zu bestätigen.

kann ich die Asynchron-Methode schreiben die Karte so etwas wie zu überprüfen ...

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) 
} 

Dies kann wie folgt ...

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

Aber ... jetzt ausgeführt werden, davon ausgehend muss ich verschiedene Dinge tun. Wenn der Benutzer eine Karte hat, muss ich weiter fortfahren und prüfen, ob ein ausreichender Kontostand vorhanden ist (auf die gleiche Weise). Wenn der Benutzer keine Karte hat, zeige ich ihm einen Bildschirm an, auf dem er seine Karte hinzufügen kann.

Aber es wird chaotisch ...

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!") 
    } 
} 

Was würde Ich mag stattdessen ist etwas entlang der Linien von diesem ...

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() 

Das sieht viel mehr „swifty“ aber ich bin mir nicht sicher, wie ich so etwas näher kommen könnte.

Gibt es einen Weg?

+1

Sie können etwas wie https://github.com/mxcl/PromiseKit verwenden –

+1

Werfen Sie auch einen Blick auf das reaktive Paradigma (sowohl mit ReactiveCocoa und RXSwift-Bibliothek), es ist nützlich für diese Art von Abstraktionen. Offensichtlich bringt es viel mehr Funktionen auf den Tisch als die, die Sie hier brauchen. –

Antwort

6

Asynchrone Operationen, geordnet und mit Abhängigkeiten? Du beschreibst NSOperation.

Natürlich können Sie Ketten Aufgaben mit GCD:

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

Aber wenn Ihre Operationen sind komplex, z.B. Sie haben Delegierte, die Architektur bricht komplett zusammen. Mit NSOperation können komplexe Vorgänge genau so eingekapselt werden, wie Sie es wünschen.

+0

Insbesondere gibt es ein wundervolles wunderbares Video vom letzten Jahr über fortgeschrittene NSOperation, das dir sagt, wie man diese Art von Sache kohärent macht. – matt

+0

Ah, ich habe das schon mal mit NSOperation gemacht und habe es vergessen. Ich werde es mir noch einmal ansehen. Hatte gehofft, dass es in den Reichen von Swift mit seinen phantastischen Schließungen und was auch immer sein könnte. Werfen wir einen Blick auf die WWDC-Videos. Thansk – Fogmeister

+1

Dies ist die eine: http://asciiwwdc.com/2015/sessions/226 Und es gibt ein unglaublich gutes Beispielcode-Projekt, das damit einhergeht. Das wird dich umhauen. – matt