2017-06-23 7 views
-2

Dies ist mein erstes Projekt, das mit JSON arbeitet. Diese Frage könnte also für andere in der gleichen Situation relevant sein. Ich mache eine Wetter-App mit der DarkSky-API. Bisher habe ich die Daten aus dem Internet angefordert, analysiert und zum Testen in der Konsole ausgedruckt. Leider bekomme ich einfach nichts. Hier ist der relevante Code:Parsen von JSON gibt null zurück, warum?

-> Funktionen in meinem Viewcontroller:

func getWeatherData(latitude: String, longitude: String, time: String) { 

    let basePath = "https://api.darksky.net/forecast/xxxxxxxxxxxxxxxb170/" 
    let url = basePath + "\(latitude),\(longitude)" 
    let request = URLRequest(url: URL(string: url)!) 

    let task = URLSession.shared.dataTask(with: request) { 
     (data:Data?, response:URLResponse?, error:Error?) 
     in 

     if let data = data { 
      do { 
       if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] { 
        let dictionary = json 
        UserDefaults.standard.set(dictionary, forKey: "lastWeatherUpdate") 
       } 
      } catch { 
       print(error.localizedDescription) 

      } 

     } 
    } 


} 

func getCurrentWeather() { 
    getWeatherData(latitude: "37", longitude: "40", time: "40000") 
    let weather = UserDefaults.standard.dictionary(forKey: "lastWeatherUpdate") 

    print(weather?["latitude"]) 
} 

Hat jemand meinen Fehler erkennen? Hier ist, wie DarkSky die Struktur der JSON-Daten spezifiziert:

"latitude": 47.20296790272209, 
    "longitude": -123.41670367098749, 
    "timezone": "America/Los_Angeles", 
    "currently": { 
    "time": 1453402675, 
    "summary": "Rain", 
    "icon": "rain", 
    "nearestStormDistance": 0, 
    "precipIntensity": 0.1685, 
    "precipIntensityError": 0.0067, 
    "precipProbability": 1, 
    "precipType": "rain", 
    "temperature": 48.71, 
    "apparentTemperature": 46.93, 
    "dewPoint": 47.7, 
    "humidity": 0.96, 
    "windSpeed": 4.64, 
    "windGust": 9.86, 
    "windBearing": 186, 
    "visibility": 4.3, 
    "cloudCover": 0.73, 
    "pressure": 1009.7, 
    "ozone": 328.35 

Nun, offenbar das ist nur der wichtige Teil des JSON.

Kann jemand meinen Fehler erkennen?

+0

'data' ist nil oder' json' ist nil? – Krunal

+0

Das liegt daran, dass der Anruf asynchron ist. Außerdem fehlt 'task.resume()' Suchen Sie nach "Swift + Async + Closure", um weitere Informationen und Lösungen zu erhalten. – Larme

+0

Nein, ich drucke einfach nichts aus ... Wo müsste ich task.resume() in diesen Code einfügen? – user8206035

Antwort

0

Hat jemand meinen Fehler entdeckt?

Eigentlich gibt es zwei Fehler:

  • Da die Aufgabe
  • dataTask arbeitet asynchron resumed in den Kommentaren erwähnt sein muss, bedarf es einen Abschluss-Handler etwas zu können, nach dem Aufruf drucken.

Der Code verwendet eine einfache Enumeration mit den dazugehörigen Typen als Rückgabetyp für Bequemlichkeit Gründen.

enum WeatherResult { 
    case success([String:Any]), failure(Error) 
} 

func getWeatherData(latitude: String, longitude: String, time: String, completion: @escaping (WeatherResult)->()) { 

    let basePath = "https://api.darksky.net/forecast/xxxxxxxxxxxxxxxb170/" 
    let urlString = basePath + "\(latitude),\(longitude)" 
    let url = URL(string: urlString)! 

    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 

     if let error = error { 
      completion(.failure(error)) 
      return 
     } 

     do { 
      if let json = try JSONSerialization.jsonObject(with: data!) as? [String:Any] { 
       completion(.success(json)) 
      } else { 
       completion(.failure(NSError(domain: "myDomain", code: 1, userInfo: [NSLocalizedDescriptionKey : "JSON is not a dictionary"]))) 
      } 
     } catch { 
      completion(.failure(error)) 
     } 
    } 

    task.resume() 
} 

func getCurrentWeather() { 
    getWeatherData(latitude: "37", longitude: "40", time: "40000") { result in 
     switch result { 
     case .success(let dictionary): 
      UserDefaults.standard.set(dictionary, forKey: "lastWeatherUpdate") 
      print(dictionary["latitude"]) 
     case .failure(let error): 
      print(error.localizedDescription) 
     } 
    } 
} 
+0

Danke Mann, erste Antwort, die mir tatsächlich geholfen hat! ^^ – user8206035