Swift closure as values in Dictionary

closures, ios, objective-c, swift

Solution

Your basic problem is that in Objective-C closures (aka blocks) are represented as NSObject (or more precisely are transparently converted to NSObjects) while in Swift there is no such mapping. This means that closures can not be directly stored in a Dictionary (short of using objective-c glue)

The closest I can come up with is something along the lines of wrapping the value in an enum:

enum DataType {
    case AsString(String)
    case AsClosure((AnyObject)->String)
}

var dict:Dictionary<String,DataType> = [
    "string":DataType.AsString("value"),
    "closure":DataType.AsClosure({(argument:AnyObject) -> String in
        return "value"
        }
    )
]

Which is probably a better solution anyway, because this way you have an explicit typing associated with individual arguments instead of it being implicit using some sort of inflection.

Alternatively, you could only wrap the closure and use a dictionary of type `Dictionary<String,Any>`.

Problem

I'm trying to use an Objective-C library which expects a `NSDictionary` as its return type. Within the `NSDictionary`, I can return values of any type, including blocks. I cannot figure out if there is a way to write an analogous swift method that returns a Dictionary with a closure or a string as a possible value type. I can't use `AnyObject` as the value type for the dictionary so this doesn't work: ``` Dictionary<String,AnyObject> = ["Key":{(value:AnyObject) -> String in return value.description] ``` I get a `Does not conform to protocol error` from the compiler regarding the closure and `AnyObject`. Is there a higher level type or protocol that both closures and basic types adhere to that I can use as the value type in a Dictionary?

Original source