Search code examples
macosswiftuinspersistentdocumentfetchrequest

NSPersistentDocument FetchRequest warp property crash on macOS Document App SwiftUI project


  1. Project create usinging Xcode macOS Document App template, with Use Core Data checkbox checked.
  2. Add a Book entity to Document.xcdatamodeld
  3. Add FetchRequest warp property to ContentView,
@FetchRequest(entity: Book.entity(), sortDescriptors: []) var books: FetchedResults<Book>
  1. Build and Run, Crash!

Crash log from console is

2020-07-03 23:12:23.597880+0800 DocMacDemo[15236:4376209] [error] error: No NSEntityDescriptions in any model claim the NSManagedObject subclass 'DocMacDemo.Book' so +entity is confused.  Have you loaded your NSManagedObjectModel yet ?
CoreData: error: No NSEntityDescriptions in any model claim the NSManagedObject subclass 'DocMacDemo.Book' so +entity is confused.  Have you loaded your NSManagedObjectModel yet ?
2020-07-03 23:12:23.598287+0800 DocMacDemo[15236:4376209] [error] error: +[DocMacDemo.Book entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
CoreData: error: +[DocMacDemo.Book entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
2020-07-03 23:12:23.644491+0800 DocMacDemo[15236:4376209] executeFetchRequest:error: A fetch request must have an entity.
2020-07-03 23:12:23.653769+0800 DocMacDemo[15236:4376209] [error] error: The fetch request's entity 0x600003500420 'Book' appears to be from a different NSManagedObjectModel than this context's
CoreData: error: The fetch request's entity 0x600003500420 'Book' appears to be from a different NSManagedObjectModel than this context's
(lldb)

I have looking for NSPersistentDocument SwiftUI example several days, but could NOT find one. Here are some similar or relation questions. Unfortunately, this problem is not solved.

EDIT: Upload this issue project to Github, https://github.com/donly/DocMacDemo.


Solution

  • This is due to emptiness of new document. As in any document-based application you have to prepare some default initial data for new document

    Here is possible solution. Tested with Xcode 11.4 / iOS 13.4

    in Document.swift

    class Document: NSPersistentDocument {
    
        // .. other code here
    
        override func makeWindowControllers() {
    
            // in case of new document create new empty book in context
            // that will be shown in opened document window
            let isNew = self.fileURL == nil
            if isNew {
                _ = Book(context: self.managedObjectContext!)       // << here !!
            }
    
            let contentView = ContentView().environment(\.managedObjectContext, self.managedObjectContext!)
    
            // ... other code here