Sometimes unpredictably within an async .task{}
an NSManagedObject
has faulted, and is not unfaulted when the object’s members are referenced. How can I figure out why it has faulted, or prevent it from faulting, or forcibly unfault it? Thank you
This example uses a Core Data store named “TestCoreDataTask” that has a single “Item” entity with a single “timestamp” attribute of type “Date”. To reproduce the issue 1) tap the Add button, 2) wait 5 seconds, 3) sometimes a faulted Item
is printed in the log.
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(.managedObjectContext) private var viewContext
@State var sheetData : SheetData?
var body: some View {
NavigationView {
Text("Add")
.onTapGesture {
let item = Item(context: viewContext)
item.timestamp = Date()
try? viewContext.save()
sheetData = SheetData(item: item)
}
}
.overlay(
EmptyView()
.fullScreenCover(item: $sheetData) { sheet in
Sheet(sheetData: $sheetData)
}
)
}
}
struct SheetData: Identifiable {
let id = UUID().uuidString
let item : Item?
}
struct Sheet: View {
@Binding var sheetData : SheetData?
@Environment(.dismiss) var dismiss
var body: some View {
Text("(sheetData?.item?.timestamp ?? Date())")
.task { @MainActor in
do {
try await Task.sleep(for: .seconds(5))
print("Sheet (sheetData?.item?.timestamp)") // sometimes this is a fault!
} catch is CancellationError {
print("Task was cancelled")
} catch {
print("error: (error)")
}
}
.onTapGesture { dismiss() }
}
}
@main
struct TestCoreDataTaskApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(.managedObjectContext, persistenceController.container.viewContext)
}
}
}
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init() {
container = NSPersistentContainer(name: "TestCoreDataTask")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error (error), (error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
}