【问题标题】:Complex JSON in Swift. How to get the data correctly. Different structuresSwift 中的复杂 JSON。如何正确获取数据。不同的结构
【发布时间】:2021-11-05 09:12:04
【问题描述】:

遇到一个难题,接收数据时不知道如何将数据分解成一个数组。

负责的变量包含不同类型的数据。

我说对了吗?我认为在初始化程序中通过可能的选项并替换所需的选项?这个数组的变量应该是什么类型?

[
  {
    "id": 42,
    "created_at": "2021-09-08T08:55:58.000000Z",
    "updated_at": "2021-09-08T08:55:58.000000Z",
    "link": "u4986",
    "type": "u",
    "responsible": {
      "id": 4986,
      "type": "management_company",
      "email": "X@X.com",
      "phone": "+0000000000",
      "comment": null,
      "first_name": "Alex",
      "second_name": "Hook"
    }
  },
  {
    "id": 43,
    "created_at": "2021-09-08T08:55:58.000000Z",
    "updated_at": "2021-09-08T08:55:58.000000Z",
    "link": "r14",
    "type": "r",
    "responsible": {
      "id": 14,
      "name": "manager",
      "guard_name": "api",
      "created_at": "2021-06-15T19:20:20.000000Z",
      "updated_at": "2021-06-15T19:20:20.000000Z"
    }
  }
]

如何为 MyJson 制作初始化器

struct MyJson: Codable {
    let id: Int
    let createdAt: String
    let updatedAt: String
    let link: String
    let type: String
    let responsible: Any
}

// MARK: - Responsible
struct User: Codable {
    let id: Int
    let type, email, phone, comment: String
    let firstName, secondName: String
}

struct UserCategory: Codable {
    let id: Int
    let name, guardName, createdAt, updatedAt: String
}

【问题讨论】:

  • app.quicktype.io ?你的 JSON 没有什么复杂的。制作可编码的结构。
  • AnyCodable 中不受支持。不同responsible 类型的最佳解决方案是具有关联值的枚举。如果不同的类型与type 值唯一相关,那很容易
  • 用户?它来自哪里?

标签: json swift struct


【解决方案1】:

在 swift JSON 解析中非常简单,构建一个反映您的 JSON 的对象(我刚刚在这里基于您的 JSON 构建了一个示例):

struct JsonExample: Decodable {
  let id: Int
  let responsible: [Responsible]

  struct Responsible: Decodable {
      let id: Int
      let email: String
      let guard_name: String
  }
}

然后直接解码

let jsonData = "json_string".data(using: .utf8)!
do {
      let decoded = try JSONDecoder().decode([JsonExample].self, from: jsonData)
            
} catch let error {
      print(error.localizedDescription)
}

如果您想区分嵌套对象,可以使用 init 并使用 JSON 中的属性来完成工作

init(from decoder : Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.id = try container.decode(Int.self, forKey: .id)
    let type = try container.decode(String.self, forKey: .type)
    if type == "a" {
         let data = try container.decode([ResponsibleA].self, forKey: . responsible)
         responsible = .responsibleA(data)
    } else { // add better error handling
         let data = try container.decode([ResponsibleB].self, forKey: . responsible)
         responsible = .responsibleB(data)
    }
 }

【讨论】:

  • 感谢您的回复。请注意责任人有不同的类型
  • 只需使用 JSON 可以返回的所有属性填充 Responibile,您不需要全部初始化
  • 一个数组可以包含不同的结构。不只是这些。如果我一个人做,那将是一个非常大的结构。我在程序的另一部分使用了 User 结构,我不需要不属于它的字段
【解决方案2】:

完成了很长时间的任务。最后我解决了这个问题。如果你正面临这个问题。你会在这里找到解决方案Indeterminate Types with Codable in Swift

【讨论】:

  • 如果你能在你的自我回答中写一些关于你如何解决问题的文字会更好,这样未来的读者就不必依赖你的链接来帮助他们弄清楚你的问题做了。
  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多