4

I am trying to create a generic UITableViewDataSource implementation. Internally, the DataSource implementation uses an NSFetchedResultsController to receive the data. Here is my current code.

extension UITableViewCell {
    class var reuseIdentifier: String {
        return toString(self).componentsSeparatedByString(".").last!
    }
}

class ManagedDataSource<CellType: UITableViewCell, ItemType>: NSObject, NSFetchedResultsControllerDelegate, UITableViewDataSource {

    // MARK: Properties

    var fetchRequest: NSFetchRequest {
        get {
            return fetchedResultsController.fetchRequest
        }
        set {
            fetchedResultsController = NSFetchedResultsController(fetchRequest: newValue, managedObjectContext: HMServicesManager.mainContext(), sectionNameKeyPath: nil, cacheName: nil)
        }
    }

    private var fetchedResultsController: NSFetchedResultsController {
        didSet {
            fetchedResultsController.delegate = self
        }
    }

    private let configureCell: (item: ItemType, cell: CellType) -> ()
    private weak var tableView: UITableView?

    // MARK: Initialization

    init(fetchRequest: NSFetchRequest,
        tableView: UITableView,
        tableViewCellType cellType: CellType.Type,
        itemType: ItemType.Type,
        configureCell: (item: ItemType, cell: CellType) -> ()) {
            self.tableView = tableView
            self.configureCell = configureCell
            fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: HMServicesManager.mainContext(), sectionNameKeyPath: nil, cacheName: nil)
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(CellType.reuseIdentifier, forIndexPath: indexPath) as! CellType
        return cell
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 0
    }


}

The UITableViewDataSource implementation and the NSFetchedResultsControllerDelegate implementation are currently incomplete but that is not my problem. I am getting a compiler error on the class definition of ManagedDataSource:

Type 'ManagedDataSource' does not conform to protocol 'UITableViewDataSource'

I don't understand why the compiler gives me an error, as the required methods of UITableViewDataSource are implemented by my class. The problem seems to be with the generics. As soon as I remove the generics and use AnyObject instead, the error goes away and my code compiles fine. That is not quite what I want though because that way the class is not type safe.

naglerrr
  • 2,809
  • 1
  • 12
  • 24
  • 2
    It is not possible because generic Swift methods are not visible to Objective-C. See http://stackoverflow.com/questions/26097581/generic-nsoperation-subclass-loses-nsoperation-functionality for a very similar issue. – Martin R Jun 29 '15 at 08:16

1 Answers1

0

This is now possible with Swift 2.0 without any workaround.

naglerrr
  • 2,809
  • 1
  • 12
  • 24
  • have you tried to make `ManagedDataSource` conform to `UITableViewDataSource` within a extension ? – onmyway133 Oct 19 '15 at 02:38
  • As I said in my answer, this is now possible using Swift 2.0 without any workaround needed. With Swift 2.0 you can just conform to `UITableViewDataSource`. I do not know if I tried to conform to the protocol using and extension before the update to Swift 2.0, but I think I did. – naglerrr Nov 02 '15 at 19:12