I'm trying to make my SwiftUI views more "Previewable" therefore I'm making them generic over their Store (ViewModel) so I can more easily mock them.
Consider the following example:
public protocol HomeViewStore: ObservableObject {
associatedtype AnimatableImageStoreType = AnimatableImageStore
var title: String { get }
var animatableImageStores: [AnimatableImageStoreType] { get }
var buttonTapSubject: PassthroughSubject<Void, Never> { get }
var retryTapSubject: PassthroughSubject<Void, Never> { get }
}
public protocol AnimatableImageStore: ObservableObject, Identifiable {
var imageConvertible: Data? { get }
var onAppear: PassthroughSubject<Void, Never> { get }
}
struct AnimatableImage<
AnimatableImageStoreType: AnimatableImageStore
>: View {
@ObservedObject private var store: AnimatableImageStoreType
public init(store: AnimatableImageStoreType) {
self.store = store
}
...
}
public struct HomeView<
HomeViewStoreType: HomeViewStore
>: View {
@StateObject private var store: HomeViewStoreType
public init(store: HomeViewStoreType) {
self._store = StateObject(wrappedValue: store)
}
public var body: some View {
VStack {
Text(store.title)
Button {
store.buttonTapSubject.send(())
} label: {
Text("API Call")
}
.background(Color(.accent))
.padding()
Button {
store.retryTapSubject.send(())
} label: {
Text("Retry")
.font(.monserrat(.bold, 14))
}
.padding()
List(store.animatableImageStores) { animatableImageStore in
AnimatableImage(store: animatableImageStore)
}
}
.background(Color(.accent))
}
}
The code gives me the following error messages:
My questions would be, why is HomeViewStoreType.AnimatableImageStoreType not conforming to AnimatableImageStore protocol when inside HomeViewStore protocol I'm constraining it to AnimatableImageStore protocol and the same goes for Identifiable which AnimatableImageStore conforms to?
Would appreciate if someone could show me a proper way to achieve this :)
CodePudding user response:
This line doesn't constraint AnimatableImageStoreType
to AnimatableImageStore
:
associatedtype AnimatableImageStoreType = AnimatableImageStore
Replace =
by :
and it will work:
associatedtype AnimatableImageStoreType: AnimatableImageStore