After an Xcode update I encountered a weird problem. In my application, when I get a response from an API, I parse it manually and map it to my model. There are a lot of places in my code where I cast a JSON value to Float
with null coalescing like below:
randomVariable = jsonDict["jsonKey"] as? Float ?? 0
It used to work fine but after the update, it would always default to 0. In order to determine the cause, I tried force casting it to Float
like below
randomVariable = jsonDict["jsonKey"] as! Float
This resulted in the following error
Unable to bridge NSNumber to Float
Upon further investigation, I found out that Xcode is using Swift 3.3 (previously, it was using Swift 3.2). The solutions I found on StackOverflow revolve around casting it to NSNumber
instead of Float
. As I mentioned above, I have similar lines of code spread across my app. I was wondering if there is a way to fix this issue. Maybe using an extension of some sort?
As you have found, you may need to cast it first to NSNumber
.
Something like this:
randomVariable = (jsonDict["jsonKey"] as? NSNumber)?.floatValue ?? 0
Maybe regex replacement would help you update your code.
Pattern: jsonDict\[([^\]]*)\] as\? Float
Replace with: (jsonDict[$1] as? NSNumber)?.floatValue
The problem is in 32 bit architecture and updated NSNumber class in swift 4.1.
For example when I write number 1.1 into dictionary it will be stored as 64bit NSNumber with most accurate representation = 1.10000000000000008881784197001...
So, when you read this number as! Float it will fail because 32 bit precision is not good enough to get this most accurate representation.
The most accurate representation in 32 bit = 1.10000002384185791015625
64 bit presentation of float number
So, you need to get truncated result that is implemented inside NSNumber.floatValue() function.
randomVariable = (jsonDict["jsonKey"] as! NSNumber).floatValue
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With