Swift - 如何将平面 json 解码为嵌套结构?
Swift - How to decode flat json to nested structure?
假设我有以下 JSON,我想将其解码为特定结构。我该怎么做
JSON:
{
"fullName": "Federico Zanetello",
"id": 123456,
"twitter": "http://twitter.com/zntfdr",
"results": ["mate","bate"]
}
解码结构
struct Response {
let data: UserData,
let results: [String]
}
UserData
结构
Struct UserData {
let fullName: String,
let id: Int,
let twitter: String
}
我进行了研究,但找不到有效的解决方案。这是我到目前为止写的代码
struct UserData: Decodable {
let fullName: String
let id: Int
let twitter: String
enum CodingKeys: String, CodingKey {
case fullName
case id
case twitter
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.fullName = try container.decode(String.self, forKey: .fullName)
self.id = try container.decode(Int.self, forKey: .id)
self.twitter = try container.decode(String.self, forKey: .twitter)
}
}
struct Respone: Decodable{
let data: UserData
let results: [String]
}
let json = """
{
"fullName": "Federico Zanetello",
"id": 123456,
"twitter": "http://twitter.com/zntfdr",
"results": ["mate","bate"]
}
""".data(using: .utf8)! // our data in native (JSON) format
let myStruct = try JSONDecoder().decode(MetaData.self, from: json) // Decoding our data
print(myStruct)
我收到 KeynotFound 错误,因为 data
密钥不在 JSON 中。我该如何解决?
你只需要这个结构..数据在你的响应中没有作为键出现
// MARK: - User
struct User: Codable {
let fullName: String
let id: Int
let twitter: String
let results: [String]
}
像这样解码广告
let myStruct = try JSONDecoder().decode(User.self, from: json)
注意:如果您不执行任何额外操作,则不需要 init()
可编码函数。如果结构元素的名称相同,则不需要 CodingKeys
以下是如何将 UserData
用作带有 interface segregation
的单独对象
struct Response: UserData, Codable {
let fullName: String
let id: Int
let twitter: String
let results: [String]
}
protocol UserData {
var fullName: String {get}
var id: Int {get}
var twitter: String{get}
}
let myStruct = try JSONDecoder().decode(Response.self, from: json)
let userData : UserData = myStruct
print(userData.fullName)
你可以这样做:
struct UserData: Decodable {
let fullName: String
let id: Int
let twitter: String
}
struct Response: Decodable{
let data: UserData
let results: [String]
enum CodingKeys : CodingKey {
case results
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
results = try container.decode([String].self, forKey: .results)
data = try decoder.singleValueContainer().decode(UserData.self)
}
}
诀窍是在 Response
中使用自定义解码,像平常一样解码 results
后,得到 singleValueContainer
。此容器将包含您 JSON 中的所有密钥,因此您可以使用此容器解码 UserData
.
假设我有以下 JSON,我想将其解码为特定结构。我该怎么做
JSON:
{
"fullName": "Federico Zanetello",
"id": 123456,
"twitter": "http://twitter.com/zntfdr",
"results": ["mate","bate"]
}
解码结构
struct Response {
let data: UserData,
let results: [String]
}
UserData
结构
Struct UserData {
let fullName: String,
let id: Int,
let twitter: String
}
我进行了研究,但找不到有效的解决方案。这是我到目前为止写的代码
struct UserData: Decodable {
let fullName: String
let id: Int
let twitter: String
enum CodingKeys: String, CodingKey {
case fullName
case id
case twitter
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.fullName = try container.decode(String.self, forKey: .fullName)
self.id = try container.decode(Int.self, forKey: .id)
self.twitter = try container.decode(String.self, forKey: .twitter)
}
}
struct Respone: Decodable{
let data: UserData
let results: [String]
}
let json = """
{
"fullName": "Federico Zanetello",
"id": 123456,
"twitter": "http://twitter.com/zntfdr",
"results": ["mate","bate"]
}
""".data(using: .utf8)! // our data in native (JSON) format
let myStruct = try JSONDecoder().decode(MetaData.self, from: json) // Decoding our data
print(myStruct)
我收到 KeynotFound 错误,因为 data
密钥不在 JSON 中。我该如何解决?
你只需要这个结构..数据在你的响应中没有作为键出现
// MARK: - User
struct User: Codable {
let fullName: String
let id: Int
let twitter: String
let results: [String]
}
像这样解码广告
let myStruct = try JSONDecoder().decode(User.self, from: json)
注意:如果您不执行任何额外操作,则不需要 init()
可编码函数。如果结构元素的名称相同,则不需要 CodingKeys
以下是如何将 UserData
用作带有 interface segregation
struct Response: UserData, Codable {
let fullName: String
let id: Int
let twitter: String
let results: [String]
}
protocol UserData {
var fullName: String {get}
var id: Int {get}
var twitter: String{get}
}
let myStruct = try JSONDecoder().decode(Response.self, from: json)
let userData : UserData = myStruct
print(userData.fullName)
你可以这样做:
struct UserData: Decodable {
let fullName: String
let id: Int
let twitter: String
}
struct Response: Decodable{
let data: UserData
let results: [String]
enum CodingKeys : CodingKey {
case results
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
results = try container.decode([String].self, forKey: .results)
data = try decoder.singleValueContainer().decode(UserData.self)
}
}
诀窍是在 Response
中使用自定义解码,像平常一样解码 results
后,得到 singleValueContainer
。此容器将包含您 JSON 中的所有密钥,因此您可以使用此容器解码 UserData
.