2016-03-22 13 views
0

zurückzugeben Ich habe ein Framework, das eine API aufruft, die eine JSON zurück zu mir zurückgibt. Das Problem ist, dass ich eine Funktion in meinem SDK habe, die NSURLSession verwendet und DataTaskWithRequest aufruft, um die Daten abzurufen. Das Problem ist, dass meine Funktion den Wert zurückgibt, bevor die Daten ordnungsgemäß abgerufen wurden. Ich habe versucht, Completion Handler mit DataTaskWithRequest und derzeit eine While-Schleife verwenden, um auf die Daten empfangen zu warten. Gibt es eine andere Art und Weise, esDelegierte und Protokolle verwenden, um Daten von dataTaskWithRequest in iOS Swift

-Code

public func getDetails() -> AnyObject { 
    if Reachability.isConnectedToNetwork() 
    { 
     received = false 
     let baseUrl = "API_URL Here" 
     let url = NSURL(string: baseUrl) 
     let request = NSURLRequest(URL: url!) 
     let session = NSURLSession.sharedSession() 

     print("Starting the connection") 
     let task = session.dataTaskWithRequest(request, completionHandler : { 
      (data, response, error) in 

      //Proper JSON Form 

      do 
      { 
       self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) 
      } 
      catch 
      { 
       print("Error") 
       return 
      } 

      self.received = true 

     }) 
     task.resume() 

     print("Going through the loop") 
     while(!received) 
     { 
      print("Searching") 
     } 
     print(JSON) 
      return JSON 
    } 
    else 
    { 

     let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK") 
     alert.show() 
     return 0 

    } 
} 
+0

poste deinen Code ... –

Antwort

0

Ihr Problem ist, dass Sie versuchen, etwas Asynchrones in etwas Synchrones zu verwandeln. Um in Pseudo-Code zusammenfassen, können Sie dies tun: -

let myData = getDetails(blah) 
doSomeAction(myData) 

Die Art und Weise, es zu nähern ist die Fertigstellung Block als Indikator selbst zu verwenden und alles asynchron machen.

getDetailsAsync() { 
    (success, message, json, error) in 
    if success == true { 
     print(json) 

    } 
    else { 
     // Do your alert here 
     print(message) 
     print(error) 
    } 
} 

This Antwort könnte hilfreich sein: Dieser Code wurde

public typealias CompletionHandler = (success: Bool, message: String, json: JSON?, error: NSError?) -> Void 

func getDetailsAsync(completion: CompletionHandler) { 
    if Reachability.isConnectedToNetwork() 
    { 
     received = false 
     let baseUrl = "API_URL Here" 
     let url = NSURL(string: baseUrl) 
     let request = NSURLRequest(URL: url!) 
     let session = NSURLSession.sharedSession() 

     print("Starting the connection") 
     let task = session.dataTaskWithRequest(request, completionHandler : { 
      (data, response, error) in 

      //Proper JSON Form 
      if error != nil { 
       completion(false, "error", nil, error) 
      } 
      else { 
       do 
       { 
        self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) 
        completion(true, "OK", self.JSON, nil) 
       } 
       catch 
       { 
        print("Error") 
        completion(false, "JSON parsing failed", nil, nil) 
       } 
      } 

     }) 
     task.resume() 
    } 
    else { 
     completion(false, "No network", nil, nil) 
    } 
} 

Nennen Sie es, wie nicht getestet.

+0

Vielen Dank! Hat mein Problem gelöst –

0

Ja, verwenden Sie einen anderen Thread zu tun, den Prozess zu überwachen und bekommen sie eine Mitteilung durch das Protokoll zu senden.

newQueue = NSOperationQueue() 

    let operation2 = NSBlockOperation(block: { 


     }) 

    operation2.completionBlock = { 
     print("Operation 2 completed") 
    } 

    let operation1 = NSBlockOperation(block: { 


     }) 

    operation1.completionBlock = { 

     self.newQueue.addOperation(operation2) 
    } 

    operation1.qualityOfService = .UserInitiated 
    newQueue.addOperation(operation1) 
} 

Hier ist eine Gliederung des Codes. Kurz gesagt, starten Sie Ihre Sitzung mit Block 1 und starten Sie Ihre Verifizierung des Downloads mit block2. block1 löst block2 aus, wenn es [fast sofort, wie Sie sagen] abgeschlossen hat, Block 2 jedoch wird nicht ausgelöst, bis die in Block 1 abgeschlossene Datenstruktur heruntergeladen ist.

+0

Kannst du es ein bisschen weiter erklären nicht vertraut mit threading in swift –

+0

Es ist ganz einfach Singh. Alles, was ich hier mache, schreibt Code, der nicht mehr von oben nach unten fließt, sondern op1 zu op2. Daher startet addOperation op1, wenn es abgeschlossen ist, feuert es seinen Completion-Block, der dann operation2 hinzufügt, die ausgeführt wird und dann seinen Completion-Block auslöst. Sie können Ihre Sitzung in Operation 1 starten und deren Abschluss überwachen, wenn Sie wissen, dass sie in Operation 2 ausgeführt wird. – user3069232

+0

Die Servicequalität hier ist eine schnelle 2.0-Funktion, um Ihrem IOS mitzuteilen, welche Priorität der genannte Prozess haben muss. Also würde ich Operation 2 hier so niedrig wie möglich machen, wenn Sie einfach nur eine oder zwei Stufen höher überwachen und bedienen, check out Quality of Service ist NSOperations. – user3069232