gpt4 book ai didi

swift - 如何通过指定其 CodingKeys 的子集来对 Codable 类型进行编码?

转载 作者:行者123 更新时间:2023-12-03 23:05:22 24 4
gpt4 key购买 nike

我有我提供的类型 CodingKeys根据需要为其数据成员提供自定义名称。我想根据不同调用站点的要求,仅编码类型 CodingKeys 的一个子集。在将数据发送到服务器之前。所需的编码因调用站点而异,因此无需考虑默认实现。
示例类型(用于演示目的):

struct Account: Codable
{
let name: String;
var balance: Float;

mutating func set(balance: Float)
{
self.balance = balance; // verifications, etc.
}
}

struct User: Codable
{
enum CodingKeys: String, CodingKey
{
case
id = "db_id",
name = "db_name",
account
// many more keys
}

let id: Int;
let name: String;
var account: Account;
// many more data members
}
创建实例:
var user = User(
id: 1, name: "john", account: Account(name: "checking", balance: 10_000));
使用 JSONEncoder按预期工作;它产生以下结果:
{
"db_id" : 1,
"db_name" : "john",
"account" : {
"balance" : 10000,
"name" : "checking"
}
}
我想对 User 的一个子集进行编码type 以便将该数据发送回服务器,以便我可以更新特定数据字段,而不是更新我的类型的整个属性集。模拟使用示例:
user.account.set(balance: 15_000);
let jsonEncoding = JSONEncodeSubset.of(
user, // instance to encode
keys: [User.CodingKeys.id, User.CodingKeys.account] // data to include
);
生成的 JSON 如下所示:
{
"db_id" : 1,
"account" : {
"balance" : 15000,
"name" : "checking"
}
}
服务器端,我们现在拥有执行所需更新所需的确切数据。
另一个示例:有人为我们的用户输入了错误的名称,因此另一个更新请求如下所示:
user.name = "jon"; // assume the model was modified to make this mutable
let jsonEncoding = JSONEncodeSubset.of(
user, // instance to encode
keys: [User.CodingKeys.id, User.CodingKeys.name] // only encode id & name
);
预期的结果 JSON 编码:
{
"db_id" : 1,
"name" : "jon"
}
请注意,我们排除了不属于更新的信息(用户帐户)。目标是优化编码以仅包含与该特定请求相关的数据。
考虑到我有大量要更新的对象列表,不同的调用站点更新不同的内容,我想有一种简洁的方式来执行编码任务。
  • 对类型数据成员的子集进行编码可以提高编码性能/内存占用。
  • 向服务器发送更多数量的较小编码对象变得更有效率。

  • Swift 是否为编码类型 CodingKeys 的子集提供任何此类支持? ?

    最佳答案

    此解决方案需要您编写自定义 encode(to:)对于所有属性,但一旦完成,它应该很容易使用。
    这个想法是让encode(to:)仅对给定数组中存在的那些属性/键进行编码。所以给出上面的例子,函数看起来像这样

    func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    for key in selectedCodingKeys {
    switch key {
    case .id:
    try container.encode(id, forKey: .id)
    case .account:
    try container.encode(account, forKey: .account)
    case .name:
    try container.encode(name, forKey: .name)

    }
    }
    }
    selectedCodingKeys是结构中的新属性
     var selectedCodingKeys = [CodingKeys]()
    我们还可以添加一个特定的编码函数
    mutating func encode(for codingKeys: [CodingKeys]) throws -> Data {
    self.selectedCodingKeys = codingKeys
    return try JSONEncoder().encode(self)
    }
    然后解码可以像在这个例子中那样完成
    var user = User(id: 1, name: "John", account: Account(name: "main", balance: 100.0))
    do {
    let data1 = try user.encode(for: [.id, .account])
    let data2 = try user.encode(for: [.id, .name])
    } catch {
    print(error)
    }

    关于swift - 如何通过指定其 CodingKeys 的子集来对 Codable 类型进行编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63077827/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com