Coredata Lightweight Migration Fails - ios

If I add a new model version and then add an attribute to an entity I get a migration failure. It doesn't matter what the type of the attribute is or whether it is optional or has a default value. If I just add the new model version but don't add the attribute it works OK. I have done this sort of thing lots of times over the past 3 years without problems. Both NSMigratePersistentStoresAutomaticallyOption and NSInferMappingModelAutomaticallyOption are set to true. The error I get is shown below.
2018-02-18 12:28:51.771608+0000 Writing Shed[4105:1886727] [error] error: Illegal attempt to save to a file that was never opened. "This NSPersistentStoreCoordinator has no persistent stores (schema mismatch or migration failure). It cannot perform a save operation.". Last recorded error = Error Domain=NSCocoaErrorDomain Code=134140 "Persistent store migration failed, missing mapping model."
Does anyone know what might be wrong?

I've found the problem. I'm developing an app on Mac OS that is already available on IOS. They sync CoreData via iCloud. At some point while working on the Mac I added some attributes to the model that weren't optional or defaulted. To cut a long story short this caused problems with an IOS store that predated the changes, so that's when the migration failed (can't migrate to non-optional/non-defaulted attributes). I'm still not sure how I got into this situation because I'm usually very careful with CoreData, but hey stuff happens. Thanks for the comments which made me look deeper.

Related

Crashing after lightweight Core Data migration

I am trying to master Code Data migration, its going to be important for supporting my app. The reason I need the migration is to preserve data. My app is used for psychological research and collection reaction time data. I have a game session and every game session has ordered set of moves. Every move has some properties. One of this properties is interval: Date. In the store version 1 it was named date and in the version 2 I renamed it to the interval and changed property's model version identifier to date.
App is not crashing on startup but when I am trying to view my old logs it crashes. I have UITextView and I display all my logs like this:
textView.text = "Interval = \(move.interval)"
If I create new game session and will view its log - the app works.
What is the best way to protect my users? Should I add additional logic inside my app for this? How can I display the old data after property was renamed?
Update:
There's no messages in the console, the app stops working with the line of code for updating the UITextView, it is highlighted in green with error message:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
I tried again from scratch and instead of renaming the variable, I created new one. This time app didn't crashed. I am sorry it is not real answer but it helped me to move on.
Lessons I learned:
Do not confuse Core Data Model Identifier in Xcode inspector and renaming ID. There's one model identifier (I left it empty) and renaming ID for every property.
If you have Core Data generated class with NSNumber, do not try to display them in console like this: label.text = "number = \(object.number)"
Do it like this:
label.text = "number = \(object.number.integerValue)"
This one gave me the same crash message, however it is not a problem if you're using NSDate.
I still have a problem when renaming variable. When I applied my commit again today I am getting the crash right on the start with the Can't find model for source store message. App in the simulator changed, so it looks like I can't reproduce this problem any more and instead have a new one.
Update
I had more practice and I think I was able to fix the crash described above.
I added next data model version - version 3 and introduced new variable. I did it like before, with switching current version from 2 to 3. Then app started to crash on launch with Can't find model for source store. I noticed that when I'm removing introduced variable the app is not crashing. I figure out that my Core Data couldn't migrate to version 3 because it already was on version 3:
I changed version from 2 to 3. I didn't change Core Data model.
I changed my code, fixed some bugs unrelated to Core Data.
Built and ran the project in the simulator. Note, now the app in the simulator has data version 3.
Changed Core Data model, built on simulator. It crashed after this step.
What I did to fix this:
Delete introduced variable. You can live generated classes as it is.
Change current version to previous. In my case, from 2 to 3.
Run the app and quit it.
Change Core Data current version and add new variable.
Run the app — it works.
Update 2
I met with this problem again and my answer didn't helped. Still, event after everything I described above.
I found this answer which this time finally fixed the issue. The secret was that new attributes should not be optional and they should have default values.

Is there a way to changing Core Data schema without migration during early development?

At the early stages of development, where data retention is no issue and experimental changes to the schema are expected to be numerous, is there a way to avoid migration? Namely, just to dump the database and start over each time.
Everything I try leads to the error: "The model used to open the store is incompatible with the one used to create the store".
Lightweight migration looks do-able, but I'll end up lots of unwanted versions and messy code. I'd also like to experiment with relationships (no wise cracks), but understand I'd need to commit to a heavyweight migration afterwards!
If the solution is to check for the existence of the original database using NSFileManager and delete/remove it if found, could someone please show the swift code with an example name of the original database, and how it can be effectively removed.
I've been trying several suggested solutions, such as dragging a copy of the .xcdatamodeld file onto the desktop, deleting the file in xcode and bringing it back in, but I keep getting the error that the model and store are not the same.
Answered in one line in first comment, but appreciated in reverse proportion.

When can "This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation." Error Occurs

"nspersistentstorecoordinator has no persistent stores. it cannot
perform a save operation background thread".
Can saving manageContext on background thread cause this issue ?
Sorry if this is already asked. I would like to know the probable reason for its occurrence ?
Apparently you have created a memory-based persistent store coordinator, instead of one that use an SQLite database (the usual case) or XML for storage. Since there is no file holding the database, you can't save anything.
Check the code where the persistent store coordinator is created.
If you used the default code from Apple verbatim then you are likely getting an error when creating the persistent store coordinator, but ignoring the error. Apple's boilerplate code checks for the error and has a comment in the if check that just says "/Error for store creation should be handled in here/". You should at least log a message in there to see if you're hitting that code path. If so, that's your issue. :)
NOTE: You can hit this problem when switching from new code (with a core data upgrade) to older code (e.g., in a branch) that doesn't have that upgrade. If you don't run clean in xcode, the compiled model file from the newer build can get put into the older build and cause you heartache.

What is .appname.sqlite.migrationdestination_xxxx file? Does it cause sql corruption error?

I'm developing iOS application using CoreData.
And I have got application datas from user that includes following hidden files.
Documents/.appname.sqlite.migrationdestination_xxxx (549MB)
Documents/.appname.sqlite.migrationdestination_xxxx-shm (721KB)
Documents/.appname.sqlite.migrationdestination_xxxx-wal (0Byte)
And There are appname.sqlite, appname.sqlite-wal and appname.sqlite-shm in same Documents folder.appname.sqlite is main sql file for app. and -wal, -shm seems to be generated automatically by iOS.
(I learned from What are the .db-shm and .db-wal extensions in Sqlite databases?)
I think migrationdestination file is just progress data for migration.
Maybe it remains when user's device failed to migrate. (e.g. iOS terminate my app when my app has been in background long-time.)
By the way, some users using my app have got this trouble.
Mar 10 13:33:24 xxxx-xx-iPhone XXXXXXXX[5416] : CoreData:
error: (11) Fatal error. The database at
/var/mobile/Applications/95D2823D-37E4-4596-9507-B58571D32EBB/Documents/appname.sqlite
is corrupted. SQLite error code:11, 'database disk image is
malformed'
And i found this tips.
Core Data store corruption
One of answer says -wal and -shm cause this error. so i removed it.
However, user still gets same error. So i think migrationdestination may cause this error.
I'll test it to remove tomorrow. Then i report the result it to here.
So Does anyone have same trouble, suggestions, answers?
Thank you for reading my issue.
These are files that exist during a migration. If you are seeing these files then your migration failed. Check your crash logs on that device and confirm.
Are you migrating in the -applicationDidFinishLaunching... method? Are you getting a bad food crash? Those are common situations that will cause a migration to fail in the middle of the migration.
Finally, I found a solution for 'database disk image is malformed'.
I renamed these files
before
Documents/.appname.sqlite.migrationdestination_xxxx
Documents/.appname.sqlite.migrationdestination_xxxx-shm
Documents/.appname.sqlite.migrationdestination_xxxx-wal
after
Documents/appname.sqlite
Documents/appname.sqlite-shm
Documents/appname.sqlite-wal
I deleted old appname.sqlite, appname.sqlite-shm, appname.sqlite-wal files.
I guessed why this error happens.
Maybe user has succeeded migration.
So there are two sql files. appname.sqlite and .appname.sqlite.migrationdestination_xxxx.
Then iOS is going to exchange these files, but if app is killed by some reason, appname.sqlite remains in the middle of deleting.
but app look appname.sqlite every time, then iOS guess wrong it's corrupted, so my app can't run.
Now i'm going to make these exchange script and apply my app.
Thank you for listing my issue.

Core Data Migration - Table Already Exists

I have an existing iPad application to which I've just added core data versioning. I've been through the documentation and followed the steps detailed. Now after choosing my new model as the current versioned model and trying to run it on my dev device from xCode I get the following error:
2012-03-28 07:35:42.137 DocsOnTap[2603:707] CoreData: error: (1) I/O error for database at /var/mobile/Applications/06EECF01-3598-4513-8A3A-BE4FD49EEBF6/Documents/.DocsOnTap.sqlite.migrationdestination_41b5a6b5c6e848c462a8480cd24caef3. SQLite error code:1, 'table Z_2TAG already exists'
The only change that I made to my model was to add in a single new entity. I have a table named Tag in my model - that appears to be what the error is referring to.
If I revert my current versioned model back to the previous model version then I can run my app on my dev device from Xcode without error.
I have read that there can be problems trying to use core data migration on dev devices. However I just want to test the process to be sure that when we update our app in the Appstore the migration works as expected for our customers.
In my case the same error appeared due to Renaming ID which was set in the Data Model inspector for the Entity. After I removed the Renaming ID the problem'd gone.
Well this was an obscure error. The entity that I was adding was named AppKeys - this must be the name of an entity used internally by core data or SQL Lite. I went back to scratch and found that I could add and migrate other attributes and entities without any problems. However if I tried once again to add my entity named AppKeys then I got the same error saying that 'table Z_2TAG already exists'. So the resolution to my problem is to choose another entity name. It is a pity that this is not documented somewhere obvious - or that the error was not more helpful. Anyway hopefully this might just help someone else one day.

Resources