2

I try to do some SwiftData work on the background thread using the next code, while I set "Strict Concurrency Check" to "Complete", I get a warning message. the "List Item" is a SwiftData model. the code:

@ModelActor
actor DataModelActor {
    
    func configureNewListItem() -> ListItem {
        let newListItem = ListItem(index: 0, pinIndex: 0)
        modelContext.autosaveEnabled = false
        modelContext.insert(newListItem)
        return newListItem
    }
}

The warring message:

enter image description here

I get "modelContext" from:

@Environment(\.modelContext) private var modelContext

How can fix the warning message (I don't want to ignore it) or is there another way to use SwiftData by avoiding the main thread? Please.

1
  • You cannot use managed objects from any other thread (or dispatch queue) than where its context is associated with. Form a design perspective, if you want to utilise Swift concurrency, it's probably best to have CoreData solely work within its confined thread and provide an API on top of it where you "exchange" sendable objects which represent the CoreData Managed objects or provide higher level functionality. So, this "Data Provider API" has async functions which receive or return sendable objects - which are not managed objects, but the API implementation can map it to managed objects. Commented Apr 26, 2024 at 7:47

1 Answer 1

1

@Model classes doesn’t conform to Sendable so you can’t pass them over actor boundaries. But the identifier for them do conform to Sendable so you can pass the id of the object.

func configureNewListItem() -> ListItem.ID { // or -> PersistentIdentifier
    let newListItem = ListItem(index: 0, pinIndex: 0)
    modelContext.autosaveEnabled = false
    modelContext.insert(newListItem)
    try? modelContext.save()
    return newListItem.id
}

Then you load the object in your other code using the id.

let newId = await.actor.configureNewListItem()
let new = modelContext.model(for: newId) as? ListItem
Sign up to request clarification or add additional context in comments.

7 Comments

I get the warning message "Capture of 'self' with non-sendable type 'ContentView' in a @Sendable closure" & "Consider making struct 'ContentView' conform to the 'Sendable' protocol" when use "let new = modelContext.model(for: newId) as? ListItem"
Maybe not using Task.detached but a .task modifier instead? I don't have time to look into this right now but are you sure it's relevant to the question?
Yes I sure from that.
And I am pretty sure it isn’t but try loading the object using model(for:) outside the Task closure instead.
Your issue is not directly relevant to the question but since you are using Task.detached then you can't use the views modelContext inside the closure so add let modelContext = ModelContext(container) inside the closure to fix the warning.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.