【问题标题】:String Value and Weather Icon in OpenWeatherMapOpenWeatherMap 中的字符串值和天气图标
【发布时间】:2019-09-14 06:51:34
【问题描述】:

我正在尝试从值中检索 Main 和 Description,但它没有显示在 UILabel 中。所有其他参数都显示得很好。像温度和最高和最低温度风速和风向。如果我的代码是正确的,我也对天气图标有困难,需要一些指导。

import UIKit
import Foundation

class ViewController: UIViewController {
    var timer = Timer()

    struct CurrentLocalWeather: Codable {
        let base: String
        let clouds: Clouds
        let cod: Int
        let coord: Coord
        let dt: Int
        let id: Int
        let main: Main
        let name: String
        let sys: Sys
        let visibility: Int
        let weather: Weather
        let wind: Wind
    }

    struct Clouds: Codable {
        let all: Int
    }

    struct Coord: Codable {
        let lat: Double
        let lon: Double
    }

    struct Main: Codable {
        let humidity: Int
        let pressure: Int
        let temp: Double
        let tempMax: Double
        let tempMin: Double
        private enum CodingKeys: String, CodingKey {
            case humidity, pressure, temp, tempMax = "temp_max", tempMin = "temp_min"
        }
    }

    struct Sys: Codable {
        let country: String
        let id: Int
        let message: Double
        let sunrise: UInt64
        let sunset: UInt64
        let type: Int
    }

    struct Weather: Codable {
        let description: String
        let icon: String
        let id: Int
        let main: String
    }

    struct Wind: Codable {
        let deg: Int
        let speed: Double
    }

    //Variables from Storyboard
    @IBOutlet weak var Temp: UILabel!
    @IBOutlet weak var TempMin: UILabel!
    @IBOutlet weak var TempMax: UILabel!
    @IBOutlet weak var WindSpeed: UILabel!
    @IBOutlet weak var Direction: UILabel!
    @IBOutlet weak var Humidity: UILabel!
    @IBOutlet weak var MainDesc: UILabel!
    @IBOutlet weak var Description: UILabel!
    @IBOutlet weak var City: UILabel!
    @IBOutlet weak var SunRise: UILabel!
    @IBOutlet weak var SunSet: UILabel!
    @IBOutlet weak var Icon: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Define URL for Weather Data
        URLSession.shared.dataTask(with: URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=51.05011&lon=-114.08529&appid=<APPID_REMOVED_FOR_POSTING_PURPOSE>&units=metric")!) { data, response, error in
            if let error = error {
                print("Error:\n\(error)")
            } else {
                do {
                    let JSon = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]

                    if let Temp1 = JSon["weather"]as? NSDictionary {
                        DispatchQueue.main.async {
                            self.Description.text = Temp1["description"] as? String
                            self.MainDesc.text = Temp1["main"] as? String
                        let Ico = (Temp1["icon"] as? String)!
                            let Icon = UIImageView()
                            let urlStr = NSURL(string:"http://openweathermap.org/img/w/\(Ico).png")
                            let urlData = NSData(contentsOf: urlStr! as URL)
                            if urlData == nil {
                                Icon.image = UIImage(data: urlData! as Data)
                            }
                        }
                    }
} catch let jsonError as NSError {
                    print("JSON error:\n\(jsonError.description)")
                }
            }
            }.resume()
}

这是查询的结果:

{"coord":{"lon":-114.09,"lat":51.05},"weather":[{"id":802,"main":"Clouds","description":"散乱的云","icon":"03d"}],"base":"stations","main":{"temp":10.9,"pressure":1014,"湿度":32,"temp_min":8.89," temp_max":13.33},"visibility":56326,"wind":{"speed":11.3,"deg":20},"clouds":{"all":40},"dt":1556142366,"sys ":{"type":1,"id":989,"message":0.0068,"country":"CA","sunrise":1556108578,"sunset":1556160342},"id":5913490,"name ":"卡尔加里","鳕鱼":200}

【问题讨论】:

  • 如果你要使用JSONSerialization,为什么一切都是可编码的?事实上,您不使用您发布的任何结构。不要在 Swift 中使用 NSDictionaryNSArrayNSDataNSURL。使用正确的 Swift 类/结构。
  • 并且以小写字母开头的变量、函数和案例名称是标准的。类、结构和枚举名称以大写开头。

标签: json swift nsjsonserialization openweathermap


【解决方案1】:

通过进行以下更改,我能够解决字符串值未显示的问题。

Import UIKit
import Foundation

class ViewController: UIViewController {
    var timer = Timer()


    //Variables from Storyboard
    @IBOutlet weak var Temp: UILabel!
    @IBOutlet weak var TempMin: UILabel!
    @IBOutlet weak var TempMax: UILabel!
    @IBOutlet weak var WindSpeed: UILabel!
    @IBOutlet weak var Direction: UILabel!
    @IBOutlet weak var Humidity: UILabel!
    @IBOutlet weak var MainDesc: UILabel!
    @IBOutlet weak var Description: UILabel!
    @IBOutlet weak var City: UILabel!
    @IBOutlet weak var SunRise: UILabel!
    @IBOutlet weak var SunSet: UILabel!
    @IBOutlet weak var Icon: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Define URL for Weather Data
        URLSession.shared.dataTask(with: URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=51.05011&lon=-114.08529&appid=<APPID_REMOVED_FOR_POSTING_PURPOSE>&units=metric")!) { data, response, error in
            if let error = error {
                print("Error:\n\(error)")
            } else {
                do {
                    let JSon = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]

                    let weatherData = (JSon["weather"]as! NSArray)
                    if let Temp1 = weatherData[0] as? NSDictionary {
                        DispatchQueue.main.async {
                            self.Description.text = Temp1["description"] as? String
                            self.MainDesc.text = Temp1["main"] as? String
                        let Ico = (Temp1["icon"] as? String)!
                            let urlStr = NSURL(string:"http://openweathermap.org/img/w/\(Ico).png")
                            let urlData = NSData(contentsOf: urlStr! as URL)
                            if urlData != nil {
                                self.Icon.image = UIImage(data: urlData! as Data)
                            }
                        }
                    }
} catch let jsonError as NSError {
                    print("JSON error:\n\(jsonError.description)")
                }
            }
            }.resume()
}

我仍然坚持让图标工作,希望我也应该能够发布它。对于尝试使用 Codable 并做对了的人,请分享。

【讨论】:

    【解决方案2】:

    Decodable 非常简单。

    这些是省略了你不想要的键的结构

    struct CurrentLocalWeather: Decodable {
        let main: Main
        let name: String
        let sys: Sys
        let weather: [Weather]
        let wind: Wind
    }
    
    struct Main: Decodable {
        let humidity: Int
        let temp: Double
        let tempMin, tempMax: Double
    }
    
    struct Sys: Decodable {
        let sunrise: Date
        let sunset: Date
    }
    
    struct Weather: Decodable {
        let description: String
        let icon: String
        let main: String
    }
    
    struct Wind: Codable {
        let speed: Double
        let deg: Int
    }
    

    要获得图标,您需要第二个数据任务,同步检索数据是非常糟糕的做法。

    而且不符合区分大小写的命名约定也是非常糟糕的做法。

    class ViewController: UIViewController {
        var timer = Timer()
    
    
        //Variables from Storyboard
        @IBOutlet weak var temp: UILabel!
        @IBOutlet weak var tempMin: UILabel!
        @IBOutlet weak var tempMax: UILabel!
        @IBOutlet weak var windSpeed: UILabel!
        @IBOutlet weak var direction: UILabel!
        @IBOutlet weak var humidity: UILabel!
        @IBOutlet weak var mainDesc: UILabel!
        @IBOutlet weak var desc: UILabel!
        @IBOutlet weak var city: UILabel!
        @IBOutlet weak var sunrise: UILabel!
        @IBOutlet weak var sunset: UILabel!
        @IBOutlet weak var icon: UIImageView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Define URL for Weather Data
            URLSession.shared.dataTask(with: URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=51.05011&lon=-114.08529&appid=<APPID_REMOVED_FOR_POSTING_PURPOSE>&units=metric")!) { data, response, error in
               guard let data = data else {  print("Error:", error!); return }
                do {
                   let decoder = JSONDecoder()
                   decoder.keyDecodingStrategy = .convertFromSnakeCase
                   decoder.dateDecodingStrategy = .secondsSince1970
                   let result = try decoder.decode(CurrentLocalWeather.self, from: data)
                   guard let weather = result.weather.first else { return }
                   DispatchQueue.main.async {
                        self.desc.text = weather.description
                        self.mainDesc.text = weather.main
                        let icon = weather.icon
                        URLSession.shared.dataTask(with: URL(string: "http://openweathermap.org/img/w/\(icon).png")!) { iconData, _ , _ in
                           if let data = iconData {
                              DispatchQueue.main.async {
                                 self.icon.image = UIImage(data: data)
                              }
                           }
                        }.resume()
                   }
                } catch {
                    print("JSON error:", error)
                }
           }.resume()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-25
      • 2016-03-31
      • 2020-02-03
      • 2019-04-07
      • 2021-08-09
      • 2013-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多