"Can't add the same store twice" on migration of Core Data versions - ios

I am trying to perform a migration between two versions of CoreData that differ fundamentally to the fact that the new version has two configurations so I can save entities in two different sqlite file (one read-only in Main Bundle and one, the old sqlite, used now only for user data). I also added a model mapping to map the differences, especially to reset relationships between the entities that are lost due to multiple configurations.
The app works properly without crash if installed from scratch and new records are inserted in user data sqlite in application documents directory as expected.
The problem is when I try a migration from previous Core Data version: the app start without crash but on first executeFetchRequest it crash at coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: "Userdata", URL: urlUser, options: optionsUser, error: &errorUser) (viewed with debug) and console return this log:
2015-02-23 18:48:24.052 MedAbility[21480:585606] CoreData: error:
-addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Volumes/Documenti/Users/andrea/Library/Developer/CoreSimulator/Devices/301801BE-4B6A-4371-BE66-3E71557B0897/data/Containers/Data/Application/FBEC0124-1D74-4F94-99F2-6F492281AA8E/Documents/MedAbility.sqlite
options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=134080 "The operation
couldn’t be completed. (Cocoa error 134080.)" UserInfo=0x7fb50ae481d0
{NSUnderlyingException=Can't add the same store twice} with userInfo
dictionary {
NSUnderlyingException = "Can't add the same store twice"; } 2015-02-23 18:48:24.061 MedAbility[21480:585606] CoreData: error:
-addPersistentStoreWithType:SQLite configuration:Userdata URL:file:///Volumes/Documenti/Users/andrea/Library/Developer/CoreSimulator/Devices/301801BE-4B6A-4371-BE66-3E71557B0897/data/Containers/Data/Application/FBEC0124-1D74-4F94-99F2-6F492281AA8E/Documents/MedAbility.sqlite
options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=134080 "The operation
couldn’t be completed. (Cocoa error 134080.)" UserInfo=0x7fb50ae481d0
{NSUnderlyingException=Can't add the same store twice} with userInfo
dictionary {
NSUnderlyingException = "Can't add the same store twice"; }
This is my code:
Old version PersistentStoreCoordinator:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("MedAbility.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
// Set options for migrations
let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options, error: &error) == nil {
coordinator = nil
// Report any error we got.
let dict = NSMutableDictionary()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(error), \(error!.userInfo)")
}
// Exclude db from backup
Util.addSkipBackupAttributeToItemAtURL(url)
return coordinator
}()
New version PersistentStoreCoordinator:
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 url = NSBundle.mainBundle().URLForResource("MedAbilityDomande", withExtension: "sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
// Set questions sqlite as read-only
let options = [NSReadOnlyPersistentStoreOption: true]
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: "Domande", URL: url, options: options, error: &error) == nil {
coordinator = nil
// Report any error we got.
let dict = NSMutableDictionary()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(error), \(error!.userInfo)")
}
let urlUser = self.applicationDocumentsDirectory.URLByAppendingPathComponent("MedAbility.sqlite")
var errorUser: NSError? = nil
var failureReasonUser = "There was an error creating or loading the application's saved data."
// Set migration options
let optionsUser = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: "Userdata", URL: urlUser, options: optionsUser, error: &errorUser) == nil {
coordinator = nil
// Report any error we got.
let dict = NSMutableDictionary()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReasonUser
dict[NSUnderlyingErrorKey] = errorUser
errorUser = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(errorUser), \(errorUser!.userInfo)")
}
return coordinator
}()
Someone know how can I resolve this issue?
Thanks for the help!
EDIT
I did some test and I found that commenting coordinator!.addPersistentStoreWithType (NSSQLiteStoreType, configuration: "Questions", URL: url, options: options, error: & error) for the first database, the application starts without issues, obviously without the content of the database not added. If I reverse the addition of the two database the app crashes with same log except for "URL: file:[...]" that it's called on the ex-first now-second database ("MedAbilityDomande.sqlite"); in practice it's the addition of the second database the problem and not a specific database. It seems that migrating the old database to the new one used for user data actually doesn't migrate configurations, so remains the old configuration that goes to overlap the entities with the new read-only database inserted into the mainBundle. As I have previously said if the app start from scratch (without migration) works perfectly.
Do you have any idea?
Thank you so much again!

I finally found the solution! I created the database MedAbilityDomande.sqlite based on the database that after I wanted to migrate to use for user data. This brought to have two databases with same UUID generating the error "Can't add the same store twice". It was enough to change the UUID of the database in the application bundle (MedAbilityDomande.sqlite) and everything worked great.
Until next time!

Related

Is there any other way than `UserDefaults` to share data between `Today Widget Extension` and the main `Container Application` in iOS

I mean I want to know that is it possible to use CoreData which shares a common resource?
You have the options of sharing the SQLite and user default between your main app and the widgets.
If you want the SQLite to be shared between the Main App and the widget, please follow the steps.
create an app group. Click on the main project -> Capabilities -> App Group -> create a group.. example: group.com.appname.appgroup
While creating the persistent coordinator, create an SQLite file in the app group and provide the path.
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
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.appname.appgroup")!
let url = directory.appendingPathComponent("somename.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption:true,NSInferMappingModelAutomaticallyOption:true])
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator}()
You can access the core data in widgets like the way you use in main app.
If you want to use the user defaults, then follow the below steps.
create a user deafult object.
var userDefaults =
UserDefaults(suiteName:"group.com.appname.appgroup")!
use this object for setting and retrieving the values.
You can share data between extensions and the host app via Keychain Sharing and App Groups (needs to be configured in the capabilities of your target).
Example for Keychain Sharing with KeychainAccess:
import KeychainAccess
let sharedKeychain = Keychain(service: "com.company.App.shared" , accessGroup: "TeamId.App")
sharedKeychain?["username"] = "Test"
Example for User Defaults:
var userDefaults = UserDefaults(suiteName: "group.com.company.App")!
Example for data in App Group:
let fileUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.company.App")!
To share data via CoreData just put the database file into the App Group storage.
Example with CoreStore:
import CoreStore
let dataStack: DataStack = {
let dataStack = DataStack(xcodeModelName: "App")
let storagePathUrl = fileUrl.appendingPathComponent("App.sqlite")
do {
try dataStack.addStorageAndWait(SQLiteStore(fileURL: storagePathUrl, configuration: "Default", localStorageOptions: .
recreateStoreOnModelMismatch))
} catch let error {
print("Cannot set up database storage: \(error)")
}
return dataStack
}()

How to use persistentStore(for: url) in core data Swift 3

I'm trying to do the following:
Tap a cell of a UITableView cell then segue to the next UIViewController and display the database results. But there are multiple persistent stores therefore the designated store is specified by the cell label text.
The question is: How to use the method persistentStore(for: url)? Or is there some else way to specify a persistent store for the fetchRequest?
Here is my code that is not working:
func wordFetchRequest() -> NSFetchRequest<Word> {
let fr = NSFetchRequest<Word>(entityName: "Word")
fr.fetchBatchSize = 100
// Assigning sort descriptors
let firstLetterSort = NSSortDescriptor(key: #keyPath(Word.firstLetter), ascending: true)
let spellSort = NSSortDescriptor(key: #keyPath(Word.spell), ascending: true)
fr.sortDescriptors = [firstLetterSort, spellSort]
// Get URL of the designated store to fetch
let libname = (AppDelegate.nameDict as NSDictionary).allKeys(for: nameToFetch).first!
// I'm not sure the following line: which file should I use? I've tried
//.sqlite, .sqlite-shm and .sqlite-wal but none worked.
let url = AppDelegate.coreDataStack.storeDirectory.appendingPathComponent("\(libname).sqlite-wal")
// Specify affected store for the fetch request
var pss = [NSPersistentStore]()
print(url)
// The following line fails:
if let ps = coreDataStack.psc.persistentStore(for: url) {
pss.append(ps)
} else {
}
fr.affectedStores = pss
print(fr.affectedStores ?? "No stores available.")
return fr
}
Any help will be much appreciated.
I had to deal with similar scenario where I had different persistent stores (to be specific one of type NSInMemoryStoreType and other of type NSSQLiteStoreType to be specific)
I found it easier to create separate persistent store coordinators for each store and create separate managed object context using these persistent stores as there parent stores :)
Here is the code which was written in iOS 9 swift 3, hence has older core data stack operations, I have seen iOS 10 Swift 3 Core data stack, I believe these methods can still give you idea of what am talking here :)
This is what you will see by default in Coredata stack, getter for persistentStoreCoordinator
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns 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
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
log.debug(url)
} catch let error as NSError {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?
dict[NSUnderlyingErrorKey] = error
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
catch{
}
return coordinator
}()
Important statement here though is
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
As you can see it specifies the persistent store type as Sqlite and specifies the configurationName as nil, which means default configuration :)
You can create multiple configurations in Coredata and specify there name in this statement to create separate persistent store coordinator for each configurations :)
You can have a look at my blog Can core data be trusted with sensitive informations to see how you can create multiple configurations and stores :)
So lets assume you create another configuration and added entities to them and lets call it as "Test1" configuration, you will create a separate persistent store coordinator for that using,
lazy var test1PersistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns 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
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: "Test1", at: url, options: nil)
log.debug(url)
} catch let error as NSError {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?
dict[NSUnderlyingErrorKey] = error
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
catch{
}
return coordinator
}()
Now you have two persistent store coordinators associated with two different configurations, simply create two managed object contexts using these persistent store coordinators as their parent store :)
lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
lazy var managedObjectContextForBackTracking : NSManagedObjectContext = {
let coordinator = self.test1PersistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
Thats it :)
Now run your fetch requests on corresponding managedObject contexts :) and be sure that nothing messes up your core data :)
Hope it helps :)

CoreData crash on migration with NSMigrationConstraintViolationError = 134111 error

I am creating a new NSPersistentStoreCoordinator for background long savings from the server. It worked fine but suddenly I see a crash in Production with the following error -
CRASH_INFO_ENTRY_0
fatal error: Background context creation failed with error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={sourceURL=file:///var/mobile/Containers/Data/Application/8EF27C05-1755-49EE-B174-8B163CC7CC1D/Documents/App.sqlite, reason=Cannot migrate store in-place: constraint violation during attempted migration, destinationURL=file:///var/mobile/Containers/Data/Application/8EF27C05-1755-49EE-B174-8B163CC7CC1D/Documents/.App.sqlite.migrationdestination_41b5a6b5c6e848c462a8480cd24caef3, NSUnderlyingError=0x170a56290 {Error Domain=NSCocoaErrorDomain Code=134111 "(null)" UserInfo={reason=constraint violation during attempted migration, NSUnderlyingException=Constraint violation, _NSCoreDataOptimisticLockingFailureConflictsKey=( "" )}}}: file /Users/*******/Desktop/7.50/APPS/LTG/project/modelBase/db/DatabaseManager.swift, line 67
Lookalike I have a constraints issue as this is the error I get -
NSMigrationConstraintViolationError = 134111, //
migration failed due to a violated uniqueness constraint
Bu since the _NSCoreDataOptimisticLockingFailureConflictsKey is <null> I can not trace the issue.
This is my code -
lazy var backgroundSyncContext:NSManagedObjectContext = {
let psc = NSPersistentStoreCoordinator(managedObjectModel: NSManagedObjectModel.MR_defaultManagedObjectModel()!)
let context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
context.undoManager = nil
context.persistentStoreCoordinator = psc
let mOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
let paths = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask)
let applicationDocumentURL = paths.last!.absoluteString?.stringByReplacingOccurrencesOfString("%20", withString: " ")
let documentPath = paths.last!
let storeUrl = documentPath.URLByAppendingPathComponent("Prep4\(AppConfig.sharedInstance.examName).sqlite")
do {
try context.persistentStoreCoordinator?.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeUrl, options: mOptions)
print("Created background context")
} catch (let error){
fatalError("Background context creation failed with error \(error)")
}
return context
}()
EDIT
OK, I have a guess - is the latest version I added constraints to the model. Is there a chance that the old version on the user device contains duplicates that are nor valid with the new constraints so the the migration fails.
Does that sounds reasonable ?
Thanks
Shani

Failed finishing setup for store during asynchronous iCloud initialization

I am in the process of creating a core data stack in Swift 2 that handles syncing data with other iDevices using iCloud using different resources (Mostly in Objective-C).
When running the app I sometimes get the following error, and if I run it again the error goes but sometimes displays old data that was supposed to be deleted:
2015-09-08 22:49:31.104 APPNAME[5606:418539]
-[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](874): CoreData: Ubiquity:
nobody~sim73E13D94-AB95-59FB-AF18-ADC7BC05B47B:APPNAMEStore Using local
storage: 1 for new NSFileManager current token <766b5e5c 3c205110
52c05248 38a47bd9 aca1ee87> 2015-09-08 22:49:31.185
APPNAME[5606:418593] -[PFUbiquitySetupAssistant
finishSetupForStore:error:](1125): CoreData: Ubiquity: CoreData:error: Caught Exception Unable to resolve mismatching KVs with
userInfo {
PFUbiquitySetupDoFork = 1; } in -finishSetupForSet:error: 2015-09-08 22:49:31.243 APPNAME[5606:418593] -[PFUbiquitySetupAssistant
finishSetupWithRetry:](829): CoreData: Ubiquity: <PFUbiquitySetupAssistant: 0x7f97b3328320>: Retrying after delay: 60
Error Domain=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={failed finishing setup for store during asynchronous iCloud
initialization=file:///Users/USER/Library/Developer/CoreSimulator/Devices/19DE5FBA-9248-410D-9264-6B434B30F8CA/data/Containers/Data/Application/5B174D0D-C80D-4362-90EE-DC640F907962/Documents/CoreDataUbiquitySupport/nobody~sim73E13D94-AB95-59FB-AF18-ADC7BC05B47B/APPNAMEStore/DD2F75D5-FEAF-482A-A896-657936AFCFCD/store/APPNAME.sqlite}
2015-09-08 22:50:31.288 APPNAME[5606:418966] -[PFUbiquitySetupAssistant finishSetupForStore:error:](1125): CoreData: Ubiquity: CoreData: error: Caught Exception Unable to resolve mismatching KVs with userInfo {
PFUbiquitySetupDoFork = 1; } in -finishSetupForSet:error: 2015-09-08 22:50:31.289 APPNAME[5606:418966]
-[PFUbiquitySetupAssistant
finishSetupWithRetry:](829): CoreData: Ubiquity: <PFUbiquitySetupAssistant: 0x7f97b3328320>: Retrying after delay: 120 Error Domain=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={failed finishing setup for store during asynchronous iCloud
initialization=file:///Users/USER/Library/Developer/CoreSimulator/Devices/19DE5FBA-9248-410D-9264-6B434B30F8CA/data/Containers/Data/Application/5B174D0D-C80D-4362-90EE-DC640F907962/Documents/CoreDataUbiquitySupport/nobody~sim73E13D94-AB95-59FB-AF18-ADC7BC05B47B/APPNAMEStore/DD2F75D5-FEAF-482A-A896-657936AFCFCD/store/APPNAME.sqlite}
2015-09-08 22:52:31.333 APPNAME[5606:420217] -[PFUbiquitySetupAssistant finishSetupForStore:error:](1125): CoreData: Ubiquity: CoreData: error: Caught Exception Unable to resolve mismatching KVs with userInfo {
PFUbiquitySetupDoFork = 1; } in -finishSetupForSet:error:
Core Data Stack
// MARK: - Core Data stack
// This handles the updates to the data via iCLoud updates
func registerCoordinatorForStoreNotifications (coordinator : NSPersistentStoreCoordinator) {
let nc : NSNotificationCenter = NSNotificationCenter.defaultCenter();
nc.addObserver(self, selector: "StoresWillChange:",
name: NSPersistentStoreCoordinatorStoresWillChangeNotification,
object: coordinator)
nc.addObserver(self, selector: "StoresDidChange:",
name: NSPersistentStoreCoordinatorStoresDidChangeNotification,
object: coordinator)
nc.addObserver(self, selector: "StoreChangedUbiquitousContent:",
name: NSPersistentStoreDidImportUbiquitousContentChangesNotification,
object: coordinator)
}
// Subscribe to NSPersistentStoreCoordinatorStoresWillChangeNotification
// most likely to be called if the user enables / disables iCloud
// (either globally, or just for your app) or if the user changes
// iCloud accounts.
func StoresWillChange (notification:NSNotification) {
managedObjectContext.performBlock { () -> Void in
if self.managedObjectContext.hasChanges {
do {
try self.managedObjectContext.save()
} catch {
print("error saving Managed Object Context in AppDelegate")
}
} else{
// drop any manged object refrences
self.managedObjectContext.reset()
}
}
}
// Subscribe to NSPersistentStoreCoordinatorStoresDidChangeNotification
func StoresDidChange(notification: NSNotification) {
NSLog("storesDidChange posting notif");
NSNotificationCenter.defaultCenter().postNotificationName("storeDidChange", object: nil)
}
func mergeChanges(notification: NSNotification) {
NSLog("mergeChanges notif:\(notification)")
self.managedObjectContext.performBlock {
self.managedObjectContext.mergeChangesFromContextDidSaveNotification(notification)
}
}
func StoreChangedUbiquitousContent(notification: NSNotification) {
self.mergeChanges(notification);
}
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.USER.swift2-iCloud" in the application's documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1]
}()
lazy var managedObjectModel: NSManagedObjectModel = {
let modelURL = NSBundle.mainBundle().URLForResource("APPNAME", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("APPNAME.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
// iCloud store
var storeOptions = [NSPersistentStoreUbiquitousContentNameKey : "APPNAMEStore",NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
do {
try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: NSURL.fileURLWithPath(url.path!), options: storeOptions)
} catch var error1 as NSError {
error = error1
coordinator = nil
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
} catch {
fatalError()
}
self.registerCoordinatorForStoreNotifications (coordinator!)
return coordinator
}()
Does anybody understand why this is occurring and how I can resolve the error ? I really appreciate feedback as I am hoping to create a public GitHub repository for other new developers to use.
Couldn't leave it as a comment, cuz wrote here. Found reply about this issue here
In terms of those iCloud errors that appear, they generally look a lot scarier than they are. My experience has been that iCloud is great at generating a lot of very scary looking messages in the log that don’t actually signal anything is wrong. In most cases the errors automatically correct themselves after a time. The most intervention I have needed to do at times has been when using the iOS simulator where at times you need to reset the computer to fix it.
However, there are some things that can cause iCloud containers to become corrupted. If you are performing a lot of synchronisation testing, in particular operations that generate a lot of duplicates, it can take an extended time for the iCloud container to properly sync.
You also need to be careful that any, and I do mean any, accessing of the information held in Core Data is handled from the same thread. That includes reading from the objects that you have loaded from Core Data. Accessing the information from multiple threads can very easily cause corruption that does not manifest until you try to sync the container (or migrate it). The best way to avoid that is to use the performBlock and performBlockAndWait methods on the iCloud + Core Data stack. Those methods guarantee that the operations (read or write) will happen on the same thread to prevent data corruption.

Importing pre-existing sqlite file and core data models with .xcdatamodel into newly created Swift application

Currently i am importing pre-existing sqlite file and core data models with .xcdatamodel into newly created Swift Application. It has two tables say A & B. Whenever i try to access A table rows. Its giving me the following error.
"The model used to open the store is incompatible with the one used to create the store"
When i searched for this error i found some solutions which i applied but did not work. Solutions already applied are :
Delete the application & install again.
Reset the entire simulator and run again.
I even restarted Xcode which to me is stupid. But still did not work.
Here is my code :
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url : NSURL! = NSBundle.mainBundle().URLForResource("db", withExtension: "sqlite")
println("Url :: \(url)")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
var options = NSMutableDictionary()
options[NSReadOnlyPersistentStoreOption] = true
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options, error: &error) == nil {
coordinator = nil
// Report any error we got.
let dict = NSMutableDictionary()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError.errorWithDomain("YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
Can somebody help me out in this. Thanks.

Resources