Using an Existing SQLite Store with NSPersistentContainer

If you’ve been creating the Core Data Stack without NSPersistentContainer and you’re thinking about switching things up to use NSPersistentContainer, you need to think about your existing SQLite persistent store.

Creating the stack with NSPersistentContainer handles the creation of SQLite stores internally, so brand new setups using NSPersistentContainer are pretty easy.

But how do you go about telling NSPersistentContainer about your existing SQLite store?

Let’s take a look now at how you can configure the container to use your previously-created persistent store.

Before NSPersistentContainer

Supposing that your previous Core Data stack creation step pointed to a .sqlite file somewhere in your user’s documents directory:

1// Configure NSPersistentStoreCoordinator with an NSPersistentStore
2let psc = NSPersistentStoreCoordinator(managedObjectModel: model) // model instance creation not shown here...
4let storeURL = try! FileManager
5        .default
6        .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
7        .appendingPathComponent("NameOfDataModel.sqlite")
9try! psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)

After NSPersistentContainer

The key to migrating to NSPersistentStore with an existing SQLite persistent store is the NSPersistentStoreDescription class. Take a look at the following code to see how to configure an instance of NSPersistentStoreDescription and assign it to the NSPersistentContainer instance’s persistentStoreDescriptions property:

 1let container = NSPersistentContainer(name: "NameOfDataModel")
 3let storeURL = try! FileManager
 4        .default
 5        .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
 6        .appendingPathComponent("NameOfDataModel.sqlite")
 8let storeDescription = NSPersistentStoreDescription(url: storeURL)
 9container.persistentStoreDescriptions = [storeDescription]
11// Remaining setup for NSPersistentContainer

Breaking it down

The let storeURL = portion of the code is identical in both snippets.

The difference is how you tell the Stack where the persistent store is located. In times past, you’d tell the NSPersistentStoreCoordinator this information through its addPersistentStore method.

With NSPersistentContainer, you need to do two things:
1 – Initialize an NSPersistentStoreDescription instance with the storeURL (i.e. the URL to where your existing persistent store is located).

2 – Assign the NSPersistentStoreDescription instance to the NSPersistentContainer's persistentStoreDescriptions property.

One subtlety to note is that the property’s name is plural: persistentStoreDescriptions.

Even though may only a single persistent store description instance to assign, such as in the example code above, you still need to wrap it in an array before you assign it, since it’s possible to add more than one description to the container.

With that adjustment to the NSPersistentContainer stack creation process, your app will once again use the persistent store it used to use!

comments powered by Disqus