Home > Mobile >  Why does associatedtype not conform to protocols defined in its constraining protocol?
Why does associatedtype not conform to protocols defined in its constraining protocol?

Time:06-01

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:

enter image description here

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
  • Related