Swift:使用Alamofire和模型中的私有变量访问JSON中的字典

时间:2017-05-13 18:45:15

标签: json swift alamofire

我正在解决我的问题,我认为这很简单。我已成功解析了JSON文件中的数据数组,以填充tableview和collectionview,但我仍然试图将字典加载到我的模型中。

{
latitude: 42.8821,
longitude: -8.541,
timezone: "Europe/Madrid",
offset: 2,
currently: {
time: 1494674291,
summary: "Drizzle",
icon: "rain",
precipIntensity: 0.1803,
precipProbability: 0.35,
precipType: "rain",
temperature: 14.73,
apparentTemperature: 14.73,
dewPoint: 11.63,
humidity: 0.82,
windSpeed: 7.15,
windBearing: 204,
cloudCover: 0.67,
pressure: 1013.37,
ozone: 378.18
},

我正在尝试访问“当前”字典以填充我的当前天气模型。

import UIKit
import Alamofire

class CurrentWeather {

    private var _currentTemp: Double!
    private var _date: String!
    private var _weatherType: String!
    private var _highTemp: Double!
    private var _lowTemp: Double!
    private var _weatherDesc: String!


    var currentTemp: Double {
        if _currentTemp == nil {
            _currentTemp = 0.0
        }
        return _currentTemp
    }

    var date: String {
        if _date == nil {
            _date = ""
        }
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .long
        dateFormatter.timeStyle = .none
        let currentDate = dateFormatter.string(from: Date())
        self._date = "Today \(currentDate)"
        return _date
    }

    var weatherType: String {
        if _weatherType == nil {
            _weatherType = ""
        }
        return _weatherType
    }

    var highTemp: Double {
        if _highTemp == nil {
            _highTemp = 0.0
        }
        return _highTemp
    }

    var lowTemp: Double {
        if _lowTemp == nil {
            _lowTemp = 0.0
        }
        return _lowTemp
    }

    var weatherDesc: String {
        if _weatherDesc == nil {
            _weatherDesc = ""
        }
        return _weatherDesc
    }



    init(currentDict: Dictionary<String, AnyObject>) {
        if let temperature = currentDict["temperature"] as? Double {
            self._currentTemp = temperature
        }
        if let icon = currentDict["icon"] as? String {
            self._weatherType = icon
        }
        if let summary = currentDict["summary"] as? String {
            self._weatherDesc = summary
        }
    }

}

我的Alamofire电话的VC代码看起来像这样 -

import UIKit
import Alamofire

class CityWeatherVC: UIViewController, UITableViewDataSource, UITableViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var cityNameLbl: UILabel!
    @IBOutlet weak var currentTempLbl: UILabel!
    @IBOutlet weak var dateLbl: UILabel!
    @IBOutlet weak var currentWeatherImg: UIImageView!
    @IBOutlet weak var currentWeatherType: UILabel!
    @IBOutlet weak var dayHighTempLbl: UILabel!
    @IBOutlet weak var dayLowTempLbl: UILabel!

    var currentWeather: CurrentWeather!
    var currentWeathers = [CurrentWeather]()
    var longRangeForecast: LongRangeForecast!
    var longRangeForecasts = [LongRangeForecast]()
    var hourlyForecast: HourlyForecast!
    var hourlyForecasts = [HourlyForecast]()


    private var _segueData: SegueData!
    var segueData: SegueData {
        get {
            return _segueData
        } set {
            _segueData = newValue
        }
    }



    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self
        collectionView.delegate = self
        collectionView.dataSource = self
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        downloadApiData {
            self.updateCurrentWeatherUI()
        }
    }

    func downloadApiData(completed: DownloadComplete) {

        let currentWeatherUrl = URL(string: "\(darkSkyUrl)\(segueData.latitude),\(segueData.longitude)?units=si")!
        Alamofire.request(currentWeatherUrl).responseJSON { response in
            let result = response.result

            if let dict = result.value as? Dictionary<String, AnyObject> {


                if let currently = dict["currently"] as? Dictionary<String, AnyObject> {

                    let current = CurrentWeather(currentDict: currently)
                    print(current) // ISSUE HERE!

                }


                if let hourly = dict["hourly"] as? Dictionary<String, AnyObject> {
                    if let data = hourly["data"] as? [Dictionary<String, AnyObject>] {

                        for obj in data {
                            let forecast = HourlyForecast(hourlyDict: obj)
                            self.hourlyForecasts.append(forecast)
                        }
                        self.collectionView.reloadData()
                    }

                }
                if let daily = dict["daily"] as? Dictionary<String, AnyObject> {
                    if let data = daily["data"] as? [Dictionary<String, AnyObject>] {

                        for obj in data {
                            let forecast = LongRangeForecast(longWeatherDict: obj)
                            self.longRangeForecasts.append(forecast)
                        }
                        self.longRangeForecasts.remove(at: 0)
                        self.tableView.reloadData()
                    }
                }
            }

        }
        completed()

    }

    // tableView - long range forecast

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "longRangeForecastCell", for: indexPath) as? LongRangeForecastCell {
            let forecast = longRangeForecasts[indexPath.row]
            cell.configureCell(longRangeForecast: forecast)
            return cell

        } else {
            return LongRangeForecastCell()
        }
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return longRangeForecasts.count
    }


    // collectionView - hourly forecast

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hourlyForecastCell", for: indexPath) as? HourlyForecastCell {

            let forecast = hourlyForecasts[indexPath.row]
            cell.configureCell(hourlyForecast: forecast)
            return cell
        } else {
            return HourlyForecastCell()
        }

    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return hourlyForecasts.count

    }


    func updateCurrentWeatherUI() {
        cityNameLbl.text = segueData.cityName
        dateLbl.text = currentWeather.date
        currentTempLbl.text = "\(currentWeather.currentTemp)"
        currentWeatherType.text = currentWeather.weatherDesc
        currentWeatherImg.image = UIImage(named: "\(currentWeather.weatherType)L")
        dayHighTempLbl.text = "\(Int(currentWeather.highTemp))"
        dayLowTempLbl.text = "\(Int(currentWeather.lowTemp))"
    }



    @IBAction func backButtonPressed(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }


}

我有一种感觉,问题与我如何引用它有关,就像我已经处理过的dictionarys数组一样。任何帮助将不胜感激。

更新:收到result.value。我希望将“当前”字典解析到我的模型中,然后使用模型类中的变量来填充我的UI的当前预测部分。我无法粘贴整个结果,因为帖子允许的字符更大。

result.value的第二次更新:

["latitude": 42.660851, "timezone": Europe/Madrid, "daily": {
data =     (
            {
        apparentTemperatureMax = "18.33";
        apparentTemperatureMaxTime = 1495022400;
        apparentTemperatureMin = "10.87";
        apparentTemperatureMinTime = 1495054800;
        cloudCover = "0.87";
        dewPoint = "11.73";
        humidity = "0.88";
        icon = rain;
        moonPhase = "0.7";
        ozone = "325.51";
        precipIntensity = "0.1753";
        precipIntensityMax = "0.3327";
        precipIntensityMaxTime = 1495040400;
        precipProbability = "0.54";
        precipType = rain;
        pressure = "1019.68";

1 个答案:

答案 0 :(得分:0)

首先,让我们为任何类

之外的JSON字典声明一个类型别名
typealias JSONDictionary = [String:Any]

返回的结果(result.value)是一个数组而不是一个字典(参见起始[)。

downloadApiData中获取作为数组中第一项的JSON数据,替换

if let dict = result.value as? Dictionary<String, AnyObject> {

if let array = result.value as? [JSONDictionary],
    let dict = array.first  {

现在将dict传递给初始值设定项(不是currently的值)

let current = CurrentWeather(currentDict: dict)

currentTempweatherTypeweatherDesc的值位于密钥currently的字典中,highTemplowTemp的值均为在字典data中数组daily的第一个字典中。

来自私人支持变量的您的班级CurrentWeather - 未托管

class CurrentWeather {

    let currentTemp: Double
    let weatherType: String
    let highTemp: Double
    let lowTemp: Double
    let weatherDesc: String

    var date: String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .long
        dateFormatter.timeStyle = .none
        let currentDate = dateFormatter.string(from: Date())
        return "Today \(currentDate)"
    }


    init(currentDict: JSONDictionary) {
        if let currently = currentDict["currently"] as? JSONDictionary {
            self.currentTemp = currently["temperature"] as? Double ?? 0.0
            self.weatherType = currently["icon"] as? String ?? "n/a"
            self.weatherDesc = currently["summary"] as? String ?? "n/a"
        } else {
            self.currentTemp =  0.0
            self.weatherType = "n/a"
            self.weatherDesc = "n/a"

        }
        if let daily = currentDict["daily"] as? JSONDictionary,
            let data = daily["data"] as? [JSONDictionary],
            let firstDailyDict = data.first {

            self.highTemp = firstDailyDict["temperatureMax"] as? Double ?? 0.0
            self.lowTemp = firstDailyDict["temperatureMin"] as? Double ?? 0.0
        } else {
            self.highTemp = 0.0
            self.lowTemp = 0.0
        }
    }
}