SwiftUI Commands and StrictConcurrency Warnings Issue

I have enabled “StrictConcurrency” warnings in my project that uses SwiftUI. I have a Commands struct. It has a Button, whose action is calling an async method via Task{}. This builds without warnings within Views, but not Commands. There the compiler reports “Main actor-isolated property 'body' cannot be used to satisfy nonisolated protocol requirement”.

Looking at SwiftUI:

In View, body is declared @MainActor:

@ViewBuilder @MainActor var body: Self.Body { get }

In Commands, body is not declared @MainActor:

@CommandsBuilder var body: Self.Body { get }

So the common practice of making a Button action asynchronous:

Button {
  Task { await model.load() }
} label:{
  Text("Async Button")
}

will succeed without warnings in Views, but not in Commands. Is this intentional? I've filed FB13212559. Thank you.

  • Thanks for filing FB13212559.

Add a Comment

Replies

I'm seeing a similar problem. Here I'm using an ObservedObject to update my app settings but get a build warning in the Command section

Main actor-isolated property 'body' cannot be used to satisfy nonisolated protocol requirement

The app seems to compile and run fine otherwise.

Feedback raised: FB13801673

struct MyCommands: Commands {
    @ObservedObject var globalAppSettings: GlobalAppSettings
    var body: some Commands {
        SidebarCommands()
        
        CommandGroup(after: CommandGroupPlacement.newItem) {
            Divider()
            Toggle("Debug Mode", isOn: $globalAppSettings.debugMode)
        }
    }
}