Skip to content

Introduce persistence framework abstraction layer - #271

Open
danielbarela wants to merge 1 commit into
ngageoint:developfrom
danielbarela:persistence-merge
Open

Introduce persistence framework abstraction layer#271
danielbarela wants to merge 1 commit into
ngageoint:developfrom
danielbarela:persistence-merge

Conversation

@danielbarela

Copy link
Copy Markdown
Contributor

Introduce persistence framework abstraction layer

Summary

This change introduces the initial persistence framework required to migrate MAGE away from direct Magical Record usage while preserving existing Core Data behavior.

A new Persistence Swift package defines a persistence abstraction layer, including a PersistenceProtocol, shared persistence container, Core Data convenience extensions, and Objective-C bridging APIs. The initial implementation continues to use Magical Record internally through MagicalRecordPersistence, allowing migration to happen incrementally without requiring a full rewrite of existing persistence code.

The application startup flow has been updated to initialize the new persistence container before launching the application, and existing Core Data usage has been routed through the new persistence APIs.

What Changed

New Persistence Swift Package

Added a new Persistence package containing:

  • PersistenceProtocol

    • Defines async read/write/background persistence operations
    • Provides a future abstraction point for alternate persistence implementations
  • PersistenceContainer

    • Provides application-wide persistence dependency injection
    • Allows the underlying persistence implementation to be swapped independently of consumers
  • PersistenceResult

    • Standardizes persistence operation results and error reporting
  • Core Data utilities:

    • NSManagedObjectContext fetch helpers
    • NSManagedObject creation and lookup helpers
    • Managed object model registry

Magical Record Migration Adapter

Added MagicalRecordPersistence as the first PersistenceProtocol implementation.

This adapter:

  • Initializes the existing Magical Record stack
  • Provides async wrappers around existing Core Data operations
  • Bridges Swift concurrency APIs into the existing Objective-C application code
  • Allows existing entities to continue using Core Data while consumers migrate gradually

Objective-C Compatibility Layer

Added ObjCCoreDataPersistence to allow existing Objective-C code to interact with the new persistence abstraction.

Updated existing startup canary writes to use:

  • ObjCCoreDataPersistence.write
  • New PersistenceResult handling

instead of directly calling Magical Record APIs.

Application Initialization Changes

Updated application startup:

  • Replaced direct MagicalRecord.setupMageCoreDataStack() calls
  • Added persistence initialization through MageInitializer
  • Ensured the app starts only after persistence has been configured

Project Integration

Updated Xcode project configuration to:

  • Add the new Persistence Swift package
  • Link the package into the application target
  • Include the new Magical Record adapter

Migration Strategy

This change intentionally keeps Magical Record as the backing implementation.

Future migrations can now happen incrementally:

  1. Move consumers from Magical Record APIs to PersistenceProtocol
  2. Introduce a native NSPersistentContainer implementation
  3. Remove Magical Record dependencies once all callers have migrated

Testing

Added initial Swift Testing target for the Persistence package.

Existing application behavior remains backed by Magical Record while exercising the new persistence entry points.

Follow-up Work

Potential follow-up work:

  • Replace the shared singleton-style PersistenceContainer with the existing dependency injection system
  • Add a native NSPersistentContainer implementation
  • Expand persistence tests around read/write/background operations
  • Remove remaining direct Magical Record usage

Reviewer Notes

A few areas worth reviewing:

  • PersistenceContainer.shared is currently a singleton-style container. This is intentional for the migration phase but may eventually move into application dependency injection.
  • MagicalRecordPersistence currently owns Magical Record initialization. This keeps migration incremental but couples the adapter to the current lifecycle.
  • @unchecked Sendable is used around Core Data and Objective-C bridging. The thread-safety assumptions should remain documented as the abstraction evolves.

This sets up the persistence framework.  Still uses Magical Record to promote an incremental update.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant