Daniel Hooper Daniel Hooper - 1 month ago 11
Swift Question

Cannot downcast object of type Any to Int when accessing from dictionary

I have a Gfycat struct that represents the data I want to store after making a network call to the Gfycat API.

typealias JSONDictionary = [String: Any]

struct Gfycat {
let id: String
let number: Int
}


In an extension to the Gfycat struct, I wrote a failable initializer that takes a dictionary of type [String: Any] as its argument. This dictionary is then used to assign values to the struct's properties. This is the original init method I wrote:

extension Gfycat {
init?(dictionary: JSONDictionary) {
guard let id = dictionary["gfyId"] as? String,
let number = dictionary["gfyNumber"] as? Int { return nil }
self.id = id
self.number = number
}
}


The problem is that when accessing a value from the dictionary, I cannot downcast the value from Any to Int. I must first downcast Any to String, then convert that string to Int. Is this a bug or rather a feature of Swift that I don't understand?

This was my solution:

extension Gfycat {
init?(dictionary: JSONDictionary) {
guard let id = dictionary["gfyId"] as? String,
let uncastedNumber = dictionary["gfyNumber"] as? String,
let number = Int(uncastedNumber) else { return nil }
self.id = id
self.number = number
}
}

Answer

I must first downcast Any to String, then convert that string to Int. Is this a bug or rather a feature of Swift that I don't understand?

It's neither a bug nor a feature of Swift. It's a fact about the dictionary you're working with. This thing is a String, not an Int. So you cannot cast it to an Int.