I offer the option for my app users to add some sample data to the app, in order not to see an empty view at first launch. To do so, I call a method inside a specific struct:
struct SampleData {
public func addSampleData(context: NSManagedObjectContext) {
let sampleItem1 = Item(context: context)
sampleItem1.id = UUID()
//many more properties and items here...
try? context.save()
}
}
That's one usage of this struct: to populate persistent Core Data.
On the other side, on my DataController class, a make a call to to this method too, but in this case in order for my Previews to have data to be displayed. This is why I use a "context" argument for the "addSampleData" call: for "preview" content, I try to use a in-Memory not persisting instance of DataController container, while on "ordinary" (not in-Memory) common use, I try to persist data. Here my planned DataController class to do so:
final class DataController: ObservableObject {
static let shared = DataController()
//For previews...
static var preview: DataController = {
let result = DataController(inMemory: true)
let viewContext = result.container.viewContext
let sampleData = SampleData()
sampleData.addSampleData(context: viewContext)
do {
try viewContext.save()
} catch {
//Error handling
}
return result
}()
let container = NSPersistentCloudKitContainer(name: "MyModel")
init(inMemory: Bool = false) {
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores { description, error in
//Error handling
}
self.container.viewContext.automaticallyMergesChangesFromParent = true
self.container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
}
}
}
For my" Item" object I use an extension to fetch request one of this "sample-not persisted" items, for previews:
extension Item {
static var sample: Item {
let context = DataController.preview.container.viewContext
let fetchRequest: NSFetchRequest<Item> = Item.fetchRequest()
fetchRequest.fetchLimit = 1
let results = try? context.fetch(fetchRequest)
return (results?.first!)!
}
}
Both previews for me as developer, and sample data import for app users, work perfectly, independently. But the problem now is that if I display a preview while using XCode, data are added AGAIN to the persistent store, resulting in a increasing amount of persisted data, each time I open ANY preview of the app.
I've cheked lots of tutorials and posts about this kind of Core Data preview usage, and I think that there is something in my code which is making this "copying" of planned-in-memory-sample-data to the persistent-data.
What am I doing wrong? Any suggestions? Thank you very much.