When I update my CoreData model, it crashes the app, So I have to delete the old app, and then reinstall. That's fine with me, but my question is: How do I tell my customer that they must delete the app before they reinstall? This seems too complicated...I am just adding 1 additonal field to a models and that's it.
Is there a better way to deal with this?
Thanks
You need to set up database migration... To upgrade a customer's existing data to the newest data model when they update. For some changes Core Data can do it for you. For others you'll have to write the migration code yourself.
Perhaps start here: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/Introduction.html
Like #Nielsbot said, there's a migration system that Core Data uses.
You can create new versions of your model and select which one to use. There's a little bit of code to change in your AppDelegate method where the persistent store coordinator loads the model to tell it to load versions. I'd suggest you read Apple's documentation on how to implement this at: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/Introduction.html
If you're just adding one field to a table then you can create a new version of the database. Keep the current one unchanged.
In one of the menus there is a create new data version or something.
Make the changes in the new version.
There are numerous tutorials about how to do this.
If you release an update that crashes the app then apple won't approve it so you will have to so this anyway.
Related
I have a cloudant database with a lot of deleted docs. Since they can't be destroyed, I would like to make a filtered copy with the non deleted items to a temporary base, destroy the original one, and copy the temporary base to a fresh database with the same name as before.
The problem is when I destroy the base, the API keys generated are also destroyed...
So the front app calling the new base can't acces it !
I would like to manually create a user/password, so I can recreate the same user each time I destroy the database.
I don't know how to do it ?
Or is there another way to achieve my goal ??
To answer your actual question, you can't add "users" to a Cloudant account, only databases. You can, however, make API-keys that span multiple databases, which sounds like it could be what you want:
https://dx13.co.uk/articles/2016/04/11/using-a-cloudant-api-key-with-multiple-cloudant-databases-and-accounts/
But as was noted by bessbd above, if your data model relies on document deletion, you're working against the grain of Cloudant, and sooner or later you'll end up with problems.
And finally -- the doc links appear to work just fine.
Maybe some useful stuff here: https://blog.cloudant.com/2019/11/21/Best-and-Worst-Practices.html
[disclaimer, I wrote that]
Can you please expand a little further on your use case? Why do you want to get rid of the deleted docs? Is there a way to avoid deleting the docs? Also, have you already read https://cloud.ibm.com/docs/services/Cloudant?topic=cloudant-documents#tombstone-documents ?
I am using realm with the react-native app I am currently working on. The problem I am facing right now is that I need to rename or delete an old model and migrate the data to a new model.
Everything works nicely after I create new models, but when I look at Realm Browser to see new data, I can still see data with the old removed model.
I tried deleteAll with realm before inserting new data, and it doesn't seem to remove data with old model.
E.g. the app used to have a model names Car, but now I want to be more specific with Truck and Sedan, etc. So I create the new models, remove the old model Car, but I can still see data with Car after launch.
I am wondering if there is a way to delete the stale data. I tried doing migration, but since the schema does not have the old model, realm cannot refer to the stale data to delete them.
Realm.compact() removes the space left behind by deletions. Compacting works if there are no open Realm instances.
This will be added to the API in the version that comes after 1.10.3.
realm-js folks have exposed a method called Realm.deleteModel on Realm to delete model during migration. This should solve the problem of having stale data after migration when removing/renaming a model.
See https://github.com/realm/realm-js/issues/1268 for more detail
I have the following scenario:
I'm starting development of a long project (around 6 months) and I need to have some information on the database in order to test my features. The problem is that right now, I don't have the forms to insert this information (I will in the future) but I need the information loaded on the DB, what's the best way to handle this? Specially considering that once the app is complete, I won't need this process anymore.
As an example, lets say I have tasks that need to be categorized. I've begun working on the tasks, but I need to have some categories loaded on my db already.
I'm working with Rails 3.1 btw.
Thanks in advance!
Edit
About seeds:I've been told that seeds are not the way to go if your data may vary a bit, since you'd have to delete all information and reinsert it again. Say.. I want to change or add categories, then I'd have to edit the seeds.rb file, do my modifications and then delete and reload all data...., is there another way? Or are seeds the defenitely best way to solve this problem?
So it sounds like you'll possibly be adding, changing, or deleting data along the way that will be intermingled amongst other data. So seeds.rb is out. What you need to use are migrations. That way you can search for and identify the data you want to change through a sequential process, which migrations are exactly designed for. Otherwise I think your best bet is to change the data manually through the rails console.
EDIT: A good example would be as follows.
You're using Capistrano to handle your deployment. You want to add a new Category, Toys, to your system. In a migration file then you would add Category.create(:name => "Toys") or something similar in your migration function (I forget what they call it now in Rails 3.1, I know there's only a single method though), run rake db:migrate locally, test your changes, commit them, then if it's acceptable deploy it using cap:deploy and that will run the new migration against your production database, insert the new category, and make it available for use in the deployed application.
That example aside, it really depends on your workflow. If you think that adding new data via migrations won't hose your application, then go for it. I will say that DHH (David Heinemeier Hansson) is not a fan of it, as he uses it strictly for changing the structure of the database over time. If you didn't know DHH is the creator of Rails.
EDIT 2:
A thought I just had, which would let you skip the notion of using migrations if you weren't comfortable with it. You could 100% rely on your db/seeds.rb file. When you think of "seeds.rb" you think of creating information, but this doesn't necessarily have to be the case. Rather than just blindly creating data, you can check to see if the pertinent data already exists, and if it does then modify and save it, but if it doesn't exist then just create a new record plain and simple.
db/seeds.rb
toys = Category.find_by_name("Toys")
if toys then
toys.name = "More Toys"
toys.save
else
Category.create(:name => "More Toys")
end
Run rake db:seeds and that code will run. You just need to consistently update the seeds.rb file every time you change your data, so that 1) it's searching for the right data value and 2) it's updating the correct attributes.
In the end there's no right or wrong way to do this, it's just whatever works for you and your workflow.
The place to load development data is db/seeds.rb. Since you can write arbitrary Ruby code there, you can even load your dev data from external files, for instance.
there is a file called db/seeds.rb
you can instantiate records using it
user1=User.create(:email=>"user#test.com",
:first_name=>"user",
:last_name=>"name",
:bio=>"User bio...",
:website=>"http://www.website.com",
:occupation=>"WebDeveloper",
:password=>"changeme",
:password_confirmation=>"changeme",
:avatar => File.open(File.join(Rails.root, '/app/assets/images/profiles/image.png'))
)
user2=User.create(:email=>"user2#test.com",
:first_name=>"user2",
:last_name=>"name2",
:bio=>"User2 bio...",
:website=>"http://www.website.com",
:occupation=>"WebDeveloper",
:password=>"changeme",
:password_confirmation=>"changeme",
:avatar => File.open(File.join(Rails.root, '/app/assets/images/profiles/image.png'))
)
Just run rake db:seed from command line to get it into the db
I have just done a quick search and nothing too relevant came up so here goes.
I have released the first version of an app. I have made a few changes to the SQLite db since then, in the next release I will need to update the DB structure but retain the user's data.
What's the best approach for this? I'm currently thinking that on app update I will never replace the user's (documents folder, not in bundle) database file but rather alter its structure using SQL queries.
This would involve tracking changes made to the database since the previous release. Script all these changes into SQL queries and run these to bring the DB to the latest revision. I will also need to keep a field in the database to track the version number (keep in line with app version for simplicity).
Unless there are specific hooks, delegate methods that are fired at first run after an update I will put calls for this logic into the very beginning of the appDelegate, before anything else is run.
While doing this I will display "Updating app" or something to the user.
Next thing, what happens if there is an error somewhere along the line and the update fails. The DB will be out of date and the app won't function properly as it expects a newer version?
Should I take it upon myself to just delete the user's DB file and replace it with the new version from the app bundle. OR, should I just test, test, test until everything is solid on my side and if an error occurs on the user's side it's something else, in which case I can't do anything about it only discard the data.
Any ideas on this would be greatly appreciated. :)
Thanks!
First of all, the approach you are considering is the correct one. This is known as database migration. Whenever you modify the database on your end, you should collect the appropriate ALTER TABLE... etc. methods into a migration script.
Then the next release of your app should run this code once (as you described) to migrate all the user's data.
As for handling errors, that's a tough one. I would be very weary of discarding the user's data. Better would be to display an error message and perhaps let the user contact you with a bug report. Then you can release an update to your app which hopefully can do the migration with no problems. But ideally you test the process well enough that there shouldn't be any problems like this. Of course it all depends on the complexity of the migration process.
It would be useful for many people to know how to completely remove an application from your device when testing.
I have downloaded my app many times now, and likewise have deleted it many times. The problem is when deleting the app, it does not remove things like the persistent object related to my app, or the images downloaded through the app. So, when I download the next build, I have no idea if something broke that is related to building the persistent object or fetching the images since those elements already exist from the last build.
I don't know if this is a cache thing. I don't know if this is expected and I have to use some utility to wipe this data after deleting the app. I can't really find much info through basic web searches.
Any information would be appreciated.
Blackberry Bold 9000. 4.6 OS. tested with both SD card and no SD card.
Objects stored in the PersistentStore are automatically deleted on uninstall if their interfaces were defined in your project. If they are from the standard BlackBerry API then they will stick around until they're deleted. E.G if you save a String in the PersistentStore it will stay in the PersistentStore but if you save a class you created it will be deleted on an uninstall. So if you want to have those objects be deleted automatically just create a wrapper class and save that.
Images stored on the filesystem will not be deleted until you or some application deletes them. However, it should be easy for you to write an app that clears everything out.
Another solution you could implement is making your app somewhat self-aware of its data.
Create a simple String value that you persist (or optionally, persist it in a Hashtable so you can store many properties this way) that includes "Version".
At startup of the GUI app, compare the stored "Version" against the application's current version. If the stored version doesn't exist, or if it exists and matches, take no action.
If it exists and does not match, automatically clean up old persisted data; or alternatively prompt the user to see if they want that data to be deleted (which one is better will depend on your implementation)
You can also use CodeModuleListener to listen for an uninstall event -- when that happens, you can clean up at that time as well or instead.
(As an aside and a bit of shameless self promotion, I am actually currently working on a shareable library for Blackberry that makes managing persistence much easier, as well as desktop data backup/restore. I'm doing this as part of the BBSSH project, but I'll be splitting it off into a separate library of core components and publishing it under a dual GPL/optional commercial license. It will contain hooks for data cleanup and data versioning. )