>假设我有一个返回此 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 代表一个动物数组。但事实并非如此。它表示具有键的字典dogs
和cats
.所以你只是这么说。
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)
}
这不会限制您cats
和dogs
,但使用"未知"键作为哈希中的数据元素通常是一个坏主意。如果你可以修改你的JSON
(你应该这样做,因为它的结构不是很好(,你也可以将动物的"种类"移动到哈希数组中的一些数据元素,这将更加灵活。