2016-05-26 9 views
0

Ich versuche, Daten aus einer JSON-Datei zu laden, die in meiner Tabellenansicht verwendet werden soll. Trotzdem, wenn ich diese Funktion in Viewdidload aufrufen, enthält das Array, das ich mit Daten füllen möchte, keine Daten und gibt ein leeres Array zurück.Funktion gibt ein leeres Array zurück, anstatt dass es ausgefüllt wird

class CompanyModel { 

func getJSON() -> NSMutableArray() { 

let companyArray: NSMutableArray = NSMutableArray() 

let requestURL: NSURL = NSURL(string: "http://localhost/Companies/JSON.php")! 
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL) 
let session = NSURLSession.sharedSession() 

let task = session.dataTaskWithRequest(urlRequest) { <- does not enter bracket? 
    (data, response, error) -> Void in 

    let httpResponse = response as! NSHTTPURLResponse 
    let statusCode = httpResponse.statusCode 

    if (statusCode == 200) { 
     print("Everyone is fine, file downloaded successfully.") 

     do{ 

      let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments) 

      if let companies = json["companies"] as? [[String: AnyObject]] { 

       for company in companies { 

        if let name = company["name"] as? String, 
         let phoneNumber = company["phone_number"] as? String, 
         let website = company["website"] as? String, 
         let email = company["email"] as? String, 
         let address = company["address"] as? String 

        { 
        let company = CompanyModel() 

         company.name = name 
         company.phoneNumber = phoneNumber 
         company.website = website 
         company.email = email 
         company.address = address 
        } 
        companyArray.addObject(company) 
        print(companyArray) 
       } 
      } 
     } catch { 
      print("Error with Json: \(error)") 
     } 

    } 
    print(companyArray) <- array is populated 
} 
print(companyArray) <- array is empty 
task.resume() 
return companyArray 
} 
} 

Wenn ich eine Debug-Sitzung ausführen, scheint es nicht die Halterung gelangt, wo ich oben erwähnt habe. Stattdessen springt es direkt zur Rückgabe der Funktion, die dann ein leeres Array zurückgibt. Ich glaube, dass keine Daten aus der JSON-Datei abgerufen werden, aber ich bin nicht sicher, warum.

+0

versuchen Sie Ihren JSON drucken, erhalten Sie gültige Daten? Nur um sicher zu gehen. auch, wenn Sie Ihre Json-Daten teilen können, könnte es einfacher zu beantworten. Da "Firmen" möglicherweise nicht der unmittelbare Schlüssel von json sind, könnte es ein Schlüssel eines Schlüssels in json sein. –

+0

Drucken Sie Ihre Json-Daten und überprüfen Sie ihre gültige JSON oder nicht –

Antwort

0

Ihr zweiter Code print(companyArray) wird ausgeführt, bevor der Aufruf mit Daten vom Server zurückgegeben werden kann, da die Anforderung als Hintergrundaufgabe ausgeführt wird. Sie sollten return companyArray in den Erfolgscode schreiben sonst return leeren ein Array im Falle eines Fehlers.

0

In Ihrem Code haben Sie eine Datenaufgabe erstellt, die auf einem anderen Thread ausgeführt wird.

Sie können Ihre Logik ändern, um companyArray nach Abschluss Ihrer Methode zurückzugeben.

print(companyArray) <- and for the love of God, don't put return here! 
} 
print(companyArray) <- this comes before the array is populated 
task.resume() <- And here is where you start the data task 
return companyArray 
0

In Ihrem Code localhost ein Problem zu schaffen und Sie werden response als nil bekommen. Also, es ist besser zu print(data), print(response), print(error) bevor Sie etwas überprüfen. Nur um zu überprüfen, verwenden Sie diese URL: https://httpbin.org/get und später ersetzen Sie bitte Ihre localhost mit IP oder domain in Ihrer URL. Hier

ist der Aktualisierungscode für den oben:

func getWebServiceWithURL(strUrl: String, completionHandler: (NSDictionary?, NSError?) ->()) ->(){ 

    let getTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: strUrl)!) { (responseData, _, error) -> Void in 

     dispatch_async(dispatch_get_main_queue(), {() -> Void in 

      do{ 
       if responseData != nil{ 

        let json = try NSJSONSerialization.JSONObjectWithData(responseData!, options: NSJSONReadingOptions.AllowFragments) as? NSDictionary 

        if let parseJSON = json { 

         // Parsed JSON 
         completionHandler(parseJSON, nil) 
        } 
        else { 
         // Woa, okay the json object was nil, something went worng. Maybe the server isn't running? 
         let jsonStr = NSString(data: responseData!, encoding: NSUTF8StringEncoding) 

         #if DEBUG 
          print("Error could not parse JSON: \(jsonStr)") 
         #endif 
        } 
       }else{ 

        completionHandler(nil, error) 
       } 

      }catch let error as NSError{ 

       print(error.localizedDescription) 
       completionHandler(nil, error) 
      } 
     }) 
    } 

    getTask.resume() 
} 
0

Ein Teil von dem doc of NSURLSession:

Wie die meisten Netzwerk-APIs, die NSURLSession API ist in hohem Maße asynchroner. Es gibt Daten, um Ihre Anwendung in einer von zwei Möglichkeiten, zu den Methoden ab, die Sie anrufen:

To a completion handler block that is called when a transfer finishes successfully or with an error. 

By calling methods on the session’s delegate as data is received and when the transfer is complete. 

und ein Teil aus dem Code:

print(companyArray) <- array is populated 
} 
print(companyArray) <- array is empty 

Sie companyArray in Ihrem Abschluss bevölkerten bekommen Handler, sobald der asynchrone Prozess abgeschlossen ist, und ist außerhalb des Beendigungshandlers leer, weil der Code:

print(companyArray) <- array is empty 

läuft sehr neben dieser Zeile:

let task = session.dataTaskWithRequest(urlRequest) { 

und der Abschluss-Handler noch nicht ausgewertet wird. Verwenden Sie den Beendigungshandler, um tatsächliche Ergebnisse zu erhalten.

0

Ihre return companyArray wird aufgerufen, bevor die Antwort vom Server kommt. Sie sollten also keine Methode mit Rückgabetyp wie Array erstellen!Sie sollten companyArray als öffentliche Variable oder Instanzvariable verwenden und Sie können den Wert aus dem Abschlussblock des Webservice-Aufrufs festlegen und verwenden, wo erforderlich.

Hoffe, das wird helfen :)