Reputation: 441
or can I check if a number was decoded as a decimal number and not and integer later?
if let int = any as? Int {
print("Object in an integer")
} else if let num = any as? Double {
print("Object in a double")
}
, where "any" is an Any value and = 1.0 (not a string) in the JSON file. "any" can be cast to both integer and double (so the order of which I check determines the outcome), but I would like to keep the original format from the JSON file.
Decoding is done using the following line:
let json = try JSONSerialization.jsonObject(with: data, options: [])
Edit: I've tried checking CFType, but get the same for both 1 and 1.0 (inspired by http://stackoverflow.com/a/30223989/1694526)
Any ideas?
Upvotes: 2
Views: 3081
Reputation: 20590
The solution is to parse to an NSNumber
and then to a Decimal
(or NSDecimalNumber
). DO NOT parse via a Double
.
let jsonString = "[ 4.01 ]"
let jsonData = jsonString.data(using: .utf8)!
let jsonArray = try! JSONSerialization.jsonObject(with: jsonData, options: []) as! [Any]
// This is the WRONG way to parse decimals (via a Double)
// parseAttemptA = 4.009999999999998976
let parseAttemptA: Decimal = Decimal(jsonArray[0] as! Double)
// This is the CORRECT way to parse decimals (via an NSNumber)
// parseAttemptB = 4.01
let parseAttemptB: Decimal = (jsonArray[0] as! NSNumber).decimalValue
Here's a screenshot of a playground...
Upvotes: 2
Reputation: 16774
As already mentioned by @Sulthan this is not possible on the level you are working as JSONSerialization
will and should use a single class to represent a value and may not determine its type.
You could try finding some other tool to check for values but does it really make sense?
Int
and Double
but what about 64 or 32 bit? Or signed and unsigned? We usually don't write those into strings so there really is no way to distinguish between them. So there is really no general logic in doing so.JSONSerialization
and print out String(data: (try! JSONSerialization.data(withJSONObject: [ "value": 1.0 ], options: .prettyPrinted)), encoding: .utf8)
I receive: {\n \"value\" : 1\n}
which means it trimmed ".0" anyway.The only way would be to use it as a display string. But in that case your value should be returned as a string and not as a number.
Upvotes: 2