Skip to content

fatbobman/CoreDataEvolution

Repository files navigation

CoreDataEvolution

CoreDataEvolution brings actor isolation, Swift-first NSManagedObject declarations, typed paths, runtime schema metadata, and model tooling to Core Data.

Swift Platforms License DeepWiki

English | 中文

Motivation

Core Data remains a pragmatic foundation for apps that depend on its mature object graph, migration, and store behavior, but its default source and concurrency patterns can feel distant from modern Swift. Projects often accumulate hand-written accessors, string-based query keys, context-passing conventions, and schema-to-source drift.

CoreDataEvolution keeps Core Data as the persistence engine while making its Swift surface more explicit and toolable. It combines actor-isolated access, macro-based NSManagedObject declarations, typed mapping, optional Observation support, and a CLI that can compare source declarations with the real model.

Related reading: Why I'm Still Thinking About Core Data in 2026

Features

  • Isolate background work with @NSModelActor, or bind UI-facing orchestration to viewContext with @NSMainModelActor.
  • Declare Core Data entities in Swift with @PersistentModel, plus explicit attribute, relationship, composition, and storage metadata.
  • Generate typed keys and paths for sort descriptors and %K-based predicates, including renamed fields and relationship paths.
  • Opt generated accessors into MainActor Observation on supported Swift and OS versions.
  • Build runtime schemas and isolated SQLite containers for test and debug workflows without replacing production .xcdatamodeld files.
  • Use cde-tool to generate declarations, validate model/source alignment, inspect models, and bootstrap configuration.

Quick Start

Add CoreDataEvolution to your package with Swift Package Manager:

dependencies: [
  .package(
    url: "https://github.com/fatbobman/CoreDataEvolution.git",
    from: "0.9.3"
  )
],
targets: [
  .target(
    name: "YourTarget",
    dependencies: [
      .product(name: "CoreDataEvolution", package: "CoreDataEvolution")
    ]
  )
]

The following executable example declares one entity, creates a test/debug runtime model, and saves through a MainActor-isolated viewContext:

import CoreDataEvolution
import Foundation

@objc(Item)
@PersistentModel
final class Item: NSManagedObject {
  var title: String = ""
}

@MainActor
@NSMainModelActor
final class ItemStore {
  func createItem(title: String) throws {
    let item = Item(context: modelContext)
    item.title = title
    try modelContext.save()
  }
}

@main
struct Example {
  @MainActor
  static func main() throws {
    let container = try NSPersistentContainer.makeRuntimeTest(modelTypes: Item.self)
    let store = ItemStore(modelContainer: container)
    try store.createItem(title: "Hello, Core Data")
  }
}

makeRuntimeTest is intentionally limited to tests and debugging. Production apps should keep a matching Core Data model and pass their loaded NSPersistentContainer to an @NSModelActor or @NSMainModelActor type.

Where to Read Next

Requirements

  • MainActor Observation requires a Swift 6.2+ compiler and iOS 17+, macOS 14+, tvOS 17+, watchOS 10+, or visionOS 1+.
  • Core Data composite attributes require iOS 17+, macOS 14+, tvOS 17+, watchOS 10+, or visionOS 1+.

Contributing & Testing

Read CONTRIBUTING.md before opening an issue or pull request. Start local validation with swift build and bash Scripts/run-tests.sh; report security-sensitive issues through SECURITY.md.

License

CoreDataEvolution is available under the MIT license. See the LICENSE file for more information.

Author

Fatbobman (肘子) — Blog: fatbobman.com · X: @fatbobman

Support

If this project helps you, please consider supporting my work:

About

SwiftData-style actor isolation, Swift-first NSManagedObject macros, and typed mapping for modern Core Data projects.

Topics

Resources

License

Contributing

Security policy

Stars

131 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors