Skip to content

0.9.0

Choose a tag to compare

@fatbobman fatbobman released this 01 Jun 05:54
· 2 commits to main since this release

What's Changed

CoreDataEvolution 0.9.0 adds opt-in MainActor Swift Observation for generated Core Data models.

  • Add @PersistentModel(observation: .mainActor) for iOS 17+ / macOS 14+ platform families.
  • Add CDEObservationDomain, a retained container-bound runtime that activates observation routing for container.viewContext.
  • Let SwiftUI and withObservationTracking read CoreDataEvolution-generated Core Data accessors directly, including relationship chains, without forcing extra ObservableObject projection layers into view structure.
  • Route saved changes with property-level precision when the producer can provide changed Core Data keys.
  • Support precise routes for plain viewContext.save(), NSModelActor.saveObservedChanges(in:), NSMainModelActor.saveObservedChanges(in:), registered ordinary background contexts, and wrapper-owned context saves.
  • Add lifecycle and fallback handling for rollback, refresh, reset, delete, temporary object ID rekeying, batch operations, unregistered contexts, and objectID-only merges.
  • Preserve precise local/background routes across store re-merges with CDEPreciseRouteEchoSuppression, including the common NSPersistentCloudKitContainer / Persistent History Tracking echo.
  • Add CDE_OBSERVATION_DEBUG and CDEObservationDomain.isDebugLoggingEnabled for opt-in unified logging diagnostics.
  • Add the public Docs/ObservationGuide.md, update README and DocC, and keep internal mechanism / implementation documents under Docs/Development.

Public API Highlights

  • PersistentModelObservationMode.mainActor
  • CDEObservationDomain(container:preciseRouteEchoSuppression:)
  • CDEObservationDomain.registerChangeProducer(context:)
  • CDEObservationDomain.newObservedBackgroundContext()
  • CDEObservationDomain.saveObservedChanges(in:)
  • CDEObservationDomain.rollbackObservedChanges()
  • CDEPreciseRouteEchoSuppression
  • NSModelActor.saveObservedChanges(in:)
  • NSMainModelActor.saveObservedChanges(in:)

Behavior Notes

  • Observation is opt-in. Plain @PersistentModel and explicit observation: .none keep the non-observable generated output.
  • Only CoreDataEvolution-generated accessors participate in observation. Raw @NSManaged properties and custom getters that bypass generated accessors are not observable.
  • Refresh is save-gated: generated setters write Core Data values, while SwiftUI refresh happens after save, merge, or lifecycle fallback.
  • Unregistered contexts, batch operations, and external CloudKit imports fall back to objectID / all-observable-key-path invalidation when changed-key metadata is unavailable.
  • Field-level precision is useful, but the main goal is cognitive clarity: SwiftUI can stay close to the persisted Core Data object graph, especially in relationship-heavy screens.

Validation

  • bash Scripts/run-tests.sh passed with com.apple.CoreData.ConcurrencyDebug=1 enabled: 334 tests / 44 suites.
  • bash Scripts/test-generated-flow.sh passed: generated source unchanged, conformance and exact validation both reported 0 errors / 0 warnings, and the external generated-flow fixture built and ran successfully.