2017-06-23 15 views
-2

これはJSONを使った最初のプロジェクトです。この質問は、おそらく同じ状況の他の人に関係する可能性があります。 DarkSky APIを使用して天気アプリを作成しています。これまでは、インターネットからデータを要求して解析し、テストのためにコンソールで印刷しました。残念ながら、私はまったく役に立たない。ここでは、関連するコードは次のとおりです。JSONを解析するとnilが返されます、なぜですか?

- 私の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'はnilですか、または' json'はnilですか? – Krunal

+0

呼び出しが非同期であるためです。また、 'task.resume()'が見つからない。詳細情報と解決策を得るために、 "Swift + Async + Closure"を探す。 – Larme

+0

いいえ、ちょうどnilを出力します...このコードではどこでtask.resume()を追加する必要がありますか? – user8206035

答えて

0

誰かが私の間違いを見つけますか?

は、実際には2つのミスがあります:タスクが非同期的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

    関連する問題