1

I am using VIPER architecture with Swift.
I want to use protocol for presenter to get UITableView delegate, because I do not want to repeat the declarations of those methods for all presenters.

So I have created protocol

protocol TableViewPresenterProtocol: class {
    associatedtype Data
    func numberOfSections()-> Int
    func haeaderTitle(secton: Int)-> String?
    func numberOfRows(section: Int)-> Int
    func itemForCell(at indexPath: IndexPath)-> Data
    func didSelect(at indexPath: IndexPath)
}

//for make optional
extension TableViewPresenterProtocol {
    func numberOfSections()-> Int {
        return 1
    }
    
    func haeaderTitle(secton: Int)-> String? {
        return nil
    }
}

class PaymentViewController {
    var presenter: (PaymentPresenterProtocol & TableViewPresenterProtocol)?
}

but XCode shows error

Protocol 'TableViewPresenterProtocol' can only be used as a generic constraint because it has Self or associated type requirements

Where in the source code do I fix that?

greybeard
  • 2,249
  • 8
  • 30
  • 66
Mirzohid Akbarov
  • 1,192
  • 1
  • 10
  • 17

1 Answers1

1

In your PaymentViewController currently the compiler has no chance to identify what your associatedtype Data refers to. It can be a String, it can be an Int or anything else. Swift does not like that. It can't work with that because it is ambiguous what the associatedtype really refers to.

In order to solve the issue, we can use TableViewPresenterProtocol as a generic constraint to tell Swift actually what type we are referring to. In your case it looks like this:

class PaymentViewController<A: TableViewPresenterProtocol> {
    var presenter: (A)?
}

And let's say you create a class, which conforms to TableViewPresenterProtocol:

class SomeOtherController: TableViewPresenterProtocol {
     typealias Data = String
     // Other conformance stuff here
}

And now you can say:

PaymentViewController<SomeOtherController>()

And it will be clear to Swift that the presenter's associatedtype Data is a String.

πter
  • 1,899
  • 2
  • 9
  • 23