-
-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for DecodingError "Expected to decode Double but found Int instead." #22
base: master
Are you sure you want to change the base?
Fix for DecodingError "Expected to decode Double but found Int instead." #22
Conversation
Int literals cannot be cast as a Double using `as?` so `Double(<Int>)` must be used instead. JSON has only one Number type, and allows "5" to be considered a Double, not just "5.0"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to address any other types?
Thank you Shane! @tattn it's my colleague @shanecowherd commenting above. Shane, I won't need anything beyond Double that I can foresee right now. Float would probably be a good choice for the library more generally. @tattn probably knows what types are otherwise supported by the library. |
Thank you for your PR 👍 I created Could you please share the use case? |
Thank you for your feedback @tattn I'm happy to share our use case which may be surprising. I'll try to explain the use case simply:
Unfortunately in JSON, a Double like "1.00" can be written as "1" and so RN sends @tattn Would you be open to supporting this use case in your library if it's not a lot of extra work? If you do decide to support this use case, this PR would be needed for that. If you don't want to support this use case, then I can maintain a fork of your repo at my company's organization and keep the fix localized to that fork. That's ok too. Example: Here is the function definition, in Swift, of a RN NativeModule function. This is what's called by JS.
|
@andrewash I haven't used React Native in a production environment, so I wasn't aware of the issue where Double is converted to Int when treated as JSON in data transmission. This seems like a problematic specification 😢 Using DictionaryDecoder as a JSON decoder is an interesting idea, but overly flexible decoding might delay the detection of implementation errors. Here's what I suggest:
For 1: let decoder = DictionaryDecoder()
decoder.decodingStrategy = .json
try decoder.decode(JSON.self, from: jsonDictionary) Setting For 2: struct RNDouble: Decodable, Equatable {
var value: Double
init(_ value: Double) {
self.value = value
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
do {
value = try container.decode(Double.self)
} catch {
value = Double(try container.decode(Int.self))
}
}
}
struct Model: Decodable, Equatable {
let double: RNDouble
} This approach directly addresses the issue but might be slightly cumbersome due to type nesting. What are your thoughts on these proposals? |
Related Issue
#21
Description
Int literals cannot be cast as a Double using
as?
soDouble(<Int>)
must be used instead.JSON has only one Number type, and allows "5" to be considered a Double, not just "5.0"
However MoreCodable's DictionaryDecoder always decoded "3" as an Int so we would need a way to convert it to a Double to support JSON's flexible number formats.
Testing
I've included a new unit test that fails before this PR, and passes once the change is made to
func castOrThrow<T>()
References
This railroad from json.org shows that
3
is totally valid as a JSON number