Swift 4 JSON 可编码 ID 作为键
Swift 4 JSON Codable ids as keys
我想将 Swift 4 的可编码功能与 json 一起使用,但有些键没有设置名称。而是有一个数组,它们是像
这样的 id
{
"status": "ok",
"messages": {
"generalMessages": [],
"recordMessages": []
},
"foundRows": 2515989,
"data": {
"181": {
"animalID": "181",
"animalName": "Sophie",
"animalBreed": "Domestic Short Hair / Domestic Short Hair / Mixed (short coat)",
"animalGeneralAge": "Adult",
"animalSex": "Female",
"animalPrimaryBreed": "Domestic Short Hair",
"animalUpdatedDate": "6/26/2015 2:00 PM",
"animalOrgID": "12",
"animalLocationDistance": ""
您在哪里可以看到 181 个 ID。有谁知道如何处理 181 以便我可以将其指定为密钥?该数字可以是任何数字,并且每个数字都不同。
想要这样的东西
struct messages: Codable {
var generalMessages: [String]
var recordMessages: [String]
}
struct data: Codable {
var
}
struct Cat: Codable {
var Status: String
var messages: messages
var foundRows: Int
//var 181: [data] //What do I place here
}
提前致谢。
我认为您不能将数字声明为变量名。来自 Apple's doc:
Constant and variable names can’t contain whitespace characters,
mathematical symbols, arrows, private-use (or invalid) Unicode code
points, or line- and box-drawing characters. Nor can they begin with a
number, although numbers may be included elsewhere within the name.
正确的方法是让 属性 捕获您的 key
。
struct Cat: Codable {
var Status: String
var messages: messages
var foundRows: Int
var key: Int // your key, e.g., 181
}
请检查:
struct ResponseData: Codable {
struct Inner : Codable {
var animalID : String
var animalName : String
private enum CodingKeys : String, CodingKey {
case animalID = "animalID"
case animalName = "animalName"
}
}
var Status: String
var foundRows: Int
var data : [String: Inner]
private enum CodingKeys: String, CodingKey {
case Status = "status"
case foundRows = "foundRows"
case data = "data"
}
}
let json = """
{
"status": "ok",
"messages": {
"generalMessages": ["dsfsdf"],
"recordMessages": ["sdfsdf"]
},
"foundRows": 2515989,
"data": {
"181": {
"animalID": "181",
"animalName": "Sophie"
},
"182": {
"animalID": "182",
"animalName": "Sophie"
}
}
}
"""
let data = json.data(using: .utf8)!
let decoder = JSONDecoder()
do {
let jsonData = try decoder.decode(ResponseData.self, from: data)
for (key, value) in jsonData.data {
print(key)
print(value.animalID)
print(value.animalName)
}
}
catch {
print("error:\(error)")
}
我建议这样:-
struct ResponseData: Codable {
struct AnimalData: Codable {
var animalId: String
var animalName: String
private enum CodingKeys: String, CodingKey {
case animalId = "animalID"
case animalName = "animalName"
}
}
var status: String
var foundRows: Int
var data: [AnimalData]
private enum CodingKeys: String, CodingKey {
case status = "status"
case foundRows = "foundRows"
case data = "data"
}
struct AnimalIdKey: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int? { return nil }
init?(intValue: Int) { return nil }
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let animalsData = try container.nestedContainer(keyedBy: AnimalIdKey.self, forKey: .data)
self.foundRows = try container.decode(Int.self, forKey: .foundRows)
self.status = try container.decode(String.self, forKey: .status)
self.data = []
for key in animalsData.allKeys {
print(key)
let animalData = try animalsData.decode(AnimalData.self, forKey: key)
self.data.append(animalData)
}
}
}
let string = "{\"status\":\"ok\",\"messages\":{\"generalMessages\":[],\"recordMessages\":[]},\"foundRows\":2515989,\"data\":{\"181\":{\"animalID\":\"181\",\"animalName\":\"Sophie\"}}}"
let jsonData = string.data(using: .utf8)!
let decoder = JSONDecoder()
let parsedData = try? decoder.decode(ResponseData.self, from: jsonData)
这样你的解码器初始化程序本身就可以处理密钥。
我想将 Swift 4 的可编码功能与 json 一起使用,但有些键没有设置名称。而是有一个数组,它们是像
这样的 id{
"status": "ok",
"messages": {
"generalMessages": [],
"recordMessages": []
},
"foundRows": 2515989,
"data": {
"181": {
"animalID": "181",
"animalName": "Sophie",
"animalBreed": "Domestic Short Hair / Domestic Short Hair / Mixed (short coat)",
"animalGeneralAge": "Adult",
"animalSex": "Female",
"animalPrimaryBreed": "Domestic Short Hair",
"animalUpdatedDate": "6/26/2015 2:00 PM",
"animalOrgID": "12",
"animalLocationDistance": ""
您在哪里可以看到 181 个 ID。有谁知道如何处理 181 以便我可以将其指定为密钥?该数字可以是任何数字,并且每个数字都不同。
想要这样的东西
struct messages: Codable {
var generalMessages: [String]
var recordMessages: [String]
}
struct data: Codable {
var
}
struct Cat: Codable {
var Status: String
var messages: messages
var foundRows: Int
//var 181: [data] //What do I place here
}
提前致谢。
我认为您不能将数字声明为变量名。来自 Apple's doc:
Constant and variable names can’t contain whitespace characters, mathematical symbols, arrows, private-use (or invalid) Unicode code points, or line- and box-drawing characters. Nor can they begin with a number, although numbers may be included elsewhere within the name.
正确的方法是让 属性 捕获您的 key
。
struct Cat: Codable {
var Status: String
var messages: messages
var foundRows: Int
var key: Int // your key, e.g., 181
}
请检查:
struct ResponseData: Codable {
struct Inner : Codable {
var animalID : String
var animalName : String
private enum CodingKeys : String, CodingKey {
case animalID = "animalID"
case animalName = "animalName"
}
}
var Status: String
var foundRows: Int
var data : [String: Inner]
private enum CodingKeys: String, CodingKey {
case Status = "status"
case foundRows = "foundRows"
case data = "data"
}
}
let json = """
{
"status": "ok",
"messages": {
"generalMessages": ["dsfsdf"],
"recordMessages": ["sdfsdf"]
},
"foundRows": 2515989,
"data": {
"181": {
"animalID": "181",
"animalName": "Sophie"
},
"182": {
"animalID": "182",
"animalName": "Sophie"
}
}
}
"""
let data = json.data(using: .utf8)!
let decoder = JSONDecoder()
do {
let jsonData = try decoder.decode(ResponseData.self, from: data)
for (key, value) in jsonData.data {
print(key)
print(value.animalID)
print(value.animalName)
}
}
catch {
print("error:\(error)")
}
我建议这样:-
struct ResponseData: Codable {
struct AnimalData: Codable {
var animalId: String
var animalName: String
private enum CodingKeys: String, CodingKey {
case animalId = "animalID"
case animalName = "animalName"
}
}
var status: String
var foundRows: Int
var data: [AnimalData]
private enum CodingKeys: String, CodingKey {
case status = "status"
case foundRows = "foundRows"
case data = "data"
}
struct AnimalIdKey: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int? { return nil }
init?(intValue: Int) { return nil }
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let animalsData = try container.nestedContainer(keyedBy: AnimalIdKey.self, forKey: .data)
self.foundRows = try container.decode(Int.self, forKey: .foundRows)
self.status = try container.decode(String.self, forKey: .status)
self.data = []
for key in animalsData.allKeys {
print(key)
let animalData = try animalsData.decode(AnimalData.self, forKey: key)
self.data.append(animalData)
}
}
}
let string = "{\"status\":\"ok\",\"messages\":{\"generalMessages\":[],\"recordMessages\":[]},\"foundRows\":2515989,\"data\":{\"181\":{\"animalID\":\"181\",\"animalName\":\"Sophie\"}}}"
let jsonData = string.data(using: .utf8)!
let decoder = JSONDecoder()
let parsedData = try? decoder.decode(ResponseData.self, from: jsonData)
这样你的解码器初始化程序本身就可以处理密钥。