TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Using both dummy-data and preview-data for Core Data

Forums > SwiftUI

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.

2      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.