Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to bridge NSNumber to Float Swift 3.3

Tags:

json

swift

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?

like image 921
Malik Avatar asked Dec 01 '22 14:12

Malik


2 Answers

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

like image 95
OOPer Avatar answered Dec 16 '22 03:12

OOPer


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
like image 29
Krešimir Prcela Avatar answered Dec 16 '22 03:12

Krešimir Prcela