LoadingState<Movie> conform to Equatable

Advertisements

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.

Leave a ReplyCancel reply