swift - Swift:仅发布特定的可编码对象
问题描述
我正在尝试解决如何通过 put 请求仅上传某些值。本质上,我有一个应用程序,当用户访问特定屏幕时,会有一堆字段,其中一些值将从 API 预先填充(确切地说,哪些值已经填充是不可预测的)。任何空白字段都是可编辑的,用户可以将自己的值放入并通过放置请求上传。但是,我只想上传新值(在原始 API 响应中基本上是“nil”)。我不想覆盖初始响应附带的值并“重新上传”它们。这是实质上代表请求主体的可编码结构:
struct UpdateRequest: Codable {
let total: Double?
let discrep: Double?
let percent: Double?
let pre: Double?
let target: Double?
let req: Double?
let dep: Double?
}
所以所有值都是可选的。
这是我的更新方法,一旦用户完成“空白”并按下特定按钮,就会调用它:
func updateVals() {
let args = ["id": viewModel.id]
guard let body = convertValues() else { return }
API.client.post(.order, with: args, using: .put, posting: body, expecting: MessageResponse.self) { (success, response) in
switch success {
case .failure:
DispatchQueue.asyncMain {
let viewController = WarningViewController.detailsUpdatedFailure()
self.present(viewController, animated: true, completion: nil)
}
case .success:
DispatchQueue.asyncMain {
let viewController = WarningViewController.detailsUpdatedSuccess()
self.present(viewController, animated: true, completion: nil)
}
}
}
}
}
这是 convertValues() :
func convertValues() -> UpdateRequest? {
// In here I have a bunch of logic to convert values to specific units which is not relevant to this question
{
return UpdateRequest(
total: convertedTotal
discrep: convertedDiscrep
percent: convertedPercent
pre: convertedPre
target: convertedTarget
req: convertedReq
dep: convertedDep
)
}
return nil
}
但是,如果“total”例如在初始 API 响应中,我不想将其上传到此请求 - 因为此端点与我从中填充这些初始值的“get”端点基本相同。
显然,我可以编写逻辑来检查值是否在响应中,但是我怎样才能只将新值上传到此 UpdateRequest 而不会为我不需要的值上传“nil”值?
解决方案
您需要做的就是覆盖encode(to:)
并UpdateRequest
使用encodeIfPresent
,因为该方法不会包含 nil 值。
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(total, forKey: .total)
try container.encodeIfPresent(discrep, forKey: .discrep)
//... and so on
}
total
仅设置示例
let req = UpdateRequest(total: 123.5, discrep: nil, percent: nil, pre: nil, target: nil, req: nil, dep: nil)
do {
let data = try JSONEncoder().encode(req)
print(String(data: data, encoding: .utf8))
} catch {
print(error)
}
输出
可选(“{\”总计\“:123.5}”)
推荐阅读
- python - 如何在 Mac 上的 Python 中检测用户输入(例如命令 - ctrl+shift+k)?
- python - 当索引为 1 时,我想在 l1 中追加到 l2
- python - 为什么 root.quit() 或 root.destroy() 不起作用,而只是两者的结合?
- html - 如何从伪类内部查找类
- azure-devops - 如何自定义功能板后面的查询
- node.js - 我在封闭函数中使用'io()'
- c# - 如何使用winforms为所有客户端停止exe
- html - T-SQL:如何仅替换 img 标记上 src='data:image/png;base64' 属性的内容
- grafana - 面板中的 grafana 变量
- python-3.x - 具有多个权重的 DEAP 算法