【问题标题】:How to extract value from JSON object with dictionary [Swift 4]如何使用字典从 JSON 对象中提取值 [Swift 4]
【发布时间】:2020-04-18 09:08:29
【问题描述】:

我正在尝试向 openweathermap.org 的 API 发出异步 API 获取请求。结果应该是这个JSON structure。我特别想得到温度。我被教导通过将 JSON 包装到字典中来使用它。问题是我不知道我可以用什么来指定对象“main”(在 JSON 中)并获取温度。我必须逐个对象迭代吗?这是我到目前为止的代码(旁注:我的应用程序使用 50 mb 的 RAM 是否令人担忧?)

let url = URL(string: stringURL)

    let myQ = DispatchQueue.init(label: "getCityDetails")
    myQ.async {

        let session = URLSession.shared
        let m = session.dataTask(with: url!, completionHandler: {(data, response, error) in
            if let error = error {
                print(error.localizedDescription)
                return
            }

            guard let httpResponse = response as? HTTPURLResponse,
                (200...299).contains(httpResponse.statusCode) else {
                    print("Error with the response, unexpected status code: \(String(describing: response))")
                    return
            }

            do {
                if let d = data{
                    let dictionaryObj =  try JSONSerialization.jsonObject(with: d, options: []) as! NSDictionary
                    print(dictionaryObj)
                }
            }catch{
                print(error.localizedDescription)
            }

        })
        m.resume()

【问题讨论】:

  • 尝试编译您附加到答案的代码:)

标签: json swift


【解决方案1】:

第一点是默认 URLSession 在后台线程中工作,因此您不需要创建调度队列(而且您没有正确使用它)。第二点尝试使用可选数据而不是使用 try/catch。最后你可以尝试将 Swift 5 与 Codable 协议一起使用,以获得更好的代码,简单且安全。

let url = URL(string: "https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=439d4b804bc8187953eb36d2a8c26a02")!
URLSession.shared.dataTask(with: url, completionHandler: {(data, response, error) in
    if let error = error {
        print(error.localizedDescription)
        return
    }

    guard let httpResponse = response as? HTTPURLResponse,
        (200...299).contains(httpResponse.statusCode) else {
            print("Error with the response, unexpected status code: \(String(describing: response))")
            return
    }

    guard let data = data else {
        return
    }

    guard let dictionaryObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
        return
    }
    if let main = dictionaryObj["main"] as? [String: Any], let temperature = main["temp"] {
        DispatchQueue.main.async {
            print("Temperature: \(temperature)")
        }
    }
}).resume()

【讨论】:

  • 有效!谢谢。我意识到在获取 JSON 时不需要使用 Dispatch.main.async,但为什么在打印温度时需要使用它?这么简单的东西,好像没必要用别的线程了
  • 我在打印温度时添加了主线程,因为通常在后台下载和处理数据,并且在主线程中更新 UI。但是,如果您不更新任何 UI,则可以将其删除。
  • 请不要忘记将答案标记为如何解决 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-23
  • 2016-07-22
  • 2016-09-27
  • 1970-01-01
  • 2017-03-29
  • 2019-01-05
  • 1970-01-01
相关资源
最近更新 更多