2016-04-26 6 views
2

In meiner App müssen wir 3 Serveraufrufe tätigen, wenn wir auf die Login-Schaltfläche klicken.Synchrones Abrufen von Daten NSOperationQueue oder NSURLSession

1) will make a server call to get an OAuth token for user credentials 
2) with the token from (1) we will get user privileges 
3) with the token from (1) and with the valid privilege from (2) we will get the data to be displayed on the page after login in a tableview. 

Ich bin verwirrt mit dem Ansatz dafür zu nehmen. Wäre es ein guter Ansatz, Operationsqueue-Abhängigkeiten zu verwenden oder NSURLSession-Tasks zu verwenden?

Nach einem der Stack-Überlauf-Lösungen für diesen - Best practices for making a queue of NSURLSessionTasks, NSURLSession hat keine Logik zur Bestellung von Anfragen wird es nur die completionBlock von nennen, was auch immer zuerst fertig ist, selbst wenn die maximale Anzahl von Verbindungen pro Host auf 1 setzen

Wenn es einen anderen besseren Ansatz gibt lass es mich wissen ..

Antwort

1

können Sie NSURLSession Aufgaben verwenden. Rufen Sie zuerst die erste API-Methode auf, und Sie erhalten eine Antwort im Beendigungshandler (Block). Speichern Sie es jetzt in einer öffentlichen Eigenschaft (wie Sie es erneut verwenden möchten) innerhalb des Complete-Handlers. Rufen Sie die zweite api-Methode von der zweiten api-Methode des Beendigungshandleraufrufs und von der Beendigungsbehandlungsroutine dieser zweiten Methode auf, indem Sie die Antwort übergeben und die öffentliche Eigenschaft verwenden, in der das Objekt der ersten api-Methode gespeichert ist.

Abschluss-Handler oder Blöcke, die nur dann aufgerufen werden, wenn die Antwort angekommen ist. Auf diese Weise können Sie Ihre API-Anrufe verwalten.

Hope this :) helfen

+0

Wird diese Methode ausprobiert oder erraten? weil, das Hinzufügen einer Datatask in einer Datatask gibt mir einen Fehler –

+1

Nein, ich hatte dies in der Vergangenheit verwendet. Ich hatte Daten zu API übergeben, die von anderen API von Vervollständigungshandler kommen. – Lion

+1

Machen Sie drei verschiedene Methoden, um diese drei Operationen durchzuführen. von Methode 1 der Vervollständigungshandleraufrufmethode mit dem Übergeben erforderlicher Daten und von Methode 2 der Vervollständigungshandleraufrufmethode durch Übergeben erforderlicher Daten. – Lion

1

Am Ende des Tages, eine vereinfachte Version des Codes den traditionellen Ansatz des „Abschluss-Handler“ verwendet, kann wie folgt aussehen:

fetchOAuthToken() { (token, error) in 
    if let token = token { 
     fetchPrivileges(token: token) { (privileges, error) in 
      if let privileges = privileges { 
       fetchData(token: token, privileges: privileges) { (data, error) in 
        if let data = data { 
         // ... 
        } 
       } 
      } 
     } 
    } 
} 

Beachten Sie, dass der Code nicht nur Fehlerbehandlung und keine Möglichkeit zum Abbrechen enthält.

Die Abhängigkeiten werden durch die Fortsetzungen - also die Completion-Handler eingerichtet.

Einen anderen Ansatz „Scala-like“ Futures verwendet, wird wie folgt aussehen (mit Promises ist ganz ähnlicher Ansatz):

fetchOAuthToken().flatMap { token in 
    fetchPrivileges(token: token).flatMap { privileges in 
     fetchData(token: token, privileges).map { data in 
      // ... 
     } 
    } 
}.onFailure { error in 
    print("Error: \(error)") 
} 

Die Anweisung erstellt über eine Aufgabe, die aus drei zusammengesetzt ist.

Dieser Ansatz enthält vollständige Fehlerbehandlung, auch wenn es nicht offensichtlich ist. Die Produktionsversion unterscheidet sich nicht wesentlich von diesem oben genannten Snippet - es kann nur ein Löschmittel hinzugefügt werden.

Es gibt einige Bibliotheken von Drittanbietern, die Scala-ähnliche Futures oder Promises implementieren.

Ein Ansatz Hinzufügen Stornierung, kann wie folgt aussehen:

let cr = CancellationRequest() 
fetchOAuthToken(ct: cr.token).flatMap { token in 
    fetchPrivileges(token: token, ct: cr.token).flatMap { privileges in 
     fetchData(token: token, privileges, ct: cr.token).map { data in 
      // ... 
     } 
    } 
}.onFailure { error in 
    print("Error: \(error)") 
} 

Später können Sie die zusammengesetzte Aufgabe aufheben (was auch immer es gerade ausgeführt wird):

cr.cancel() 

Hinweis:

Dieses Problem kann auch mit NSOperations gelöst werden. Es würde jedoch drei Unterklassen von NSOperation und eine oder zwei threadsichere Hilfsklassen erfordern, die verwendet werden, um das Ergebnis von Op1 an den Eingang von Op2 und das Ergebnis von Op2 an den Eingang von Op3 "zu übertragen". Ich würde schätzen, dass dies etwa 500 Zeilen Code - zu viel für eine Antwort auf SO nehmen wird;)

Die "Scala-like" Futures-Ansatz erfordert eine Drittanbieter-Bibliothek. Die Stornierung erfordert eine andere - oder Ihre eigene Implementierung (die nicht so schwierig ist), oder eine Bibliothek, die alles in einem bietet.