ManagedModels for CoreData
Instead of wrapping CoreData, use it directly :-)
The key thing ManagedModels provides is a @Model
macro,
that works similar (but not identical) to the SwiftData
[@Model
](https://developer.apple.com/documentation/swiftdata/model())
macro.
It generates an
NSManagedObjectModel
straight from the code. I.e. no CoreData modeler / data model file is necessary.
A small sample model:
@Model class Item: NSManagedObject {
var timestamp : Date
var title : String?
}
The full CoreData template application converted to ManagedModels
```swift
import SwiftUI
import ManagedModels
@Model class Item: NSManagedObject {
var timestamp : Date
}
struct ContentView: View {
@Environment(\.modelContext) private var viewContext
@FetchRequest(sort: \.timestamp, animation: .default)
private var items: FetchedResults-
var body: some View {
NavigationView {
List {
ForEach(items) { item in
NavigationLink {
Text("Item at \(item.timestamp!, format: .dateTime)")
} label: {
Text("\(item.timestamp!, format: .dateTime)")
}
}
.onDelete(perform: deleteItems)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
Text("Select an item")
}
}
private func addItem() {
withAnimation {
let newItem = Item(context: viewContext)
newItem.timestamp = Date()
try! viewContext.save()
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
offsets.map { items[$0] }.forEach(viewContext.delete)
try! viewContext.save()
}
}
}
#Preview {
ContentView()
.modelContainer(for: Item.self, inMemory: true)
}
```
This is not intended as a replacement implementation of
SwiftData.
I.e. the API is kept similar to SwiftData, but not exactly the same.
It doesn't try to hide CoreData, but rather provides utilities to work with
CoreData in a similar way to SwiftData.
A full To-Do list application example:
ManagedToDos.app.
Blog article describing the thing: @Model
for CoreData.
Requirements
The macro implementation requires Xcode 15/Swift 5.9 for compilation.
The generated code itself though should backport way back to
iOS 10 / macOS 10.12 though (when NSPersistentContainer
was introduced).
Package URL:
https://github.com/Data-swift/ManagedModels.git
ManagedModels has no other dependencies.
Differences to SwiftData
- The model class must explicitly inherit from
NSManagedObject
(superclasses can't be added by macros),
e.g. @Model class Person: NSManagedObject
.
- Uses the CoreData
@FetchRequest
property wrapper instead @Query
.
- Doesn't use the new
Observation
framework (which requires iOS 17+), but uses
ObservableObject
(which is directly supported by CoreData).
TODO
- [ ] Figure out whether we can do ordered attributes: Issue #1.
- [ ] Support for "autosave": Issue #3
- [ ] Support transformable types, not sure they work right yet: Issue #4
- [ ] Generate property initializers if the user didn't specify any inits: Issue #5
- [ ] Support SchemaMigrationPlan/MigrationStage: Issue #6
- [ ] Write more tests.
- [ ] Write DocC docs: Issue #7, Issue #8
- [ ] Support for entity inheritance: Issue #9
- [ ] Add support for originalName/versionHash in
@Model
: Issue 10
- [ ] Generate "To Many" accessor function prototypes (
addItemToGroup
etc): Issue 11
- [x] Foundation Predicate support (would require iOS 17+) - this seems actually supported by CoreData!
- [ ] SwiftUI
@Query
property wrapper/macro?: Issue 12
- [ ] Figure out all the cloud sync options SwiftData has and whether CoreData
can do them: Issue 13
- [x] Archiving/Unarchiving, required for migration.
- [x] Figure out whether we can add support for array toMany properties: Issue #2
- [x] Generate
fetchRequest()
class function.
- [x] Figure out whether we can allow initialized properties
(
var title = "No Title"
): Issue 14
Pull requests are very welcome!
Even just DocC documentation or more tests would be welcome contributions.
Links
Disclaimer
SwiftData and SwiftUI are trademarks owned by Apple Inc. Software maintained as
a part of the this project is not affiliated with Apple Inc.
Who
ManagedModels are brought to you by
Helge Heß / ZeeZide.
We like feedback, GitHub stars, cool contract work,
presumably any form of praise you can think of.