Swift: инициализация данных модели из сетевого запроса [weatherApp] - PullRequest
0 голосов
/ 12 ноября 2019

Я работаю с WeatherApp в Swift, он запрашивает некоторые данные с openweather.org, но у меня проблема с переносом данных в данные модели

Модель данных Class

import Foundation

class CurrentWeather {
    let temperature: Int?
    let tempMin: Int?
    let tempMax: Int?
    let location: String?

    struct WeatherKeys {
        static let temperature = "temp"
        static let tempMin = "temp_min"
        static let tempMax = "temp_max"
        static let location = "name"
    }

    init(weatherDictionary: [String: Any]) {
        temperature = weatherDictionary[WeatherKeys.temperature] as? Int
        tempMax = weatherDictionary[WeatherKeys.tempMax] as? Int
        tempMin = weatherDictionary[WeatherKeys.tempMin] as? Int
        location = weatherDictionary[WeatherKeys.location] as? String

    }
}

Сетевой запрос Class

import Foundation
import Alamofire

class WeatherService {

    let APIKey = "c70ff4cc260c1075bbfb6849caa1ad29"
    let weatherBaseURL = "http://api.openweathermap.org/data/2.5/weather?"

    func getCurrentWeather(latitude: Double, longitude: Double, completion: @escaping (CurrentWeather?) -> Void) {
        if let weatherURL = URL(string: "\(weatherBaseURL)lat=\(latitude)&lon=\(longitude)&appid=\(APIKey)") {
            Alamofire.request(weatherURL).responseJSON(completionHandler: { (response) in
                if let jsonDictionary = response.result.value as? [String: Any] {
                    if let currentWeatherDictionary = jsonDictionary["main"] as? [String: Any] {

                        //Print to show the data from the URL

                         print(currentWeatherDictionary)

                        //Initialize model data with currentWeatherDictionary(NOT WORKING)
                        let currentWeather = CurrentWeather(weatherDictionary: currentWeatherDictionary)
                        completion(currentWeather)
                    } else {
                        completion(nil)
                    }
                }

            })
        }
    }

}

результат currentWeatherDictionary: ["temp": 297.73, "temp_min": 294.15, "temp_max": 301.48, "влажность": 33, "давление ": 1017]

Я хочу использовать модель данных, чтобы присвоить ее значение соответствующей метке в viewController. На данный момент она не показывает мне никакого значения в TemperatureLabel, просто" - "


    let coordinate: (lat: Double, long: Double) = (37.8267, -122.4233)
    var weatherService = WeatherService()

    override func viewDidLoad() {
        super.viewDidLoad()
        weatherService.getCurrentWeather(latitude: coordinate.lat, longitude: coordinate.long) { (currentWeather) in
            if let currentWeather = currentWeather {
                DispatchQueue.main.async {
                    if let temperature = currentWeather.temperature {
                        self.temperatureLabel.text = "\(temperature)"
                    } else {
                        self.temperatureLabel.text = "-"
                    }
                }
            }
        }        
    }

1 Ответ

0 голосов
/ 12 ноября 2019

Все данные о температуре openweathermap: Double, а не Int.

И в словаре main нет ключа location

Гораздо проще декодироватьданные с Decodable

struct WeatherData : Decodable {
    let main : CurrentWeather
}

struct CurrentWeather : Decodable {
    let temp, tempMin, tempMax : Double
    let pressure, humidity : Int
}

class WeatherService {

    let APIKey = "c70ff4cc260c1075bbfb6849caa1ad29"
    let weatherBaseURL = "http://api.openweathermap.org/data/2.5/weather?"

    func getCurrentWeather(latitude: Double, longitude: Double, completion: @escaping (CurrentWeather?) -> Void) {
        if let weatherURL = URL(string: "\(weatherBaseURL)lat=\(latitude)&lon=\(longitude)&appid=\(APIKey)") {
            Alamofire.request(weatherURL).responseData(completionHandler: { (response) in
                switch response.result {
                case .success(let data):
                  let decoder = JSONDecoder()
                  decoder.keyDecodingStrategy = .convertFromSnakeCase
                  let result = try decoder.decode(WeatherData.self, from: data!)
                  completion(result.main)

                case .failure(let error): 
                  print(error)
                  completion(nil)
                }
            })
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...