Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Core Data is saving to /dev/null so it is in memory only

I'm using Swift 4 and the NSPersistentContainer for a very simple data model. I have 1 entity and several attributes plus one index. When I first created this the app was saving the data in a real store. Then I added one attribute and the index and setup to migrate automatically. Now the CoreData debug output shows me: CoreData: annotation: Connecting to sqlite database file at "/dev/null" Because of this my data is not saved between sessions. Is there a way to specify the sqlite db file? Can I get back to the old file?

var dataContainer: NSPersistentContainer = {
  let container = NSPersistentContainer(name: "MyProject")
  // Auto migrate data to new version
  let description = NSPersistentStoreDescription()
  description.shouldMigrateStoreAutomatically = true
  description.shouldInferMappingModelAutomatically = true
  container.persistentStoreDescriptions = [description]

  container.loadPersistentStores(completionHandler: { (storeDescription, error) in
  if let error = error {
    let msg = "\(error)"
    os_log("dataContainer: loadPersistentStores Error = %@", msg)
  }
  })
  container.viewContext.name = "MyProject"
  return container
}()
like image 277
Nieuwsma Avatar asked Sep 20 '18 20:09

Nieuwsma


2 Answers

When you instantiate your NSPersistentStoreDescription you have the option of passing in a URL. Here's a link to the documentation, and here's a well explained post on the topic

let container = NSPersistentContainer(name: "NameOfDataModel")

let storeURL = try! FileManager
        .default
        .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        .appendingPathComponent("NameOfDataModel.sqlite")

let storeDescription = NSPersistentStoreDescription(url: storeURL)
container.persistentStoreDescriptions = [storeDescription]
like image 175
se_puede_dev Avatar answered Sep 18 '22 22:09

se_puede_dev


Since you're creating storeURL with the default DataModel name (i.e. "NameOfDataModel"), you don't need to explicitly create "NameOfDataModel.sqlite" using FileManager - as the container would, by default, be creating the same.

Hence, you can utilize that default "NameOfDataModel.sqlite" location (i.e. URL) to create the storeDescription instance, as follows:

let container = NSPersistentContainer(name: "NameOfDataModel")

if let storeURL = container.persistentStoreDescriptions.last?.url
{
    let storeDescription = NSPersistentStoreDescription(url: storeURL)

    // Setting Migration Flags
    storeDescription.shouldMigrateStoreAutomatically = true 
    storeDescription.shouldInferMappingModelAutomatically = true

    container.persistentStoreDescriptions = [storeDescription]
}


PS: Since the default value for the aforementioned Migration flags/keys is true, this all might just be overkill.

Documentation:
shouldInferMappingModelAutomatically
shouldMigrateStoreAutomatically

like image 45
N a y y a r Avatar answered Sep 17 '22 22:09

N a y y a r