first let me state that this is NOT a core data migration question. I'm not actually looking at changing the Core Data model, but add additional items during an app update.
The process is as follows:
1) Application is created with a pre-loaded core data. Specifically, a checklist.
2) User can edit this checklist by changing certain values (owned, wanted, etc) but CANNOT remove items
3) I release updates with new items that are added. The users existing data is NOT modified (unless I need to make changes for errata purposes)
I currently manage this by creating NSUserDefaults to check to see if a user has received an update, and if they haven't, add the new items. For example, if a user is going from version 1.4.3 to 1.4.4, the app will check and add the items added in 1.4.4. However, if the app is going from 1.4.0 to 1.4.4, it will check and add items added in 1.4.1, 1.4.2, 1.4.3, AND 1.4.4
. In addition, if a user is installing the app new at version 1.4.4, the newer items are already part of the pre-load and it knows not to apply any of the previous updates. The updates are applied as a .plist/xml file
The system currently works and works well, but it is becoming cumbersome as I now have 38 plist files in my application and 37 if/else statements checking to see if the updates are applied.
There must be a better way. My initial thoughts are to have two databases in the app... One which I update with app updates and the second that is editable by user. Then, with each app update, the database would be compared and any new items in the database would be copied over to the editable store. I'm concerned that this would be a long process though (there are currently over 37,000 items and it's fine when I'm adding 400-500 in an update, but would it take a long time to traverse 37,000 items and copy over new ones?)
I suppose this question may be too subjective for this site, and I apologize if it is, but suggestions would be greatly appreciated!
Zack
You could do this with one pre-load data store and no update property lists or if statements like this:
Store the app current version in user defaults so that during an update you can retrieve it as the previous version (it sounds like you're already doing this, but I wanted to be clear).
In the preload store, add three integer fields that correspond to the major, minor, and point release where that preload item was added. For example, if an item was added in version 1.4.3, major = 1, minor = 4, and point = 3.
When adding new items to the user's data store during an update, get the previous app version from user defaults, and get the major, minor, and point update numbers from that. If the user is upgrading from version 1.4.0, use previousMajor = 1, previousMinor = 4, previousPoint = 0. Make these values default to zero, so that if the user is installing the app for the first time, all three are zero.
Fetch anything that needs to be added from the preload store using a predicate like:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"major > %d and minor > %d and point > %d",
previousMajor, previousMinor, previousPoint];
Everything that the fetch finds needs to be added. Add it, and you're done.
Related
I have an iOS social app that uses Firebase as the main database to store all the posts with time stamp included
What I want to achieve is to remove anything that is > 10 days old from my database.
Currently, I am checking this with this super inefficient way (The only way I know). Every time the user queries the firebase, I have swift code that also queries the ENTIRE database and delete all entries that is > 10 days old. This works but it is really inefficient...
What you're trying to do is currently best done on a server you control with a job that runs periodically to scan and delete the old items. You can use the admin SDK for that.
You should also have a index on the time field that you're using to determine how old it is, in order to optimize the query that generates the results.
I have one clarification, If I had upload a first version 1.0 of my app in ituenes app store and that app 100 users have been downloaded and using it, after one month I have added some extra features in the same app and uploading a next version eg: 1.2
Then The 100 users who have already using those application has been updated the next version.
My question is : In the first version if they have saved their data in
1. Nsuser Default
2. Core Data
Will it be deleted when updating the next version.
What will be the process, Some one could be explain.
When using Core Data if you have made changes to the data model then there are several possibilities.
First, if you don't do anything and just update the data model then when the update is applied to existing installs the app will crash when trying to access CoreData data. This is because the model it is expecting is different from the one in the database.
Second, you could get around this by manually deleting the core data store and setting up a new one. This will also get rid of all the data so possibly not a good solution.
Third, you can update your CoreData model version number. Instead of just changing the data model create a new version of the data model from the existing one.
Now, when the app detects that the data model and data do not match (like in the first version above) it will migrate the data from the old to the new version. Sometimes this is possible automatically but it may require some additional code from you to help it along.
This site goes into how the migration works... https://www.objc.io/issues/4-core-data/core-data-migration/
I am creating a core data app with preloaded data using an SQL file. I am able to create the preloaded data, insert that SQL file into the project, and there is no problem. When users open the app for the first time the pre-populated store is copied over to the default store.
However, I am thinking ahead that in future versions I will want continue to add to this database. I will want users to be able download the current version with the latest DB without erasing user-generated data or user-edits to data in the preloaded DB.
This is not a migration issue because the model has not changed. Basically, when a new version of the app is opened for the first time I want it to check for the presence of new objects in the pre-populated store and add them to the user store. Any suggestions are welcome.
Make your preloaded data include, for each object, the version where that object was first added to the preload file. Then add new data by
Look up the previous app version in user defaults. Compare it to the current version. If they're the same, stop, otherwise continue to the next step. (If there is no previous version number, continue to the next step).
Fetch all objects that were added more recently than the saved version number from step 1.
Add those objects to the user's persistent store.
Update the app version in user defaults so it'll be current next time.
You can do this check every time the app launches. You'll want to save a numeric version number in user defaults that will always increase in future versions of the app.
The simple way to record the version info in the preload file is just to add an extra field on each entity type. A more elegant way would be to create a new entity called something like VersionWhereAdded that includes a version number and a to-many relationship to objects added in that version.
My question contains two ways:
1. For example I have an app which is on appstore and containing sqlite database. After sometime I want to update app version without changing database schema. what happened when app will be updated on user's device ? would all data in old database removed or just remains with same database and data ?
2.For example I have an app which is on appstore and containing sqlite database. After sometime I want to update app version with changed database schema. what happened when app will be updated on user's device ? its must changed the DB file but how can we save old data entries those are in old DB version. I have read many posts but still confused which approach I should use.
Thanks in advance for Helping
It is quite simple. When updating the application documents folder remains intact, so you can assume that the user data continues to be available.
For case 2 make sure you do not compromise the data in your update routines at the first start after the update. The app should detect that it is in a new version and modify the schema (e.g. via SQL scripts) while taking care of not deleting user data.
I've got an iOS app which uses Core Data (SQLite on the backend). It only has one entity, 'Item'. There is a SQLite file bundled with the app, with hundreds of items pre-added, so when the user downloads the app from the App Store it already has the data.
The only entity has a BOOL favorite attribute which the user can alter, used -of course- to check if an item is among the user favorite items.
I'm planning to publish an update of the app with more items pre-built in the app bundle (a new SQLite file), but I want to keep the user favorites. As well, in this version my Core Data model will suffer a few modifications (I need some new properties in the 'Item' entity). The new set of items is a superset of the old items (an item in the old version of the app shall be in the new version, always).
I've been struggling with this a lot and I can't find a solution to this. I'm able to upgrade the data model introducing new properties into my entity while keeping the user favorites (performing a so-called lightweight migration, but then I'm not able to merge old and new items. On the other hand, I'm able to get the new pre-added items, but then the favorite-related data is discarded.
Any hint? Thank you all in advance
I finally managed to solve the problem.
I've got two NSPersistentStoreCoordinators, two NSManagedObjectContexts and two NSManagedObjectModels in my app delegate: one set to use in the application (the updated one) and another set pointing to the old store. In my app delegate didFinishLaunchingWithOptions: method I load all the user's favorites from the old store and save them into the new one. That's the only point in the app where I touch the old store.
Thank you all anyway!
I would suggest creating a second database with your new stuff in there, but without favorites. Then you pull favorites from your old database and insert them into your new one. Remove the old database and replace with the new one. That seems like the most straight-forward solution. There may be functionality built into Core Data for these situations, but chances are this is easier.