My goal is pre-loading Core Data, at the first app launch. So far I ran a simulation and filled Core Data with data. (I had checked "allow external Storage").
I went into application_support and copied: MyApp.sqlite-wal, MyApp.sqlite-shm, .MyApp_SUPPORT/_EXTERNAL_DATA/ and MyApp.sqlite.
Then I added the MyApp.sqlite file in my app bundle and added this code in my app delegate:
lazy var persistentContainer: NSPersistentContainer = {
let modelName = "MyApp"
var container: NSPersistentContainer!
container = NSPersistentContainer(name: modelName)
// Preloading
let appName: String = "MyApp"
var persistentStoreDescriptions: NSPersistentStoreDescription
let storeUrl = self.getDocumentsDirectory().appendingPathComponent("MyApp.sqlite")
if !FileManager.default.fileExists(atPath: (storeUrl.path)) {
let seededDataUrl = Bundle.main.url(forResource: appName, withExtension: "sqlite")
try! FileManager.default.copyItem(at: seededDataUrl!, to: storeUrl)
}
let description = NSPersistentStoreDescription()
description.shouldInferMappingModelAutomatically = true
description.shouldMigrateStoreAutomatically = true
description.url = storeUrl
container.persistentStoreDescriptions = [description]
//End Preloading
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
It works but It looks like it doesn't find the images that were saved in external storage. They're present in .MyApp_SUPPORT/_EXTERNAL_DATA as references. Where should I add the references?
Load everything is my goal.
Step 1: Create "MyAppSeedData" dir and paste MyApp.sqlite, the MyApp_SUPPORT, the MyApp.sqilte-smh, MyApp.sqilte-wal files inside.
Step 2: Drag MyAppSeedData to the bundle under AppDelegate and tick the box add target.
Step 3: These functions must be in AppDelegate file:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
//If first launch condition == true {
seedData()
//}
return true
}
func seedData() {
let fm = FileManager.default
//Destination URL: Application Folder
let libURL = fm.urls(for: .libraryDirectory, in: .userDomainMask).first!
let destFolder = libURL.appendingPathComponent("Application Support").path
//Or
//let l1 = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).last!
//
//Starting URL: MyAppSeedData dir
let folderPath = Bundle.main.resourceURL!.appendingPathComponent("MyAppSeedData").path
let fileManager = FileManager.default
let urls = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask)
if let applicationSupportURL = urls.last {
do{
try fileManager.createDirectory(at: applicationSupportURL, withIntermediateDirectories: true, attributes: nil)
}
catch{
print(error)
}
}
copyFiles(pathFromBundle: folderPath, pathDestDocs: destFolder)
}
func copyFiles(pathFromBundle : String, pathDestDocs: String) {
let fm = FileManager.default
do {
let filelist = try fm.contentsOfDirectory(atPath: pathFromBundle)
let fileDestList = try fm.contentsOfDirectory(atPath: pathDestDocs)
for filename in fileDestList {
try FileManager.default.removeItem(atPath: "\(pathDestDocs)/\(filename)")
}
for filename in filelist {
try? fm.copyItem(atPath: "\(pathFromBundle)/\(filename)", toPath: "\(pathDestDocs)/\(filename)")
}
} catch {
print("Error info: \(error)")
}
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let modelName = "MyApp"
var container: NSPersistentContainer!
container = NSPersistentContainer(name: modelName)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()