Using actors in a SwiftUI .task

Hi,

having the concurrency checks (-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks) enabled I always get this warning, when trying to access/use an actor in a SwiftUI .task: "Cannot use parameter 'self' with a non-sendable type 'ContentView' from concurrently-executed code".

What would be a correct implementation?

Here's a minimal code-sample which produces this warning:

import SwiftUI

struct ContentView: View {
  @State var someVar = 5
  var a1 = A1()

  var body: some View {
    Text("Hello, world!")
      .padding()
      .task {
        await a1.doSomething()
      }
  }
}

public actor A1 {
  func doSomething() {
    print("Hello")
  }
}

Replies

The problem is that someone can mutate a1 before, and during the tasks runtime. One way to fix this is to make ContentView run all its accesses on the main thread by making it a @MainActor like so:

@MainActor
struct ContentView: View {

If having all interactions run on the main thread is not ideal you could also make ContentView an actor like so:

actor ContentView: View {
...
  nonisolated var body: some View { 

The nonisolated tells the compiler to not implicitly make it isolated, which would make that function no longer able to comply with the protocol View. For a Swift View id recommend going the @MainActor annotation.