Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an object depending on a String in Swift?

Here is my code what I would like to refactor:

let myCell = MyCustomTableViewCell()
self.createCell(myCell, reuseIdentifierString: "myCellIdentifier")

the MyCustomTableViewCell conforms to the SetCell protocol so it works fine. and the SetCell protocol is not an @obj_c protocol. This is a swift protocol

private func createCell<T where T:SetCell>(classType: T, reuseIdentifierString: String) -> UITableViewCell {
  var cell = _tableView.dequeueReusableCellWithIdentifier(reuseIdentifierString) as T
  cell.setText()
  return cell.getCustomCell()
}

And now I refactor my code, I would like to create the myCell depending on a String, but the string is exactly the same as my Class name. I dont want to use else-if or switch-case

let myCell: AnyClass! = NSClassFromString("MyCustomTableViewCell")
self.createCell(myCell, reuseIdentifierString: "myCellIdentifier")

But now the myCell which is AnyClass does not conform to protocol. How can I do this?

like image 691
szuniverse Avatar asked Sep 08 '14 15:09

szuniverse


1 Answers

You need a little more code than that. You will get an AnyClass and not an AnyObject. So you need to create an instance of that type. You could try this:

let cellClass: AnyClass! = NSClassFromString("MyCell")
var objectType : NSObject.Type! = cellClass as NSObject.Type!
var theObject: NSObject! = objectType() as NSObject
var myCell:MyCell = theObject as MyCell

For letting it conform to your protocol you could try a couple of things:

1. You could create a base class for all your cells that conforms to a protocol. And use that in the code above instead of the UITableViewCell. For this you could use code like this:

protocol SetCell {
    func setcell() {}
}
class BaseUITableViewCell : UITableViewCell, SetCell {
    func setcell() {}
}
class MyCell : BaseUITableViewCell {
    override func setcell() {}
}

let cellClass: AnyClass! = NSClassFromString("MyCell")
var objectType : NSObject.Type! = cellClass as NSObject.Type!
var theObject: NSObject! = objectType() as NSObject
var myCell:BaseUITableViewCell = theObject as BaseUITableViewCell

2. You can extend the UITableViewCell with your extension like by adding an empty extension

extension UITableViewCell: SetCell {}

//compile-time error:

Declarations from extensions cannot be overridden yet

//Edwin: Strange, this is in the documentation. So it looks like this one is out...

3. You could define a variable that conforms to a protocol like this:

@objc protocol SetCell {
    func setcell() {}
}

let cellClass: AnyClass! = NSClassFromString("MyCell")
var objectType : NSObject.Type! = cellClass as NSObject.Type!
var myCell2:protocol<SetCell> = objectType() as protocol<SetCell>
like image 110
Edwin Vermeer Avatar answered Nov 01 '22 08:11

Edwin Vermeer