Reputation: 1878
When I include a SQLite file with Objective-C under "Target - Build Phases - Copy Bundle Resources", this file will be completely copied to the target, i.e. device or simulator. On the target, I get the whole file: tables and contents (Records/rows).
Doing the same with Swift, the tables will be copied, but they are empty: no records/rows. :-(
Can I do something additional? Is there any "trick"?
How can I preload my core data with base-records using Swift???
I'm using Xcode v6.1.1, with Beta 6.2 it is the same.
Upvotes: 2
Views: 1281
Reputation: 4986
I had a related issue related to this. I started working on some tutorials which used this line:
documentsURL.URLByAppendingPathComponent("StoreName")
At some point this stopped working. Data was not being written to the store anymore. To see why data was not being written, I tried opening the sqlite file but could not find it on my mac at the URL being used. The app folder was there, but there was no sqlite file. I looked back at older core data projects and found they used .sqlite extension. So I modified the line to:
documentsURL.URLByAppendingPathComponent("StoreName.sqlite")
This seemed to work so give it a try.
Upvotes: 0
Reputation: 1878
This is my solution (for sqlite-files). I don't know why it is so "extravagant" in Swift. Perhaps there's an easier way? Many THX to pbasdf!!!
Important: beneath the *.sqlite-file you must add the *.sqlite-shm and the *.sqlite-wal to your project This files will automatically be added to "Target - Build Phases - Copy Bundle Resources"
This is based on the Standard-Template for the "AppDelegate.swift"…
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let dataName = „MyData.sqlite" // must be replaced by the name of your file!
let modelName = „MyData“ // must be replaced by the name of your model!
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent(dataName)
let fileManager = NSFileManager.defaultManager()
let bundle = NSBundle.mainBundle()
let fromURL = bundle.URLForResource(modelName, withExtension: "sqlite")
// check sqlite-file: must it be installed?
if !fileManager.fileExistsAtPath(url.path!) {
self.copySqlliteFiles(modelName, databaseName: dataName)
}
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil, error: &error) == nil {
...}
return coordinator
}()
// MARK: - copy sqllite-files (c) by Ray Wenderlich & Team in „“Core Data by Tutorials“
// check sqlite-files: they must be installed...
func copySqlliteFiles(modelName: String, databaseName: String)
{
let bundle = NSBundle.mainBundle()
let baseDatabaseURL = bundle.URLForResource(modelName, withExtension: "sqlite")
let documentsURL = self.applicationDocumentsDirectory
let storeURL = documentsURL.URLByAppendingPathComponent(databaseName)
NSFileManager.defaultManager().copyItemAtURL(baseDatabaseURL!, toURL: storeURL,error: nil)
let baseSHMURL = bundle.URLForResource(modelName,withExtension: "sqlite-shm")
let shmURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent(databaseName + "-shm")
NSFileManager.defaultManager().copyItemAtURL(baseSHMURL!, toURL: shmURL, error: nil)
let walURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent(databaseName + "-wal")
let baseWALURL = bundle.URLForResource(modelName, withExtension: "sqlite-wal")
NSFileManager.defaultManager().copyItemAtURL(baseWALURL!, toURL: walURL, error: nil)
}
Upvotes: 4
Reputation: 41226
I think this probably has to do with how files are laid out on iOS. Specifically:
To fix this, you need to copy the store from the Application directory to the Documents directory if it doesn't already exist.
This link gives an explanation and example code to do that. But in Objective-C it looks like:
NSString *storePath = [[self applicationDocumentsDirectory]
stringByAppendingPathComponent: @"MyDB.sqlite"];
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
// Copy the default db if it doesn't already exist
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle]
pathForResource:@"MyDB" ofType:@"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath
toPath:storePath error:NULL];
}
}
Upvotes: 0