簡體   English   中英

在 Swift 模型中解碼數組(可解碼)

[英]Decoding an Array in a Swift model (Decodable)

我正在從 API 檢索 JSON,我想為我使用的每個端點創建一個模型。

所有端點都使用此格式:

{
  "id": "xxxxxx",
  "result": {…},
  "error": null
}

關鍵是:

  • id始終是一個字符串
  • error可以為null或其中包含鍵的對象
  • result可以是null 對象或數組。

我遇到的問題是,在其中一個端點上,結果是數組的數組:

{
  "id": "xxxxxx",
  "result": [
      [
          "client_id",
          "name",
          50,
          "status"
      ]
  ],
  "error": null
}

如您所見,我有數組的數組,其中的值可以是 String 或 Int。

您如何使用 Decodable 協議對其進行解碼,然后根據其原始值將這些解碼值用作 String 或 Int?

import Foundation

let string =  """
{
    "id": "xxxxxx",
    "result": [
        [
            "client_id",
            "name",
            50,
            "status"
        ]
    ],
    "error": null
}
"""

struct Container: Codable {
    let id: String
    let result: [[Result]]
    let error: String?
}

enum Result: Codable {
    case integer(Int)
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(Int.self) {
            self = .integer(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        throw DecodingError.typeMismatch(Result.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Result"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(self)
    }
}

let jsonData = string.data(using: .utf8)!
let container = try? JSONDecoder().decode(Container.self, from: jsonData)

print(container)

改進了@ArinDavoodian 的回答。

讀取數據:

container?.result.first?.forEach { object in
    switch object {
    case let .integer(intValue):
        print(intValue)
        break
    case let .string(stringValue):
        print(stringValue)
        break
    }
}

一個簡單的解決方案:

let yourInsideArray = container?.result.first!
for index in 0..<yourInsideArray.count {
let yourObjectInsideThisArray = yourInsideArray[i]
//do some
 switch yourObjectInsideThisArray {
    case let .integer(intValue):
        print(intValue)
        break
    case let .string(stringValue):
        print(stringValue)
        break
    }
}

暫無
暫無

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

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