I added a protocol extension for a protocol with an associated type called PickerType
. I wrote a reimplementation of a function, refresh(:,completion:)
that’s defined in the protocol and implemented in a different protocol extension.
But the function inside my new extension isn’t called when I call refresh(:,completion:)
unless the compiler knows what type PickerType
is. I wrote the following:
extension PickerItemProvider where PickerType: Equatable & SyncableEntity {
func refresh(_ sender: Any, completion: (() -> Void)?) {
print("we're trying to have this implementation called")
PickerType.startSync()
}
}
It gets called as I would expect if I call refresh(:,completion:)
on a PickerSectionProvider<ObservationType>
(see the code from my Playground below) but not when I call refresh(:,completion:)
on an ItemProvider
, which is a generic type that must conform to PickerItemProvider
(again see my code below).
// We are trying to get our pickers to sync their provided type when you pull to refresh. But the implementation of refresh(:, completion:) that we added doesn’t get called.
import Foundation
protocol PickerItemProvider: class {
associatedtype PickerType
func findItem(by identifier: NSNumber) -> PickerType?
func itemAt(_ indexPath: IndexPath) -> PickerType?
func refresh(_ sender: Any, completion: (() -> Void)?)
}
extension PickerItemProvider {
func findItem(by identifier: NSNumber) -> PickerType? {
return nil
}
public func refresh(_ sender: Any, completion: (() -> Void)?) {
print("the default refresh implementation")
}
}
public class PickerSectionProvider<ProvidedType: Equatable> : PickerItemProvider {
func itemAt(_ indexPath: IndexPath) -> ProvidedType? {
return nil
}
}
extension PickerItemProvider where PickerType: Equatable & SyncableEntity {
func refresh(_ sender: Any, completion: (() -> Void)?) {
print("we’re trying to have this implementation called instead of the above implementation of refresh")
PickerType.startSync()
}
}
protocol SyncableEntity {
static func startSync()
}
extension SyncableEntity {
static func startSync() {
}
}
class ObservationType: Equatable, SyncableEntity {
}
func ==(lhs: ObservationType, rhs: ObservationType) -> Bool {
return false
}
class GenericPickerViewController<PickerType: Equatable, ItemProvider: PickerItemProvider> where ItemProvider.PickerType == PickerType {
var itemProvider: ItemProvider?
init() {
}
func foo() {
// Why doesn’t the implementation of refresh(:,completion:) we added get called here?
itemProvider?.refresh("dummy sender") {
}
}
}
class PopupPickerRow<T: Equatable, ItemProvider: PickerItemProvider> where ItemProvider.PickerType == T {
var pickerController = GenericPickerViewController<T, ItemProvider>()
}
let pickerSectionProvider = PickerSectionProvider<ObservationType>()
let row = PopupPickerRow<ObservationType, PickerSectionProvider<ObservationType>>()
row.pickerController.itemProvider = pickerSectionProvider
row.pickerController.foo()