ios - 使用 Decodable + Realm Swift 解码自定义 JSON

标签 ios swift realm decodable

我从服务器返回了一个大的 JSON,看起来像这样:

{
  "id": "123",
  "status": "ok",
  "person": {
    "administration": {
      "name": "John"
    }
  },
  "company": {
    "name": "Test"
  }
}

我有一个结构:

struct Info: Decodable, Object {
  let id: String
  let status: String
  let personName: String
  let companyName: String
}

它符合Decodable协议(protocol),也是一个Object(Realm实体)。 我的问题是:我能以某种方式解码 personName 中的人名吗?类似于 person.administration.name.
我希望最终的 Realm 对象是一个平面对象,并且大部分字段都是字符串。
我是否应该为 Person/Company 创建单独的结构而不是 Realm 对象,并在 decode 方法中将相应的值设置为“personName”?

let personName: String = try container.decode((Person.Administration.name).self, forKey: .personName)

最佳答案

您可以简单地使用 containers 来解码具有 Decodable 的嵌套数据,即

struct Info: Decodable {
    let id: String
    let status: String
    let personName: String
    let companyName: String

    enum CodingKeys: String, CodingKey {
        case id, status
        case person, administration
        case company
        case name
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decode(String.self, forKey: .id)
        status = try values.decode(String.self, forKey: .status)

        //Decoding personName
        let person = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .person)
        let administration = try person.nestedContainer(keyedBy: CodingKeys.self, forKey: .administration)
        personName = try administration.decode(String.self, forKey: .name)

        //Decoding companyName
        let company = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .company)
        companyName = try company.decode(String.self, forKey: .name)
    }
}

示例:

我已经解码了您在上面提供的 JSON,即

if let data = json.data(using: .utf8) {
    let info = try? JSONDecoder().decode(Info.self, from: data)
    print(info)
}

它给出的输出是:

(id: "123", status: "ok", personName: "John", companyName: "Test")

您可以根据自己的意愿为所有不同级别分离出CodingKeys。为简单起见,我将它们保持在同一水平。

建议尝试将可选类型Codable一起使用。这是因为 API 响应可能出乎意料。如果您没有得到任何预期的键值对,您可能会在创建对象时得到一个 nil

关于ios - 使用 Decodable + Realm Swift 解码自定义 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53434510/

相关文章:

ios - Realm Swift iOS - 安全地删除和重新键入加密的 Realm

ios - CoreData 上的 Realm 我应该使用 NSFetchedResultController 还是字典?

ios - 防止用户修改 SLComposeViewController 中的部分文本

ios - 找不到 SpriteBuilder 图像文件

ios - 需要帮助隐藏/显示自定义 navBar IOS Swift

swift - 如何取消选择谷歌地图中的标记swift

swift - 如何制作具有写时复制语义的容器? ( swift )

iphone - 使用 MKNetworkKit setImageFromURL 时如何获取图像帧?

swift - UIStackView 等间距包括边缘

swift - 如何更新版本来修复此错误? : 'Realm version is higher than the current version provided to ` setSchemaVersion:withMigrationBlock :`'