Swift: AnyObject cast to Float failed
The 0.6
is a Double
literal value. As such, you can't cast it to Float
(you need to convert it).
Try this instead:
let f = Float(json["progress"] as! Double)
Or, if you aren't really sure what type of number this AnyObject
holds, the safer approach would be:
let f = (json["progress"] as! NSNumber).floatValue
Of course, those as!
above will crash hard if the json value is missing or you misjudge the expected type. Use the as?
operator instead if you feel otherwise :)
Casting crash course. When casting a known Double
value to a Float
, the compiler gives us a nice heads up about this:
let d = 0.6
let f = d as? Float
warning: cast from 'Double' to unrelated type 'Float' always fails
Unexpected behavior when casting an NSNumber to Float
This is a consequence of SE-0170 NSNumber bridging and Numeric types, implemented in Swift 4:
as?
forNSNumber
should mean "Can I safely express the value stored in this opaque box called a NSNumber as the value I want?".
1.12
is a floating point literal, and inferred as a Double
, so NSNumber(value: 1.12)
is “boxing” the 64-bit floating point value
closest to 1.12
. Converting that to a 32-bit Float
does not
preserve this value:
let n = NSNumber(value: 1.12)
let x = Float(truncating: n) // Or: let x = n.floatValue
let nn = NSNumber(value: x)
print(n == nn) // false
On the other hand, 1.0
can be represented exactly as a Float
:
let m = NSNumber(value: 1.0)
let y = m.floatValue
let mm = NSNumber(value: y)
print(m == mm) // true
and that is why casting m as? Float
succeeds. Both
n.floatValue
Float(truncating: n)
can be used to ”truncate” the number to the closest representable
32-bit floating point value.
Casting problems after updating from Swift 4 to 4.1
Can you try
if let floatDoubleArray = response.result.value as? [[NSNumber]] {
let floatArr = floatDoubleArray.map{$0.map{$0.floatValue}}
}
Unable to bridge NSNumber to Float Swift 3.3
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
Implicit Any? to Any cast warning when passing Any? type variable in as Any? type parameter
Dictionary look ups return optional values because the key might not exist. In the case of a non-existent key, the look up returns nil
, so the type of the dictionary look up has to be optional.
In your case, your values are of type Any?
, so a look up from that dictionary returns a doubly wrapped optional Any??
. So you are trying to pass a value of type Any??
to a function that takes Any?
.
If you use optional binding to handle and unwrap the dictionary access, everything works:
let testDict : Dictionary<String, Any?> = ["Test": "Hello"];
if let value = testDict["Test"] {
// "Test" key is valid
someFunc(value);
}
Unable to bridge NSNumber to Float Swift 3.3
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
Casting CGFloat to Float in Swift
You can use the Float()
initializer:
let cgFloat: CGFloat = 3.14159
let someFloat = Float(cgFloat)
Convert Float to Int in Swift
You can convert Float
to Int
in Swift like this:
var myIntValue:Int = Int(myFloatValue)
println "My value is \(myIntValue)"
You can also achieve this result with @paulm's comment:
var myIntValue = Int(myFloatValue)
Related Topics
How to Avoid Duplicate Key Error in Swift When Iterating Over a Dictionary
Cast Any to Float Always Fails in Swift4.1
Cannot Convert Double to String
Attributed Text, Replace a Specific Font by Another Using Swift
How to Specify the Type Information of an Array That Would Hold Swiftui Custom Views
Extending a Protocol Where Self: Generic Type in Swift (Requires Arguments in <...>)
How to Set Scrollview Content Size in Swift 3.0
Instance Member 'View' Cannot Be Used on Type 'Gamescene'
Cannot Call Value of Non-Function Type 'Ciimage'
MAC App to Switch Between /Etc/Hosts Files, How to Allow Access
Delegate Must Respond to Locationmanager:Didupdatelocations Swift Eroor
Swift Calculate Time for Timers Running in Background
How Have Multiple Init() with Swift
Skaction.Movebyx Not Setting Physicsbody.Velocity
Swift 3: Int Is Not Convertible to Bool in Bitwise Operation
Swift: Accessing Computed Property Through Pointer
Swift Error Using Initialized Properties in Expressions Before Super.Init