Swift可编码:使用父项';s键作为值
我有一个在根级别具有ID的JSON:Swift可编码:使用父项';s键作为值,swift,codable,decodable,jsondecoder,Swift,Codable,Decodable,Jsondecoder,我有一个在根级别具有ID的JSON: { "12345": { "name": "Pim" }, "54321": { "name": "Dorien" } } 我的目标是使用Codable创建一个同时具有name和ID属性的用户对象数组。 struct User: Codable { let id: String let name: String } 我知道如何使用Codable,也知道如何工作。但我在这里尝试
{
"12345": {
"name": "Pim"
},
"54321": {
"name": "Dorien"
}
}
我的目标是使用Codable创建一个同时具有name和ID属性的用户对象数组。
struct User: Codable {
let id: String
let name: String
}
我知道如何使用Codable,也知道如何工作。但我在这里尝试的是两者的结合,我不知道下一步该怎么做
到目前为止,我得到的是:(你可以把这个贴在操场上)
这就是我想做的:
let decoder = JSONDecoder()
do {
let decoded = try decoder.decode([User].self, from: data)
decoded.forEach { print($0) }
// User(id: "54321", name: "Dorien")
// User(id: "12345", name: "Pim")
} catch {
print("Failed to decode JSON")
}
非常感谢您提供的任何帮助。您可以使用自定义编码密钥并按如下所示设置用户来解析未知密钥
struct CustomCodingKey: CodingKey {
let intValue: Int?
let stringValue: String
init?(stringValue: String) {
self.intValue = Int(stringValue)
self.stringValue = stringValue
}
init?(intValue: Int) {
self.intValue = intValue
self.stringValue = "\(intValue)"
}
}
struct UserInfo: Codable {
let name: String
}
struct User: Codable {
var id: String = ""
var info: UserInfo?
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CustomCodingKey.self)
if let key = container.allKeys.first {
self.id = key.stringValue
self.info = try container.decode(UserInfo.self, forKey: key)
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CustomCodingKey.self)
if let key = CustomCodingKey(stringValue: self.id) {
try container.encode(self.info, forKey: key)
}
}
}
let decoder = JSONDecoder()
do {
let decoded = try decoder.decode(User.self, from: data)
print(decoded.id) // 12345
print(decoded.info!.name) // Pim
} catch {
print("Failed to decode JSON")
}
不过别忘了设置自定义编码器。或者用可解码的而不是可编码的。这很好。在同一个对象中获取所有属性只剩下一件事了,比如:User{let id:String,let name:String}。我相信我会找到答案的。我刚刚意识到这样我得到的是一个单用户对象,而我期待的是一个用户数组。我将更新我的问题,使之更清楚。你的回答结构越来越差
Id
、name
或其他user
相关属性应位于作为数组返回的同一对象中。如果这是不可能的,那么当前结构应该作为数组发送,否则没有选项,然后将其解码为字典(即[String:UserInfo].self
),然后将每个字典映射到用户。我完全同意你的观点。不幸的是,这是我必须处理的情况。。。感谢您抽出时间给出您的答案。
struct CustomCodingKey: CodingKey {
let intValue: Int?
let stringValue: String
init?(stringValue: String) {
self.intValue = Int(stringValue)
self.stringValue = stringValue
}
init?(intValue: Int) {
self.intValue = intValue
self.stringValue = "\(intValue)"
}
}
struct UserInfo: Codable {
let name: String
}
struct User: Codable {
var id: String = ""
var info: UserInfo?
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CustomCodingKey.self)
if let key = container.allKeys.first {
self.id = key.stringValue
self.info = try container.decode(UserInfo.self, forKey: key)
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CustomCodingKey.self)
if let key = CustomCodingKey(stringValue: self.id) {
try container.encode(self.info, forKey: key)
}
}
}
let decoder = JSONDecoder()
do {
let decoded = try decoder.decode(User.self, from: data)
print(decoded.id) // 12345
print(decoded.info!.name) // Pim
} catch {
print("Failed to decode JSON")
}