使用swift在http请求中发送数值,将000000000000001添加到实际值

时间:2018-01-18 11:18:12

标签: ios swift siesta-swift

我尝试向服务器执行HTTP请求:内容是一个JSON对象,其中包含密钥的数值" amount"。如果"金额"是带十进制数字的值,例如1.6,请求将包含该值  1.6000000000000001,服务器不接受此值(api是Java制作的,类型是浮点数。我无法向服务器发送字符串,因为从我那里接收数据的API只能接受&#的数字34; amount"。我尝试使用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()

2 个答案:

答案 0 :(得分:4)

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

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序列化始终将数值格式化为完全精度 - 因此双精度数字1.6的格式为1.6000000000000001

解决方案1:发送字符串

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

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解析器可能会将其转换为接收端的浮点数。

解决方案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规范发送浮点数,并且它仍然很可能在接收端被解析为浮点数。

答案 1 :(得分:0)

在没有看到您的代码的情况下提供帮助很有挑战性,但是,要检查的一件事是您是否使用NumberFormatter来确保您正在对您的值进行正确的舍入。假设你从UITextField中提取数字,那么你需要这样的东西:

 agrep('timothy', c('timo','tim','timoth', 'timothys'), max.distance = 0.01, value=TRUE)