2017-06-23 102 views
-2

这是我的第一个使用JSON的项目,所以这个问题可能与其他人在相同的情况下有关。 我正在使用DarkSky API制作天气应用程序。到目前为止,我正在从互联网上请求数据,解析数据并进行测试,并将其打印在控制台中。不幸的是,我只是得到零。下面是相关的代码:解析JSON返回零,为什么?

- >功能在我的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"]) 
} 

是否有人发现我的错误?下面是DarkSky如何指定JSON数据的结构:

"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 

好了,显然这只是JSON的重要组成部分。

任何人都可以发现我的错误吗?

+0

'data'为零或'json'为零? – Krunal

+0

这是因为呼叫是异步的。它也缺少'task.resume()'寻找“Swift + Async + Closure”以获得更多信息和解决方案。 – Larme

+0

不,我只是打印出零...我在哪里必须在此代码中添加task.resume()? – user8206035

回答

0

有人发现我的错误吗?

其实有两个错误:

  • 正如意见中提到的任务必须是resumed
  • dataTask以异步方式工作,它需要一个完成处理程序能够调用后打印的东西。

代码使用具有相关联的类型的简单枚举作为返回类型方便的原因。

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

谢谢你,第一个回答,实际上帮助我!^^ – user8206035