Womble Womble - 1 year ago 173
Swift Question

Swift 3 - class name/type lookup

My app uses hundreds of subclasses of a drawing class. (These subclasses are automatically generated from art files.)

Ideally, I'd like to load in the names of some subclasses, check if those subclasses are actually available, and if so, instantiate them.

However, it would seem that the lack of

-style functionality in pure Swift means that I am forced to declare all my class names to the compiler in advance.

e.g. getting a class via a very long, tedious switch statement:

func drawingObjectFromClassName(_ className: String) -> SomeDrawingProtocol?
switch className {
case "foo": return foo()
case "bar": return bar()
// etc.

print("Warning: no class found for className: ", className)
return nil

But I'd also like to check for the existence of a subclass (e.g. "foo") without having to instantiate the object.

I could duplicate that switch statement to do this, but then I'd have two identical sets of keys to maintain. Yuck.

So, one possible solution is to use a lookup table.

Question: if I hard-code a Dictionary with all my subclass names as the keys, what syntax do I need for the values , such that a retrieved value can be instantiated as an object of the required class? Thanks for any help.

Answer Source
protocol P {

extension String : P { }

extension Int : P { }

let types : [String : P.Type] = [
    "str": String.self,
    "int": Int.self

if let type = types["int"] {
    let object = type.init()
    assert(object is Int)

You can now use all the standard dictionary operations to check if things are present, cast the types you pull out however you want, etc.

I defined the protocol in the example above in order to have a common initialiser (which is probably what you'll need in most cases), but you can simply use Any.Type and cast the type using as Int.Type if needed.