3

Xcode's preview canvas keeps on crashing with no error message when I try to pass in a preview Core Data object like so:

import SwiftUI
import CoreData

struct BookView: View {
    let book: Book
    
    var body: some View {
        Text("Hello, World!")
    }
}

// ^^^ This stuff is fine ^^^

// vvv This stuff is not vvv

struct BookView_Previews: PreviewProvider {
    static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    
    static var previews: some View {
        let book = Book(context: moc)
        book.title = "Test book"
        book.author = "Test author"
        book.genre = "Fantasy"
        book.rating = 4
        book.review = "This was a great book; I really enjoyed it."
        
        return NavigationView {
            BookView(book: book)
        }
    }
}

I'm following a Hacking with Swift tutorial on Core Data and SwiftUI and am at this step.

This appears to be the standard way to add preview objects into the SwiftUI canvas, but I'm unable to get it to work. FYI the app runs fine in the simulator, I'm just trying to get it to also work in the preview canvas. I'm using Xcode 13.2.1 on macOS 12.

Thank you!

Microbob
  • 672
  • 5
  • 20
  • @JoakimDanielson This is a paired-down version of the full code where I do access the attributes of the object. The view is fine, it's launching the preview that doesn't work. – Microbob Dec 25 '21 at 20:17

1 Answers1

4

Instead of creating a NSManagedObjectContext use

static let context = PersistenceController.preview.container.viewContext

That variable is provided in the standard Xcode project with Core Data.

Also, if you have been using the real store for preview it might be corrupted somehow so you might have to destroy.

Add the code below

    do{
        try container.persistentStoreCoordinator.destroyPersistentStore(at: container.persistentStoreDescriptions.first!.url!, type: .sqlite, options: nil)
    }catch{
        print(error)
    }

Right under

container = NSPersistentCloudKitContainer(name: "YourAppName")

Before you load the store.

This destroys the store and then it gets recreated when you call loadPersistentStores be sure to remove that piece of code after you clear the preview device so you don't accidentally destroy another store you don't mean to destroy.

lorem ipsum
  • 21,175
  • 5
  • 24
  • 48
  • Thanks for the solution! That's so strange that this works but the whole `NSManagedObjectContext` thing doesn't. Is that function deprecated? – Microbob Dec 25 '21 at 20:24
  • @Microbob I've never really used that other way. It seems unnecessary, You would have to check the diagnostics button that appears in the canvas to try and figure out why it was crashing. I don't think it is deprecated. – lorem ipsum Dec 25 '21 at 20:30
  • It says it expected declaration i tried to put it here in my persistence.swift file – arman Feb 17 '22 at 00:02
  • so i was able to destroy the store however when i close the app and try to create a new one the codes never goes away it still produce the same codes it was before – arman Feb 17 '22 at 00:36