SwiftUI View cannot conform custom Equatable protocol in Swift 6.

In Swift 6, stricter concurrency rules can lead to challenges when making SwiftUI views conform to Equatable. Specifically, the == operator required for Equatable must be nonisolated, which means it cannot access @MainActor-isolated properties. This creates an error when trying to compare views with such properties:

Error Example:

struct MyView: View, Equatable {
    let title: String  
    let count: Int

    static func ==(lhs: MyView, rhs: MyView) -> Bool {
        // Accessing `title` here would trigger an error due to actor isolation.
        return lhs.count == rhs.count
    }

    var body: some View {
        Text(title)
    }
}

Error Message:

Main actor-isolated operator function '==' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode.

Any suggestions?

Thanks

FB: FB15753655 (SwiftUI View cannot conform custom Equatable protocol in Swift 6.)

Answered by DTS Engineer in 813558022

It looks like you got lots of good replies on Swift Forums.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I tested your code in Xcode 16.1ß3 (Swift 6.0.2).

It apparently works.

I even tested with

        return lhs.count == rhs.count && lhs.title == rhs.title

Could you show complete code to reproduce ? Where exactly do you declare MyView ?

It looks like you got lots of good replies on Swift Forums.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Ensure that Swift Concurrency is marked in the build settings @Claude31

Love seeing so much interaction in the Swift Forums!

I'm going to summarize the discussion:

Potential Workarounds:

  1. Add @preconcurrency to the Equatable Protocol:

One potential solution discussed is adding @preconcurrency to the Equatable protocol. This would suggest that we are confident Apple will improve this in the future. However, this information hasn’t been officially communicated in the forums. @DTS Engineer isn't it?

  1. Using MainActor.assumeIsolated:

Another approach mentioned is using MainActor.assumeIsolated as described in Swift documentation .

This works under the assumption that Equatable will only be used from the MainActor. While this might work in some cases, it could lead to issues such as the program stopping if the assumption is incorrect. It seems like a good solution but not ideal practice, even, in this case won't stop the program.


Additionally, some forum members pointed out that using the Equatable protocol with views might not be possible.

There is also a feature request (FB15753655) proposing the creation of a custom Equatable protocol specifically for views that use @MainActor

Update: You cannot use MainActor.assumeIsolated because the render graph, which uses the com.apple.SwiftUI.AsyncRenderer queue, can operate off the main thread.

SwiftUI View cannot conform custom Equatable protocol in Swift 6.
 
 
Q