Swift编码:如何为TestModel实现多编码策略优化API请求?
解决TestModel增量编码的几种方案
你现在的场景是需要给同一个模型实现两种编码策略:全量编码用于常规请求,增量编码只发送必要字段节省带宽。下面是几种实用的实现方式:
方案1:添加自定义编码方法,手动处理编码流程
直接在TestModel里实现你设想的encodeForUpdate(to:)方法,然后手动构建编码逻辑,绕开JSONEncoder默认调用的encode(to:)方法:
class TestModel { enum CodingKeys: String, CodingKey { case someKey = "some_key" case otherKey = "other_key" case thirdKey = "third_key" case apiID = "id" // ... 更多其他键 } // 原始全量编码方法 func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(someKeyValue, forKey: .someKey) try container.encode(otherKeyValue, forKey: .otherKey) try container.encode(thirdKeyValue, forKey: .thirdKey) // ... 更多其他编码字段 } // 自定义增量更新编码方法 func encodeForUpdate(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(apiID, forKey: .apiID) try container.encode(justOneValueToUpdate, forKey: .someKey) } }
调用时需要手动创建编码器并触发自定义方法:
func getUpdateData(from model: TestModel) throws -> Data { let encoder = JSONEncoder() let userInfo: [CodingUserInfoKey: Any] = [:] let updateEncoder = try encoder.encoder(for: userInfo) try model.encodeForUpdate(to: updateEncoder) return try encoder.encode(updateEncoder) }
方案2:用编码模式动态切换字段(最便捷)
给模型加一个编码模式属性,在默认的encode(to:)方法里根据模式决定要编码的字段,这样可以直接复用JSONEncoder的默认流程:
class TestModel: Encodable { enum CodingMode { case full case update } enum CodingKeys: String, CodingKey { case someKey = "some_key" case otherKey = "other_key" case thirdKey = "third_key" case apiID = "id" // ... 更多其他键 } // 新增编码模式属性,默认全量编码 var codingMode: CodingMode = .full // 模型原有属性 var someKeyValue: String var otherKeyValue: Int var thirdKeyValue: Bool var apiID: String var justOneValueToUpdate: String func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) switch codingMode { case .full: try container.encode(someKeyValue, forKey: .someKey) try container.encode(otherKeyValue, forKey: .otherKey) try container.encode(thirdKeyValue, forKey: .thirdKey) // ... 其他全量字段 case .update: try container.encode(apiID, forKey: .apiID) try container.encode(justOneValueToUpdate, forKey: .someKey) } } }
调用时只需切换模式,再用常规方式编码:
let testModel = TestModel(/* 初始化参数 */) testModel.codingMode = .update let updateData = try JSONEncoder().encode(testModel)
方案3:创建专用的更新模型(最清晰)
如果更新字段固定,直接创建一个只包含必要字段的结构体,专门用于更新请求,避免原模型逻辑复杂化:
// 专用更新模型 struct TestModelUpdate: Encodable { enum CodingKeys: String, CodingKey { case apiID = "id" case someKey = "some_key" } let apiID: String let someKey: String // 从原模型快速初始化 init(from model: TestModel) { self.apiID = model.apiID self.someKey = model.justOneValueToUpdate } }
调用时直接生成更新模型再编码:
let testModel = TestModel(/* 初始化参数 */) let updateModel = TestModelUpdate(from: testModel) let updateData = try JSONEncoder().encode(updateModel)
内容的提问来源于stack exchange,提问作者PlankTon
相关产品推荐
相关产品推荐

