iOS 10+ using NSPersistentContainer - What's the best method to "clear all" - ios

We want to have a settings bundle property that can be set to delete all the information stored using core data. I see some examples that loop over all the entities and calls delete. I see some that manipulate the files storing the stores. This last way sounds better but I'm not sure how that fits into the magic of NSPersistentContainer.
On iOS 10, what's the best way to delete all the content in Core Data and continue on in the app saving new fetched data to Core Data?

I haven't tried it, but here's what I think I'd do:
Create a new directory where you'll keep your persistent store and anything else that NSPersistentContainer wants to save. Make sure to create this directory when the app launches, using FileManager. You'll use this with Core Data by...
Subclassing NSPersistentContainer and overriding defaultDirectoryURL(). Use the directory from step 1.
Now you'll be sure that everything the persistent container writes goes in a known location that doesn't contain anything else.
When you want to delete everything, just delete every file in the directory that you're using (again, using FileManager). Make sure to do this before loading any data.

Related

Change Realm file without restarting application

I'm currently using dropbox to backup the Realm database file and when i need to restore, i just delete the old file and than put the new one from dropbox in its place, but to work i need to restart the application.
So, i'm looking a way to avoid the app restart.
You could delete the current files the way Realm suggests in the docs: https://realm.io/docs/swift/latest/#deleting-realm-files
Then nil your current Realm, write the new file to the right location in your file system and create a new Realm instance. Then reload your UI to show the new data.
You'll also have to be careful that your code is not holding references to objects in the previous Realm before it gets deleted.

Migrating coreData to a clean start

I'm updating an app to a whole new version (remade). Everything is going to change to be faster and less bugy. As other post suggest I cannot create another version of the model since I don't have the app code to the previous version (I started a new project). All I have is the bundle identifier for it to be an update. I will use core data but I want to delete all the old models and old data for the users that are updating, as if they deleted the app and reinstall it. How do I achieve this? or there's no need to delete anything because is a different model? All i want is to prevent app crash on launch. thanks in advance.
If you tried to open the same persistent store file with a model that doesn't allow Core Data to make sense of it then you'd raise an exception. So probably all you need to do is use a different file — remember that you get to specify the on-disk location in addPersistentStoreWithType:configuration:URL:options:error: — for your persistent store and ask NSFileManager to delete the old one.
I don't think there's a penalty for asking to delete a file that already doesn't exist so no need for any particularly complicated logic. You'd just be duplicating what the file manager does internally anyway.
Alternatively, if you prefer to keep the same file, enclose your call to addPersistentStoreWithType:... in an #try/#catch block and in the #catch just delete the existing file and try the addPersistentStoreWithType:... a second time.

How to fetch record from sqlite database that has been created automatically when implemented in coredata

I have app in that i am using coredata. And when i install the app three files are getting created in the document directory called “test.sqlite, test.sqlite-shm and test.sqlite-wal". And now in second app i copy the test.sqlite in the folder and i want to access the database and tables but i got error like this "no such table found". Is there any issue that i create the database with coredata? please help me.
You either need to:
send all of the sqlite* files that Core Data creates
export the content from the data store, format it and send that
Option 1 should work and be fast to implement, but it isn't very future proof. Option 2 will take longer but is a much better solution.

Core data solution for read-write separate

I am doing something with core data. Since the original sqlite file contains the data in the application. I decide to do the following:
Separate the reading and writing action. Make all the reading from one data source of one sqlite file and make all the writing in another file.
Since there are some rules in the directory in iOS application, I plan to copy all the reading data from bundle to the cache directory and put the writing data in the document directory.
The question is that, is it possible to use the reading file in the bundle resource directly. Which means I don't have to copy it into the cache file and that will save some space for the device.
Or you guys have any other better idea, please tell me.
I put the write data into the document because the file in it can be backuped by icloud, which could act as a feature in my program.
You ask if what you want to do is a good idea, but first you need to think through some possible pitfalls.
I suppose the file in your bundle was also created with Core Data, and it has a MOM. The new file you write - it probably uses the same MOM. What will you do if you ever need to update the MOM? The file on iCloud will be say version 1, and maybe the users iPhone uses Version 1, but your new version 2 is loaded onto the users iPad. Now what? The ipad should not update the repository as that would make the iPhone fail when it tries to use the data - the ipad has no way of knowing if all other devices have updated or not.

How can I ship my app with a pre-populated Core Data database?

My app uses Core Data and I want some default entries to be inside.
What's best practices of how to do that?
If you're already loading the pre-load data via a temporary routine for testing in your current code there's no reason you can't use the sqlite file it creates in the simulator's directory (no need to write a separate Mac app).
If you're not already filling that db you can still write an iOS app that does it. Odds are you've already written the methods for adding data to your store so you can use them to import the pre-load data as well.
Either way you'd grab the sqlite file from the simulator's directory and add it to your app's bundle; on first launch you'll copy it into the appropriate place in the app's directory before pointing Core Data to it. If it's really large the downside is that there will be a copy in the bundle and another on disk, but there's not much you can do about that other than grabbing the data over the network.
As others have suggested, if the amount of data is small you can just import it at first launch, using the methods you've already written for adding data as part of the normal app's workflow.
See the CoreDataBooks example, which has sample code for copying a database at first launch.
EDIT: I've created a Core Data framework (read about it here: http://bikepress.org/?p=1120) that includes this feature.
I would just create a database and put add it to my target so that Xcode copies it into the app bundle. At the first launch just copy it from the app bundle to eg. the documents directory or wherever your app expects the database.
There is Core Data Editor at the app store. Alternatively you could build your own simple mac app just for this particular DB and manage it from there. If the amount of default entries is small, then you're better off storing it in a plist or something and loading it into DB after the first launch.
In iOS 5, my app was rejected if I put a database file into resource bundle. So, I have to download the database from internet instead.

Resources