Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift cast dictionary value as type

I am looking for best way how can I make this code to one line:

if (dictionary["Amoumt"] is Double) {
    amount = dictionary["Amount"] as Double
} else {
    amount = NSString(string: dictionary["Amount"] as String).doubleValue
}

I have Dictionary<String, AnyObject> and I would like to parse values from it. I am using code like above but it's too many lines. I would like to make it to one line. Something like:

dictionary["Amount"].parseDouble()

There is no problem to create extension with this method:

func parseDouble() -> Double {
    if (self is Double) {
        return self as Double
    } else {
        return NSString(string:(self as String)).doubleValue
    }
}

But which type should I extend? Next could you help me with generic method? So I could call something like this:

dictionary["Amount"].parse(Double)

And is this good way how to do this or should I do it another way?

like image 247
Libor Zapletal Avatar asked Nov 01 '22 08:11

Libor Zapletal


1 Answers

You can use AnyObject as is. Try:

var dictionary:[String:AnyObject] = [
    "foo": 4.21,    // NSNumber
    "bar": "42.5",  // NSString
    "baz": [1,2,3], // NSArray
]

let foo = dictionary["foo"]?.doubleValue ?? 0 // -> 4.21
let bar = dictionary["bar"]?.doubleValue ?? 0 // -> 42.5
let baz = dictionary["baz"]?.doubleValue ?? 0 // -> 0.0

This works because both NSNumber and NSString have .doubleValue property. On the other hand, NSArray does not have that property, in this case it returns nil.

As described in the document:

You can also call any Objective-C method and access any property without casting to a more specific class type. This includes Objective-C compatible methods marked with the @objc attribute.

like image 123
rintaro Avatar answered Nov 09 '22 17:11

rintaro