@ModelActor with default actor isolation = MainActor

If I set my build settings "default actor isolation" to MainActor, how do my @ModelActor actors and model classes need to look like ?

For now, I am creating instances of my @ModelActor actors and passing my modelContext container and processing all data there. Everything stays in this context. No models are transferred back to MainActor.

Now, after changing my project settings, I am getting a huge amount of warnings.

Do I need to set all my model classes to non-isolated and the @ModelActor actor as well?

Is there any new sample code to cover this topic ... did not find anything for now.

Thanks in advance, Marc

Answered by DTS Engineer in 844021022

If you set the Default Actor Isolation to MainActor, which is the default value of a new project after Swift 6.2, the compiler will assume that your code runs on the main actor, unless you say otherwise.

In the case you described, where your SwiftData models can run in a model actor (@ModelActor), you should explicitly annotate the model classes with nonisolated, as shown below:

@Model nonisolated class MyCoolModel {
    var timestamp: Date
    ...
}

A model actor is an actor that has its own model context, and so you can use it as a normal actor, and mark its functions with nonisolated, if needed:

@ModelActor actor MyTestModelActor {
    func updateTimestamp(identifier: PersistentIdentifier) throws {
        guard let model = modelContext.model(for: identifier) as? MyCoolModel else {
            return
        }
        model.timestamp = Date()
        try modelContext.save()
    }
    
    nonisolated func doSomethingNonisolated(...) {...}
}

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

If you set the Default Actor Isolation to MainActor, which is the default value of a new project after Swift 6.2, the compiler will assume that your code runs on the main actor, unless you say otherwise.

In the case you described, where your SwiftData models can run in a model actor (@ModelActor), you should explicitly annotate the model classes with nonisolated, as shown below:

@Model nonisolated class MyCoolModel {
    var timestamp: Date
    ...
}

A model actor is an actor that has its own model context, and so you can use it as a normal actor, and mark its functions with nonisolated, if needed:

@ModelActor actor MyTestModelActor {
    func updateTimestamp(identifier: PersistentIdentifier) throws {
        guard let model = modelContext.model(for: identifier) as? MyCoolModel else {
            return
        }
        model.timestamp = Date()
        try modelContext.save()
    }
    
    nonisolated func doSomethingNonisolated(...) {...}
}

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thanks a bunch for the help! After following your advice and switching to Swift 6, all the warnings disappeared and everything is working like a charm.

@ModelActor with default actor isolation = MainActor
 
 
Q