2016-04-18 9 views
0

Ich versuche, den Benutzer meiner App zu überprüfen, wenn sie die App öffnen. Ich habe einen Begrüßungsbildschirm, der einen Post der Benutzer-E-Mail an den Server sendet und basierend auf der Antwort vom Server wird entweder die Home-Ansicht oder eine E-Mail-Verifizierungsseite geladen.Wie man einen Beitrag zu einem Server macht, auf die Antwort wartet und dann die Ansicht basierend auf der Antwort in Swift ändert?

Das Problem, das ich bekomme, ist, dass, wenn ich den Beitrag mache es scheint es auf einen eigenen Thread, und ich sehe nicht die Antwort, bis die Ansicht bereits geändert und die App hat sich beruhigt.

Ich habe zu verwenden versucht:

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) 

und

 let task = session.dataTaskWithRequest(request) 
     { 
     //more stuff to handle return 
     } 
      task.resume() 

und auch

NSURLConnection.sendSynchronousRequest() 

Das Problem mit der ersten und der dritten Option ist, dass sie veralteten Methoden sind, in Zusätzlich dazu arbeiten sie an ihrem eigenen Thread und erhalten die Antwort nach der if-Anweisung, die die Ansicht ändert schon gelaufen.

Dies ist ein Ausschnitt des Codes verwendet:

 //returns the email of the user 
     let email = self.fileCom.getUserStringField("email") 


     //write the string to post to the server 
     let post = "email=" + email + 
        "&pass=" + self.serverCom.PASSWORD 

     //post the user email to verification script and log result 
     logResponse(self.serverCom.postToServer(self.serverCom.getVerifyEmailScriptURL(), bodyData: post)) 

     //Check the status of verified and email 
     // if(self.fileCom.getUserBoolField("verified")) 
     if(false)//temp 
     { 
      //change view to home view 
      print("\nHomeView\n") 
      showHomeView() 
     } 
     else 
     { 
      //change view to verification view 
      print("\nVerifyView\n") 
      showVerificationView() 
     } 

Die if-Anweisung wird die Ansicht ändern auf der gespeicherten Antwort vom Server an die Benutzer-Datei im Ordner Dokumente basieren.

+0

Sie haben den Blick in den Abschluss-Handler für das Netzanruf zu zeigen. –

Antwort

2

NSURLSession ist der aktuelle unterstützte Weg, hier zu gehen. Mit NSURLSession können Sie entweder eine Klasse erstellen, die ihre Delegate-Methoden zur Deklaration als Delegat implementiert, oder Sie können blocks/closures verwenden. "Blöcke" in C/Obj-C sind eng mit "Closures" in Swift verknüpft. Sie ermöglichen es Ihnen, Funktionen als Variablen zu übergeben. Sie können dazu NSURLSession-dataTaskWithRequest:completionHandler: verwenden.

Der completionHandler-Block wird ausgeführt (in der Delegate-Warteschlange der Sitzung), wenn der Ladevorgang abgeschlossen ist. Von dort aus können Sie auf die Antwort reagieren.

Hier ist ein kurzes Beispiel davon mit (mit einigen Anmerkungen):

let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { 
// Don't put other code before this next line, it is defining the closure we just started with the "{" 
(data, response, error) -> Void in 
    // This is where the closure body begins 
    print(NSThread.isMainThread()) // false (unless you've set the delegate queue to be the main queue) 

    // Example of processing the return value 
    let dataString = NSString.init(data: data!, encoding: NSUTF8StringEncoding) 
    print(dataString) // Okay to do work with this here, but don't do any UI work. 

    // Jump back over to the main queue to do any UI updates 
    // UI updates must always be done on the main queue 
    dispatch_async(dispatch_get_main_queue(), { 
     print(NSThread.isMainThread()) // true (we told it to execute this new block on the main queue) 
     // Execute the code to update your UI (change your view) from here 
     myCoolUIUpdatingMethod(dataString) 
    }); 

    // anything down here could be executed before the dispatch_async block completes 
    // dispatch_sync would block this thread until its block completes 
}); 

// run the task 
task.resume() 

// your program's main thread will not be blocked while the load is in progress 
+0

Also habe ich das zu meinem Code hinzugefügt, und es lief nicht. Ich habe eine print-Anweisung vor und nach der Zeile "let task" und nur die print-Anweisung vor der Ausführung eingefügt. –

+0

Auch ich habe eine task.resume() nach dem letzten ");" um die Aufgabe tatsächlich auszuführen. Aber es ist immer noch, nachdem sich die Ansicht ändert. –

+0

Ich habe gerade meinen Beitrag bearbeitet, um einige Dinge zu klären. Wenn Ihre zweite Druckanweisung war, wo ich kommentierte "Setzen Sie nicht anderen Code vor dieser nächsten Zeile ..." Deshalb wurde es nicht ausgeführt. Das ist effektiv in der Kopfzeile der Schließung, die nicht funktioniert. Wenn Sie einen Ausdruck in "dispatch_async (dispatch_get_main_queue(), {" setzen, wo ich den zweiten Druck habe, um anzuzeigen, dass es der Hauptthread ist, funktioniert das? –