I'm trying to implement the repository pattern in Swift in a generic way. The problem that I'm currently facing is, that it seems like I have to write type erasure wrappers for all my repositories. Am I missing something here? Is there a better way to do this or to make the compiler happy at this point?
// 1
class Item {}
// 2
protocol Repository {
associatedtype T
}
// 3
protocol AnyItemRepository: Repository where T == Item {}
// 4
class ItemRepository: AnyItemRepository {
static let shared = ItemRepository()
private init() {}
}
// 5
class ViewController {
// 6
var itemRepository: AnyItemRepository? = ItemRepository.shared
}
Protocol 'AnyItemRepository' can only be used as a generic constraint because it has Self or associated type requirementsYou don't need the AnyItemRepository type. Just write extension methods on Repository like so:
public extension Repository where T == Item {
func doSomethingSpecial(with items: [Item]) {
// blah blah
}
}
In your view controller, you can't use Repository or AnyItemRepository in this way because these are generic type constraints. You must either use a concrete type or generically parameterize ViewController.
class RepositoryViewController<R>: UIViewController where R: Repository, R.T == Item {
var itemRepository: R { get }
}
class ViewController: RepositoryViewController<ItemRepository> {
override var itemRepository: ItemRepository {
return ItemRepository.shared
}
}
(The above is untested pseudocode designed to give you the gist. It has never been run by anyone ever and may not even compile.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With