user89862
user89862

Reputation:

Swift - instantiate class from type returned in a function

Is it possible to return the type of a class from a function?

I'm trying to do something like this:

func giveMeAClass() -> AnyClass {
    return String.self
}

let theClass = giveMeAClass()

let instantiatedFromTheClass = theClass()

let castedFromTheClass = someObject as! theClass

EDIT:

Another example where I'm trying to do something more useful

class BaseModel {
    var baseProperty: String!
}

class TextModel: BaseModel {
    var textProperty: String!
}

class DateModel: BaseModel {
    var dateProperty: NSDate!
}

class BaseCell<T: BaseModel>: UITableViewCell {
    var model: T!
}

class TextCell: BaseCell<TextModel> {

}

class DateCell: BaseCell<DateModel> {

}

func getCellTypeForModel(model: BaseModel) -> ??? {

    if model is TextModel {
        return TextCell.Type // ???
    }

    else if model is DateModel {
        return DateCell.self // ???
    }

    return BaseCell.somethingElse // ???
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let model = cellModels[indexPath.item] as! BaseModel
    let cellType = getCellTypeForModel(anyModel)
    let castedCell = tableView.dequeueReusableCellWithIdentifier("identifier", forIndexPath: indexPath) as! cellType

    // give the model to the cell, customize it, etc

    return castedCell
}

Upvotes: 0

Views: 554

Answers (1)

dfrib
dfrib

Reputation: 73186

When initializing from metatypes, you need to explicitly call the initializer. E.g.

protocol SimplyInitializable { init() }

extension String: SimplyInitializable {}
extension Int: SimplyInitializable {}

class Foo : SimplyInitializable {
    let foo : Int
    required init() { foo = 42 }
}

func getType<T: SimplyInitializable>(type: T.Type) -> SimplyInitializable.Type {
    return type
}

/* example usage */
var MyType = getType(String)
let foo = MyType.init() as! String // "", String

MyType = getType(Int)
let bar = MyType.init() as! Int // 0, Int

MyType = getType(Foo)
let baz = MyType.init() as! Foo
baz.foo // 42

Note that you needn't a function to make the metatype assignment, e.g.

let MyType2 : SimplyInitializable.Type = Foo.self
let foobar = MyType2.init()

Upvotes: 2

Related Questions