2016-04-28 12 views
0

Ich habe einen Webdienst, der die Antwort in json zurückgibt. Ich habe eine separate Klasse für den Datenzugriff in xcode (swift) für iPhone erstellt. Was ich tun möchte, ist eine Funktion in der Datenzugriffsebene, die das Antwortwörterbuch zurückgibt, WENN FETCHING COMPLETE ist. Problem: Wie erfolgt die Rücksendung nur, wenn das Abholen vom Dienst abgeschlossen ist? Ex: Student Tabelle-> eine Studenten- Click> Fetch Daten von Studenten-> Daten zurück, wenn vervollständigtIOS SWIFT - Antwortdaten zurücksenden, wenn der Serviceanruf beendet wird.

Abrufen
func getUser(userID:String)->NSDictionary{ 

     let manager = AFHTTPRequestOperationManager() 
     let parameters = ["uid":userID] 
     manager.POST(urlStudentInfo, parameters: parameters, 
      success: {(operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in 
       print("JSON success: " + responseObject.description) 
       if let responseDic = responseObject as? NSDictionary{ 
        let isUser = responseDic["status"] as! Bool 

        if isUser{ 



        }else{ 

        } 
       } 

      }, 

      failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in 

     }) 

    return response 

} 

Dies ist meine Funktion Struktur. Das Problem wird behoben, nachdem die Rückgabe abgeschlossen ist. Die Rückkehr ist also immer Null.

Hat jemand einen Vorschlag, zurückzukehren, nachdem das Abrufen abgeschlossen ist?

+0

Bitte präzisieren Sie über {CallService} –

+0

aktualisiert den {CallService} Teil –

Antwort

1

Wie sieht Ihr {callService} tatsächlich aus? Hat es einen Beendigungshandler? asynchrone Funktionen wie Webservices können aber im Allgemeinen nicht wie eine normale Funktion betrachtet werden. Sie müssen den Aufruf von ws in einer Funktion starten und dann eine andere Funktion aufrufen, um etwas vom Completion-Handler zu wissen Die Ws-Funktion weiß, dass es abgeschlossen ist. Also kurz gesagt, sollten Sie nicht alles von dieser Funktion zurück versuchen, und stattdessen gibt den Wert aus dem Abschluss-Handler

edit:

Ich würde raten, nicht NSNotifications zu verwenden, sondern Rückrufe delegieren, oder einfach nur Verwenden Sie die Daten im Completion-Handler direkt. Aber was auch immer versucht wird, das zurückgegebene NSDictionary zu verwenden, sollte stattdessen ein Delegat der Klasse sein, in der sich diese Funktion befindet (siehe Tutorials zu Protokollen, wenn Sie nicht wissen, wie es funktioniert), dann können Sie das Wörterbuch durch die Delegatenrückrufe innerhalb des Abschlusses zurückreichen Handler (denken Sie an, wie UITableViews Sie all diese Funktionen machen implementieren, damit es funktioniert, müssen Sie etwas ähnliches für Ihren Webservice Anruf tätigen)

this answer könnte Ihnen helfen, was ich

+0

Ja, ich habe Completion Handler im Dienst. Ich habe das mit NSNotification versucht. SO kann ich die Antwort im Objekt senden. Aber das erfordert die Behandlung von 3 Zuständen (Erfolg-Dienste zugänglich, Fehler-falsche Parameter, Ausfall-Service nicht erreichbar) in 1 Service-Anruf und es gibt viele Dienste, auf die ich zugreife. So ist es nicht möglich, das immer zu verwenden, da ich Listener für viele Anrufe haben muss. –

+0

Getestete Delegate-Methoden, es ist eine gute Lösung. Funktioniert. –

+0

froh zu hören, kann die Antwort als gelöst dann markieren, krank vielleicht die Antwort mit dem Inhalt meines Kommentars aktualisieren – Fonix

0

bedeuten zu verstehen, weil Sie eine asynchrone fordern Methode sollten Sie nicht versuchen, sofort einen Wert zurückzugeben. Stellen Sie stattdessen eine Abschlussverarbeitung bereit, die Sie aufrufen können, wenn die Ergebnisse später zurückgegeben werden.

ich auch AFNetworking 3.x, zumindest unter Verwendung würde vorschlagen, (weil die AFHTTPRequestOperationManager von AFNetworking 2.x NSURLConnection verwendet, die jetzt veraltet ist):

func getUser(userID:String, completionHandler: (NSDictionary?, NSError?) ->()) { 
    let manager = AFHTTPSessionManager() 
    let parameters = ["uid":userID] 
    manager.POST(urlStudentInfo, parameters: parameters, progress: nil, success: { task, responseObject in 
     if let responseDic = responseObject as? NSDictionary, let isUser = responseDic["status"] as? Bool { 
      if isUser{ 
       completionHandler(responseDic, nil) 
      } else { 
       let error = NSError(domain: NSBundle.mainBundle().bundleIdentifier!, code: 1, userInfo: [NSLocalizedDescriptionKey: "status false"]) 
       completionHandler(nil, error) 
      } 
     } else { 
      let error = NSError(domain: NSBundle.mainBundle().bundleIdentifier!, code: 2, userInfo: [NSLocalizedDescriptionKey: "Response not dictionary; or status not found"]) 
      completionHandler(nil, error) 
     } 
    }, failure: { task, error in 
     completionHandler(nil, error) 
    }) 
} 

Und Sie es nennen würde wie folgt:

getUser(userID) { responseDictionary, error in 
    guard responseDictionary != nil && error == nil else { 
     print(error) 
     return 
    } 

    // do something with responseDictionary here 
} 

// but do not try to use responseDictionary here, because the above runs asynchronously 

Oder, noch besser, könnten Sie Alamofire verwenden. Siehe zum Beispiel https://stackoverflow.com/a/27393174/1271826.