I have two read-only databases that I update occasionally during new app releases. Rather that do some type of version control updating of the sqlite by copying it from the app bundle to the app documents directory I would like to simply point the persistent container to the app bundle and read it. This works fine for one database but not for the other and I can't figure out why. (FYI both work in simulator, but one crashes on device)
I use identical persistent container code, the one that does not crash is like this:
lazy var strengthPersistentContainer: NSPersistentContainer =
{
let container = NSPersistentContainer(name: "Favs")
let sqlFileName: String = kStrengthShortFileName
let sqlFileExtension: String = "sqlite"
let fileUrl: URL = Bundle.main.url(forResource: sqlFileName, withExtension: sqlFileExtension)!
let description = NSPersistentStoreDescription(url: fileUrl)
description.isReadOnly = true
container.persistentStoreDescriptions = [description]
container.loadPersistentStores
{
_, error in
if let error = error as NSError?
{
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
return container
}()
The one that crashes, is the same:
lazy var everKeneticPersistentContainer: NSPersistentContainer =
{
let container = NSPersistentContainer(name: "EverKenetic")
let sqlFileName: String = kEverKineticFileName
let sqlFileExtension: String = "sqlite"
let fileUrl: URL = Bundle.main.url(forResource: sqlFileName, withExtension: sqlFileExtension)!
let description = NSPersistentStoreDescription(url: fileUrl)
description.isReadOnly = true
container.persistentStoreDescriptions = [description]
container.loadPersistentStores
{
_, error in
if let error = error as NSError?
{
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
return container
}()
The main difference is I am using a singleton and a simple context fetch that crashes whereas the other uses a FetchedResultsController fetch which works fine.
Here is the singleton code that crashes:
class EverKenetic: NSObject
{
private static var manager: EverKenetic = EverKenetic()
var everKineticContext: NSManagedObjectContext?
override init()
{
if let appDelegate = UIApplication.shared.delegate as? AppDelegate
{
let theContext = appDelegate.everKeneticPersistentContainer.viewContext
everKineticContext = theContext
}
}
class func exerciseInfo(_ everKeneticName: String) -> EverKeneticExercise!
{
let fetchRequest: NSFetchRequest<EverKeneticExercise> = EverKeneticExercise.fetchRequest()
if let context: NSManagedObjectContext = manager.everKineticContext
{
let entity = NSEntityDescription.entity(forEntityName: "EverKeneticExercise", in: context)
fetchRequest.entity = entity
fetchRequest.fetchBatchSize = 2
let predicate: NSPredicate = NSPredicate(format: "name = %@", everKeneticName)
fetchRequest.predicate = predicate
let sortDescriptorRoutine = NSSortDescriptor(key: "name", ascending: false)
let sortDescriptors = [sortDescriptorRoutine]
fetchRequest.sortDescriptors = sortDescriptors
fetchRequest.returnsObjectsAsFaults = false
var fetch: [EverKeneticExercise]?
do
{
///////////// CRASHES HERE /////////////////
fetch = try context.fetch(fetchRequest)
}
catch _ as NSError
{
fetch = nil
}
if let result = fetch
{
if !result.isEmpty
{
return result[0]
}
}
}
return nil
}
It crashes with: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Can't create support directory (can't create directory)' terminating with uncaught exception of type NSException
It's really hard to find code examples for how to do read-only app bundle databases. I would appreciate any help or direction.