【问题标题】:Parsing nested JSON in Swift compared with Objective-C与 Objective-C 相比,在 Swift 中解析嵌套 JSON
【发布时间】:2020-05-13 17:52:41
【问题描述】:

我正在尝试在 Swift 中解析一些我之前在 Objective-C 中解析过的 JSON,但遇到了一些困难。

在 Objective-C 中,我能够使用以下方法简单地解析它:

NSError* error;
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSNumber *temp = jsonResults[@"main"][@"temp"];
NSNumber *humidity = jsonResults[@"main"][@"humidity"];

在 Swift 中,到目前为止,当我尝试序列化为字典时,或者当我尝试访问 JSON 中的值时序列化为字符串时,我的代码会出错。

在 Swift 中执行此操作的正确方法是什么。这是我尝试序列化为 Dictionary 的版本,它给出了一个错误

  //assemble url query items
    components.queryItems = queryItems
    let url = components.url
    let task = URLSession.shared.dataTask(with: url!) { //open 2
    [weak self] data, response, error in
    print("heard back from task")
    guard let data = data, error == nil else { return }
    do {
    let jsonResults = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [Dictionary:Any]
    //Gives error Dictionary' requires that 'Value' conform to 'Hashable'
    let main = jsonResults["main"] as Any
    let temp = main[3]
    completion("got here")
    } catch let error as NSError {
    print(error)
    }

这是 JSON 的示例:

{"coord":{"lon":10.73,"lat":59.91},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"base":"stations","main":{"temp":49.62,"feels_like":43.45,"temp_min":48,"temp_max":52,"pressure":987,"humidity":30},"wind":{"speed":1.99,"deg":95,"gust":7},"clouds":{"all":95},"dt":1589387530,"sys":{"type":3,"id":2009047,"country":"NO","sunrise":1589337830,"sunset":1589398989},"timezone":7200,"id":3143242,"name":"Oslo County","cod":200}

【问题讨论】:

标签: ios json swift json-serialization


【解决方案1】:

在swift中你只需要下面的代码:-

型号:

struct Model: Codable {
    let coord: Coord
    let weather: [Weather]
    let base: String
    let main: Main
    let wind: Wind
    let clouds: Clouds
    let dt: Int
    let sys: Sys
    let timezone, id: Int
    let name: String
    let cod: Int
}

struct Clouds: Codable {
    let all: Int
}

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

struct Main: Codable {
    let temp, feelsLike: Double
    let tempMin, tempMax, pressure, humidity: Int

    enum CodingKeys: String, CodingKey {
        case temp
        case feelsLike = "feels_like"
        case tempMin = "temp_min"
        case tempMax = "temp_max"
        case pressure, humidity
    }
}

struct Sys: Codable {
    let type, id: Int
    let country: String
    let sunrise, sunset: Int
}

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

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

解析:

do {
    let model = try JSONDecoder().decode(Model.self, from: data)
} catch {
    print(error.localizedDescription)
}

【讨论】:

  • 我在控制台中得到了一个奇怪的声明没有数据,我认为来自 JSONDecoder().decode
  • decder 是否应该将 json 作为参数(需要额外的步骤将数据序列化为 JSON?
  • @zztop 你需要给 Model 而不是 Main。儿子的名字有点混乱。现在检查我的答案,我已经更新了。
  • 我认为这很接近。但是数据应该是什么类型?我的变量数据实际上是来自 URL 会话的 NSData,我必须将其转换为 JSON,例如:let data: Data // 从网络请求接收,例如 let json = try? JSONSerialization.jsonObject(with: data, options: [])let jsonData = JSON.data(using: .utf8)!让 blogPost: BlogPost = 试试! JSONDecoder().decode(BlogPost.self, from: jsonData)
  • 看起来为了使用 Decodable,参数应该是字符串的形式,使用 utf8 转换为数据,如文档中的此示例所示:让 json = BUNCH OF JSON.data(使用: .utf8)! let decoder = JSONDecoder() let product = try decoder.decode(GroceryProduct.self, from: json) developer.apple.com/documentation/foundation/jsondecoder
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-31
  • 2018-08-06
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
相关资源
最近更新 更多