可编码:按键解码



>假设我有一个返回此 json 的 API:

{
"dogs": [{"name": "Bella"}, {"name": "Lucy"}], 
"cats": [{"name": "Oscar"}, {"name": "Coco"}]
}

还有一个看起来像这样的模型:

import Foundation
public struct Animal: Codable {
let name: String?
}

现在我想从"dogs"键解码动物数组:

let animals = try JSONDecoder().decode([Animal].self, from: response.data!)

但是,我不知何故必须引用"狗"键。我该怎么做?

首先,您提供的 JSON 不是有效的 JSON。因此,让我们假设您的实际含义是这样的:

{
"dogs": [{"name": "Bella"}, {"name": "Lucy"}],
"cats": [{"name": "Oscar"}, {"name": "Coco"}]
}

那么代码的问题就在于这一行:

let animals = try JSONDecoder().decode([Animal].self, from: response.data!)

您声称 JSON 代表一个动物数组。但事实并非如此。它表示具有键的字典dogscats.所以你只是这么说。

struct Animal: Codable {
let name: String
}
struct Animals: Codable {
let dogs: [Animal]
let cats: [Animal]
}

现在一切都会正常工作:

let animals = try JSONDecoder().decode(Animals.self, from: response.data!)

你们都可以像这样从 JSON 中获取所有值:

let arrayOfResponse = Array(response.data.values)
let clinicalTrial = try JSONDecoder().decode([Animal].self, from: arrayOfResponse!)

如果你以前知道像狗、猫这样的钥匙,你可以这样做

struct Initial: Codable {
let dogs, cats: [Animal]
}
struct Animal: Codable {
let name: String
}
// MARK: Convenience initializers
extension Initial {
init(data: Data) throws {
self = try JSONDecoder().decode(Initial.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
}

// data  is your response data
if let inital = try? Initial.init(data: data) {
let cats = inital.cats
let dogs = inital.dogs
}

您的JSON略有偏差,您必须在name两边加上双引号,但这样您就可以运行以下 Playground:

import Cocoa
let jsonData = """
{
"dogs": [{"name": "Bella"}, {"name": "Lucy"}],
"cats": [{"name": "Oscar"}, {"name": "Coco"}]
}
""".data(using: .utf8)!
public struct Animal: Codable {
let name: String
}
do {
let anims = try JSONDecoder().decode([String:[Animal]].self, from:jsonData)
print(anims)
for kind in anims.keys {
print(kind)
if let examples = anims[kind] {
print(examples.map {exa in exa.name })
}
}
} catch {
print(error)
}

这不会限制您catsdogs,但使用"未知"键作为哈希中的数据元素通常是一个坏主意。如果你可以修改你的JSON(你应该这样做,因为它的结构不是很好(,你也可以将动物的"种类"移动到哈希数组中的一些数据元素,这将更加灵活。

相关内容

  • 没有找到相关文章

最新更新