2016-05-18 7 views
0

Mein Problem tritt auf, wenn ich Daten aus meiner MySQL-Datenbank in ein Klassenobjekt füllen möchte. Ich versuche, ein Array von Objekten zurückzugeben und es gibt nil zurück und dann füllt es sich irgendwie. Wie kann ich es füllen, bevor ich das leere Array zurückschicke?NSURLSession.sharedSession(). DataTaskWithRequest läuft langsam in Funktion

Hier ist mein Code und ein Screenshot von Codeausgabe

import Foundation 

class Research 
{ 
    var mainResearchImageURL:String = "" 
    var userProfileImageURL:String = "" 
    var caption:String = "" 
    var shortDescription:String = "" 

    init(mainResearchImageURL :String, userProfileImageURL:String, caption:String, shortDescription:String) 
    { 

    self.mainResearchImageURL = mainResearchImageURL 
    self.userProfileImageURL = userProfileImageURL 
    self.caption = caption 
    self.shortDescription = shortDescription 
    } 

    class func downloadAllResearches()->[Research] 
    { 
    var researches = [Research]() 
    let urlString = "http://localhost/test/index.php" 
    let request = NSMutableURLRequest(URL: NSURL(string: urlString)!) 
    request.HTTPMethod = "POST" 
    let postString = "action=listresearches" 
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) 
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in 
     if (error == nil) { 

      do { 
       let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray 
       //let dictionary = json!.firstObject as? NSDictionary 

       var counter:Int = 0; 
       for line in json!{ 
        let researchData = line as! NSDictionary 
        let researchLineFromData = Research(mainResearchImageURL: researchData["research_mainImageURL"] as! String, userProfileImageURL: researchData["research_creatorProfileImageURL"] as! String, caption: researchData["research_caption"] as! String, shortDescription: researchData["research_shortDescription"] as! String) 
        researches.append(researchLineFromData) //researches bir dizi ve elemanları Research türünde bir sınıftan oluşuyor. 

        counter += 1 
        print ("counter value \(counter)") 
        print("array count in loop is = \(researches.count)") 
       } 
      }catch let error as NSError{ 
       print(error) 
      } 
     } else { 
      print(error) 
     }}) 
    task.resume() 

    print("array count in return is = \(researches.count)") 
    return researches 
    } 
} 

Und dies ist die Ausgabe:

enter image description here

+0

Das Problem, das Sie haben, ist kein "Problem". Swift tut Ihnen einen Gefallen, indem Sie Webanfragen im Hintergrund ausführen und Ihre Anwendung nicht halten, wenn diese fertig ist. Sie müssen nur entsprechend damit umgehen. Ich würde in Versandgruppen suchen. Sie ermöglichen Ihnen, Code auszuführen, sobald eine Aufgabe abgeschlossen ist. Überprüfen Sie diese Antwort hier: http://stackoverflow.com/questions/35906568/wait-until-swift-for-loop-with-asynchronous-network-requests-finishes-executing/35906703#35906703 –

Antwort

0

dies auf Sie hinzufügen completionHandler (es funktioniert, wenn Sie eine Ansicht aktualisieren)

dispatch_async(dispatch_get_main_queue(), { 
    if (error == nil) { ...... } 
}) 

Hinweis 1:

geben Sie die Aufgabe zurück und verwenden Sie einen Abschlussparam in Ihrer Methode Sie können die Aufgabe abbrechen, wenn sie zu langsam ist.

Beratung 2: Verwenden alamofire und swiftyJson Rahmen

0

Was hier geschehen ist, dass Sie den Wert vor dem Fertig zurückkehren (denken Sie daran, dass der Aufruf asynchron ist), können Sie so etwas wie dies machen:

class func downloadAllResearches(success:([Research])->Void,failure:(String)->Void) 
{ 
    var researches = [Research]() 
    let urlString = "http://localhost/test/index.php" 
    let request = NSMutableURLRequest(URL: NSURL(string: urlString)!) 
    request.HTTPMethod = "POST" 
    let postString = "action=listresearches" 
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) 
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in 
    if (error == nil) { 

     do { 
      let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray 
      //let dictionary = json!.firstObject as? NSDictionary 

      var counter:Int = 0; 
      for line in json!{ 
       let researchData = line as! NSDictionary 
       let researchLineFromData = Research(mainResearchImageURL: researchData["research_mainImageURL"] as! String, userProfileImageURL: researchData["research_creatorProfileImageURL"] as! String, caption: researchData["research_caption"] as! String, shortDescription: researchData["research_shortDescription"] as! String) 
       researches.append(researchLineFromData) //researches bir dizi ve elemanları Research türünde bir sınıftan oluşuyor. 

       counter += 1 
       print ("counter value \(counter)") 
       print("array count in loop is = \(researches.count)") 
      } 
      success(researches) 
     }catch let error as NSError{ 
      print(error) 
      failure("Can be extract from NSERROR") 
     } 
    } else { 
     print(error) 
     failure("Error - Can be extract for NSERROR") 
    }}) 
task.resume() 
diese Fuction Verwendung so etwas wie dieses

}

Und für Anruf:

Research.downloadAllResearches({ (objects:[Research]) -> Void in 
     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      //Do whatever you like with the content 
     }) 
    }) { (failureLiteral:String) -> Void in 

    } 
+0

Hat nicht für mich gearbeitet. Wenn ich versuche, die Funktion wie Sie zu rufen, warnt Xcode mich mit einer roten Flagge und sagt "Expected declaration". –

+0

Können Sie einen Druckbildschirm nehmen? Mmm hast du das letzte} in die Methode (downloadAllResearches) gesteckt, habe ich versehentlich ausgelassen (im Blockcode) –

+0

Habe gearbeitet, danke! –