I read Matt's post yesterday night. I completely agree and recommend isolating Model to a separate Module. I am working on a Task Management app "for me" using SwiftUI and CoreData. Its not big but I realized I hadn't isolated my models. Its cheap to sell good advice, hard to do. I set to move all model to Swift pacakage yesterday late night, then fixed 200+ errors, spent more hours on fixing CoreData model errors. Today, I got the app working as it was again and want to share what special things to take care for CoreData models.
Im working on app for Mac (primary) and iPad/iPhone (on the go work). Everything has to sync. For free. CoreData with CloudKit Mirroring provides this feature (with upto a minute of delay sync, which is fine for tasks). I did consider using JSON model as backing data but the trouble of self hosting, finding a platform to sync. Too much. CloudKit works fine and backed by Apple. (I spent a lot trying to get it working last year.)
Lets move CoreData models to SPM module.
CoreData model in Swift Package
- First off; move the xcdatamodeld to the new SPM Module. Please go through Matts blog if you want specifics on setting up the SPM Module. Mine looks like this. Note; All manually generated NSManagedObjects files are in CoreData directory.
2. Next up: CoreData NSManagedObject needs to find the associated classs (the one inside CoreData directory) for entity. It uses Module to look up classes. I tried with both `Current Product` and `Universal Namespace` but none worked. I added the Module Name explicitly (in this example FocusModel) and this worked.
3. Now we need to tell SPM to copy the xcdatamodeld file, as is, as resource when embedded to executable/app. We do this by instrcuting SPM to copy the file as is. This way we can refer to this using `Bundle.module` (not `Bundle.main`)
4. I'm using the modified CoreDataStack file showcased by Apple (Will update with link when I find) but the idea is this file loads the stack.
- Note CoreDataStack (loader) is also inside the Model Module.
- And we are using Bundle.module to refer to the SPM copied resource locaation.
5. That should be it. Embed the model. Enjoy