Search code examples
swiftcastingdowncast

Casting Any? to Int, String or Bool


I have a function in Swift that returns Any? value and I would like to cast the result (based on the value type) to Bool, String or Int.

The function is this one:

static func value(forKey: SettingKeys) -> Any? {
    return settingManager.settings.filter({$0.key == forKey.rawValue}).first?.value
}

and then when I do:

let printingEnabled = AppSettings().value(forKey:"printingEnabled") as? Int

i get NIL. Without the casting, the value is Optional("1"). Similar when I try casting results to String or Int. Any idea of how I could cast the result to a type of my choosing?

Thank you.


Solution

  • You don't want a function to return Any?. It is a nightmare of a type. Instead, you want to use generics to make sure the value is the type you want. For example:

    static func value<T>(ofType: T.Type, forKey: SettingKeys) -> T? {
        return settingManager.settings.filter({$0.key == forKey.rawValue}).first?.value as? T
    }
    

    Then this would be:

    let printingEnabled = AppSettings().value(ofType: Int.self, forKey:"printingEnabled")
    

    printingEnabled will in this case be Int?.

    You can also, of course, wrap this up in helpers like:

    static func int(forKey: SettingKeys) -> Int? {
        return value(ofType: Int.self, forKey: forKey)
    }
    

    (BTW, while you definitely want to avoid Any? and use this kind of approach, I can't actually reproduce your issue. printingEnabled is Int? for me, and is Optional(1) as expected. I don't see any case where it's nil. But I can't make your code compile as written, either, since it's not clear what SettingKeys and settings are, so my code is probably significantly different than yours.)