I have app on app store and I set up storeURL to : Model 2.sqlite. It working good but now maybe 2 months later, I am working on new version app, I added new model version and set storeURL: Model.sqlite. But I cant migrate from old version(lightweight migration). When I set storeURL to : Model 2.sqlite and start my app, console show me Can't find model for source store. Where can be the problem? I dont wanna lose data from old version.
Thank you
The store URL is where your persistent store is put. It is logically nothing to do with the format of that store. Most apps will change their model several times but never once change the store's URL.
Your error suggests you've either removed the old version of your model from the build or, for some reason, declined to use a versioned model at all. If you were to open your current Xcode project now, would the old version of your model be in it? Is it located such that Core Data could be expected to know its relationship to the new?
Related
My app under development uses core data.
When I add an optional attribute to an entity, I expected that automatic lightweight migration is done, because I use an NSPersistentCloudKitContainer, and all my NSPersistentStoreDescription have the default settings shouldMigrateStoreAutomatically = true and shouldInferMappingModelAutomatically = true.
After changing the xcdatamodeld file by adding an attribute and restarting the app with the old persistent store, no data is fetched, and no error is reported.
However when I re-install the app, everything works fine, because a new persistent store is filled with the iCloud data.
Maybe I can detect that the model has changed, delete the old persistent store, and setup a new one that is synced then with iCloud.
But it should also work without iCloud sync: I thought the old persistent store should be automatically migrated to the new model, i.e., the newly added attribute should be initialized with nil.
Is this a misunderstanding? Do I miss something? How to do the migration correctly?
PS: I have read this answer, but since my app is still under development, I thought I don't need different versions of the model, but could simply update it.
I've got my app in the App Store with datamodel in version 2. I created version 3 of the data model, set it as current and add 1 new entity to it (attributes are marked as Optional). This new entity has no relations with others. Of course NSMigratePersistentStoresAutomaticallyOption and NSInferMappingModelAutomaticallyOption are both set to YES. Now if I overwrite the app downloaded from the App Store (with datamodel v2) by Xcode version (with datamodel v3), users data is missing. There is no information in the log about any problem.
I have searched on Stack Overflow for the solution for hours and (I think) tried everything (e.g. delete and re-add the xcdatamodel file in version 1, then create version 2 and 3 of the data model) but haven't found any solution.
I would like to add that I have done similar changes (added new entity) in my other app and everything works perfectly - users data is migrated using lightweight method to new version of data model.
Please help :)
long story short, my Core Data schema was changed, and my app was submitted to the app store, which caused everybody who updated their app to crash. The crash is caused by a missing NSPersistentStore due to not migrating the data model properly.
I still see the .sqlite and associated database files in the documents directory, and if I downgrade to the older version everything works fine with all data. My question is, can I recover from this with an app update by somehow migrating the existing NSPersistentStore and adding it to the NSPersistentStoreCoordinator?
EDIT: so I didn't actually change my xcdatamodel myself, hence, "long story short". However, I did remove XMPPFramework from my project and I have a feeling this might have caused the core data problem.
EDIT:
I didn't make any changes directly to my data model, but I have pinpointed the problem. I was retrieving my NSManagedObjectModel using [NSManagedObjectModel mergedModelFromBundles:nil] which merges ALL data models present in the bundle. This included all data models that came with the XMPPFramework, and now that the framework has been removed, the NSManagedObjectModel that is passed into [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel] is different, thus causing the crash.
I resolved the problem by using FMDB to fetch the contents of the existing DB, then created a new sqlite file and pointed the persistent store coordinator to that new sqlite file. Then I just inserted all the existing data into the new database by looping through the existing data and creating the appropriate NSManagedObjects. I also stopped using mergedModelFromBundles to retrieve my data model and instead use initWithContentsOfURL.
Actually you might have updated xcdatamodel somehow after first version, And you didn't created a new xcdatamodel model for second version. So on second update it's crashing.
NOTE: After first version release, you have to create a second model version of xcdatamodel.
To create second model version of xcdatamodel -
1. first you have to select Model.xcdatamodeld -> Go to Editor on menu -> Add Model Version. Here you have to name a model version and based on which old model you want to create this new one.
Now whatever changes you want to make you should make on new model version xcdatamodel.
2. You can see on image, I've given a new name to my new model 'Model2.0', which is based on my previous 'Model'.
New model will work exactly like your old model, Additionally changes will be made on new model won't affect to your old model. So it won't crash your app after update.
3. You have to select your new 'Model2.0' as a default working model. For that please consider the below image.
4. Here you can see there is 2 model now. Please select 'Model.xcdatamodeld' a main model, and open it's 'File Inspector' on right side - as opened on above image.
5. There is 'Model Version' field on the right side, Which indicates the 'current' model selected on this project. Please select the new model 'Model2.0' for your updated version. Now you can run and it will work fine onwards.
NOTE: Please make sure now whatever changes you will make, you will do it on your new model 'Model2.0', So it won't conflict with your old model. You have to make new model each time, if you want to change configuration of xcdatamodel on updated app version.
Our app got released in app store and now I wanted work on next version. Here I might add property and entity to current model .
I am using core data with Magical record .
I need help on core data migration with magical record .
I am already using [MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:#"xxxxxxx"]; in app delegate .
As per my understand MR will take care of migration if we use above method .
Should I need to do any changes in Model.xcdatamodeld like adding model version (Editor->Add model Version) .
Please help me how can migrate core data.
To build on #casademora answer who obviously knows a lot more about MR than me, here is what got stuff working for me. The key is reading the Apple docs as suggested.
highlight your existing .xcdatamodel and then click Editor > Add model version > name it with an increment from your previous (i.e. if "myapp" use "myapp 2" as suggested in xcode.
make your changes on the newly created .xcdatamodel.
highlight the parent .xcdatamodel and then on the File Inspector on the right of xcode select your new version as the current Model Version.
NOTE: This step is only required if doing more than a Lightweight Migration. Select File > New > File > Core Data > Mapping Model. Choose your original as source, new as target and then save in the same folder as your .xcdatamodel.
make sure you are using setupAutoMigratingCoreDataStack or setupCoreDataStackWithAutoMigratingSqliteStoreNamed of course
test by downloading the app from app store and opening it, then closing and running debug over the top. You should not get any "Removed incompatible model version" messages (i.e. all persistent data should be in place still) or any other errors.
That method simply enables auto migrations to happen when you have multiple versions of a data model in your application bundle. To add a new version of a data model, you'll need to select your data model in Xcode, and in the menu select Editor -> Add Model Version... From there, Xcode will do the proper setup for you. This is also a fairly simple idea, it creates a new data model file, that starts off as the contents of your current data model file. From there, you can change and edit your data model as you see fit. Be aware that only simple changes are "automatic". Adding a new property is valid if it has a default value. Adding a new entity falls into the automatic category as well. I suggest reading more details about Core Data Migrations from Apple's Official Documentation
i have submitted an app on the app store that uses core data.
The problem is that i duplicated my project and then lost the first source code. If i update the app using the "duplicated" source code does it delete all core datas users may have stored? i know that if you change the file file-xcdatamodel without mapping the previous datas you will lose all you had stored, can i assume the duplicated project use the exact same file?
thanks in advance
In that case I think that, if you didn't modify your xcdatamodel, the data stored by user will keep during the upgrade. In order to be sure, you can install your own apo from App Store, save some data, update this app from Xcode with your new version and check if the stored data still are there.
If you've modify your xcdatamodel, you must perform a light or a heavy migration, depending on your canges.