I have my LoadingState defined as follows:
enum LoadingState<T: Codable> {
case none
case loading
case success(T)
case error(Error)
}
Movie is defined below:
struct Movie: Codable {
let title: String
}
In my SwiftUI view I am trying to use the task(id) modifier as shown below:
struct ContentView: View {
@State private var loadingState: LoadingState<Movie> = .none
var body: some View {
VStack {
Button("Perform Time Consuming Operation") {
loadingState = .loading
}.buttonStyle(.borderedProminent)
}.task(id: loadingState) {
}
}
}
But I get the following error:
Instance method 'task(id:priority:_:)' requires that 'LoadingState<Movie>' conform to 'Equatable'
Any ideas?
>Solution :
You have to make your types conform to Equatable
. Exactly what the error message says.
For your Movie
type it can be autogenerated, you just have to add Equatable
protocol name to the declaration:
struct Movie: Codable, Equatable { // <- here
let title: String
}
For the enum
it’s a bit tricker, if you want it to work only with T
also being Equatable
you may declare it as
enum LoadingState<T: Codable & Equatable>: Equatable {
// case … case … etc
}
// or
enum LoadingState<T>: Equatable where T: Codable, T: Equatable {
// case … case … etc
}
Or, if you want LoadingState
work with any T
, but to conform to Equatable
iff T
is also Equatable
you have to do it in extension (your original enum declaration stays):
extension LoadingState: Equatable where T: Equatable { }
You may also need to do something with .error(Error)
case too, it may want to declare it as generic type and attach Equatable
to it too, as we did with T
above.