Does SwiftData have a context.perform {} method?

Does SwiftData have a method like CoreData's context.perform {} context.performAndWait {}? I execute it in an asynchronous thread, context.insert(userBook), and get an error message

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'user' between objects in different contexts (source = <NSManagedObject: 0x6000021f1400> (entity: UserBookEntity; id: 0x6000003366e0 <x-coredata:///UserBookEntity/tEB7 59DFB-A4B1-4216-9138 -809BAB786A5920>;

I define a base Repo

struct BaseRepo {
    static let shared = BaseRepo()
    var container: ModelContainer?
    var context: ModelContext?

    let fullModelList: [any PersistentModel.Type] =  [
        DomainDict.self,
        User.self,
        UserBookEntity.self,
        Book.self,
        Category.self
    ]

    init() {
        do{
            container = try ModelContainer(for: fullModelList)
            if let container {
                context = ModelContext(container)
            }
        }
        catch{
            print(error)
        }
    }
}

then I save data ,but get an error,It shows that I am not in the same context, but I pass in the same context

    func saveBookData(bookData: FetchBookData,uid: String) -> Future<Void, Error> {
        return Future { promise in
            
            guard let context = BaseRepo.shared.context,
                  let bookListResp = bookData.bookList,
                  let user = UserSvc.shared.findUserByUid(context: context, uid: uid) else {
                return
            }
            BookSvc.shared.saveBookData(context: context, user: user, bookListResp: bookListResp)
            
            promise(.success(()))
        }
    }
func saveBookData(context: ModelContext, user: User,bookListResp: BookListResp) {
    let bookRoleDtoList = bookListResp.content
    let date = Date()
    bookRoleDtoList.forEach { bookRoleDto in
        let userBook = UserBookEntity(
            id: UUID(),
            user: user)
        userBook.book = book
        context.insert(userBook)
    }
}
Answered by milutz in 758297022

I think you are running into the sam issues I have over here. The gist of it is, that currently to-one relationships can only be populated after the entity is initially inserted into the context. Which also means they must be optional, which is unfortunate from a modelling perspective. I filed FB12363892 for that.

Accepted Answer

I think you are running into the sam issues I have over here. The gist of it is, that currently to-one relationships can only be populated after the entity is initially inserted into the context. Which also means they must be optional, which is unfortunate from a modelling perspective. I filed FB12363892 for that.

It is indeed caused by this problem. I changed the relationship to optional and it can be saved, but I think this is a problem with Apple, because semantically, I need the relationship not to be optional.

Does SwiftData have a context.perform {} method?
 
 
Q