簡體   English   中英

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 錯誤,因為 JSON 中不存在data密鑰。 我該如何解決這個問題?

你可以這樣做:

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

你只需要這個結構。數據在你的響應中不作為鍵出現

// 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() function 進行編碼。如果結構元素的名稱相同,則不需要CodingKeys

以下是如何將UserData用作具有interface segregation的單獨 object

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM