ios - swift在http请求中发送一个数值,实际值加上000000000000001

标签 ios swift siesta-swift

我正在尝试向服务器执行 HTTP 请求:内容是一个 JSON 对象,其中包含键“金额”的数值。如果“金额”是带有小数位的值,例如1.6、请求中会包含值 1.6000000000000001,服务器不接受这个值(api 是 Java 制作的,类型是 float 。我不能向服务器发送 String,因为从我那里接收数据的 API 只能接受数字“数量"。我尝试使用 Siesta Framework 或 dataTask 执行请求,但结果始终相同

这就是我创建请求的方式(我省略了不太重要的部分)

let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject) // jsonObject contains the Double value "amount"
let request = URLRequest(url: url)
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request)    
task.resume()

最佳答案

如果没有完全重现问题的代码,很难确定,但我想您看到的是这种行为:

let amount = 1.6  // Double
let jsonObject = ["amount": amount]
let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject)
String(data: jsonData, encoding: String.Encoding.utf8)

Swift Foundation 的 JSON 序列化始终将数值格式化为全精度 — 因此 double 字 1.6 被格式化为 1.6000000000000001

方案一:发送字符串

如果服务器接受,您可以并且应该发送一个字符串:

let amount = "1.6"  // String
let jsonObject = ["amount": amount]
let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject)
String(data: jsonData, encoding: String.Encoding.utf8)

请注意,如果您正在处理金钱或任何其他需要精确值的事物,字符串是发送该值的唯一正确方式:即使您将其拼写为 1.6,标准的 JSON 解析器可能会在接收端将其转换为 float 。

解决方案 2:使用 Decimal 更改格式

如果出于某种原因你只是需要以较低的精度格式化它以使其在服务器上通过验证,你可以将它作为 Decimal 而不是 Double< 嵌入到 JSON 中 并且它的格式会有所不同:

let amount = 1.6
let jsonObject = ["amount": Decimal(amount)]
let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject)
String(data: jsonData, encoding: String.Encoding.utf8)
// {"amount":1.6}

您甚至可以操纵 Decimal 以四舍五入到特定精度。

但是请注意,这并不能避免浮点精度问题:您仍在根据 JSON 规范发送 float ,并且它仍然很可能在接收端被解析为 float 。

关于ios - swift在http请求中发送一个数值,实际值加上000000000000001,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48320047/

相关文章:

ios - Xcode:禁用后启用Create Git Repository

ios - 快速接触多个节点 - IOS

ios - Swift 的 Facebook SDK 文档是否过时?对应的SDK版本是多少?

siesta-swift - 身份验证 token

ios - 如何使用结构化模型层在 Siesta 中实现持久缓存

ios - 使用 TableViewController 创建双委托(delegate)

ios - 我可以在 iOS native 联系人中添加应用程序的自定义链接吗?

ios - 午睡 JSON 响应

ios - 更改从shouldAutorotateToInterfaceOrientation返回: at runTime

嵌套导航 Controller 上的 iOS8 行为