Cesare
Cesare

Reputation: 9409

Failing cast from Any to Int

I have the following dictionary of type [String: Any] (this is what the log looks like):

["name": Cesare de Cal, "last_name": de Cal, "email": [email protected], "id": 1012058902268810, "first_name": Cesare]

I want to get the profile ID "id":

if let fbID = fbValues["id"] as? Int {
    print("here should be the fb Id", fbID)
} else {
    print("cast failed") // cast failed
}

but this cast fails. Why? I'm assuming "id" (1012058902268810) is a number, right?

Upvotes: 1

Views: 2186

Answers (2)

Peter
Peter

Reputation: 806

rob already provided you with a possible solution. Just to answer your question about why the cast fails, it fails because of how type casting works in Swift:

From the documentation:

Type casting is a way to check the type of an instance, or to treat that instance as a different superclass or subclass from somewhere else in its own class hierarchy. (...) A constant or variable of a certain class type may actually refer to an instance of a subclass behind the scenes. Where you believe this is the case, you can try to downcast to the subclass type with a type cast operator (as? or as!). (...) Casting does not actually modify the instance or change its values. The underlying instance remains the same; it is simply treated and accessed as an instance of the type to which it has been cast.

This will work:

let something: Any = 1
let number = something as! Int

This won't work:

let something: Any = "1"
let number = something as! Int

This won't work either because Int has no initializer for type Any:

let something: Any = "1"
let number = Int(something)

But this will work - first you cast to String and then you coerce to Int (and Int has an initializer that accepts String)

let something: Any = "1"
let string = something as! String
let number = Int(string)!

Edit to answer Cesare: You're right. I edited my answer to just provide more info about type casting since you already had your problem solved ;)

And these were just some examples for getting the cast/coercion point across. In a real scenario you shouldn't be forcing unwrapping any of this as John Montgomery pointed out.

Upvotes: 2

rob mayoff
rob mayoff

Reputation: 385540

If you don't know whether the id value is coming in as a String or an Int, you could try handling both:

switch fbValues["id"] {
case nil:
    print("no id given")
case let string as String:
    if let id = Int(string) { print("id = \(id)") }
    else { print("non-numeric id \(string)") }
case let id as Int:
    print("id = \(id)")
default:
    print("what is this I don't even")
}

Upvotes: 1

Related Questions