I'm having the below setup (where Content is an abstraction and Clip is one of its concrete types):
enum PlayableItem<Content: Hashable> {
case placeholder
case content(Content)
}
protocol DataSourceType<Content> {
associatedtype Content: Hashable
var dataItems: [PlayableItem<Content>] { get set }
}
protocol ListView<Content> {
associatedtype Content: Hashable
var dataSource: any DataSourceType<Content> { get set }
}
class DIManager {
private let dict = [String: Any]()
public func resolve<T>(_ dependencyType: T.Type) -> T {
dict["Something"] as! T
}
}
// -----------------------------------------------------------------------
struct Clip: Hashable { }
// I tried to use this protocol in ClipsListView but without luck
protocol ClipsDataSourceType: DataSourceType where Content == Clip { }
class ClipDataSource: ClipsDataSourceType {
var dataItems: [PlayableItem<Clip>] = [.placeholder, .content(Clip())]
}
class ClipsListView: ListView {
var dataSource: any DataSourceType<Clip>
init() {
if #available(iOS 16.0.0, *) {
dataSource = DIManager().resolve((any DataSourceType<Clip>).self)
} else {
dataSource = ClipDataSource()
}
}
}
We're targeting iOS lower than 16, so I'm trying to make this setup work on lower targets, before Runtime support for parameterized protocol types in Swift was introduced.
Basically I need PlayableItem, the Datasource and the ListView be generic. So that I can make specializations like ClipsDatasource/ClipsListView.
By “avoid,” are you saying that you simply do not want to write < and >? If so, you can write typealias ClipDataSourceType = DataSourceType<Clip>, but I’m not sure I understand the desired outcome here.
If I put the typealias, I'd have an error next to class ClipDataSource: ClipsDataSourceType { saying "Cannot inherit from protocol type with generic argument 'ClipsDataSourceType' (aka 'DataSourceType')".
I appreciate that the example's goal is not that eloquent, apologies for that. I'm doing a refactoring into some existing code, that the above example mimics. I redacted the original question. The goal is, you could say, to make it compile for targets lower than iOS 16.
Aside from the default ClipsDataSource argument, which wouldn't scale past your example but satisfies your example, what does that achieve that this cannot?
extension ListView where DataSource.Content == Clip
Thanks @Jessy, I'll give that a try. Although in an extension we cannot have stored properties, and most probably I'd need to add some in each subclass/specialization.
And besides, with this I get the error: associated type 'Content' can only be used with a concrete type or generic parameter base