Based on your experience, for an iOS app which uses only one main-thread only NSManagedObjectContext, what is the best way to persist user settings and cached data from server to disk with respect to reliability and performance?
I see next options:
Currently we use the 1st option, so I can say that the reliability of it is very good, the data is saved even after Xcode terminate the app during debug session, but performance may suffer when app become more and more complex, esp. when changes to DB can happen at any moment of the app's flow due to async loading of data from server.
On the other side saving at certain events of the app (exit, going to background etc) will give the best performance, but can you say from your experience that it is enough to make sure that user will not loose the data?
The persistent store should be located in the AppData > Library > Application Support directory. In this example you should see a SQLite database with extension . sqlite. It is possible that you don't see the persistent store in the Application Support directory.
To save an object with Core Data, you can simply create a new instance of the NSManagedObject subclass and save the managed context. In the code above, we've created a new Person instance and saved it locally using Core Data.
A persistent store is a repository in which managed objects may be stored. You can think of a persistent store as a database data file where individual records each hold the last-saved values of a managed object. Core Data offers three native file types for a persistent store: binary, XML, and SQLite.
I think you should save often, because it's more reliable (you won't lost data if the app crashes) and you can save free up memory occupied by modified but unused objects.
At the same moment you don't want to overwhelm db with your save requests.
My suggestion is to expose two methods in interface file and choose which one you want to call depending on the situation you have.
- (void)save {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(save) object:nil];
[_storage save:nil];
}
- (void)setNeedsSave {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(save) object:nil];
[self performSelector:@selector(save) withObject:nil afterDelay:1.0];
}
Also, have you considered using second managed object context with private queue? You can set it up as a parent context and save / fetch data in background: http://www.cocoanetics.com/2012/07/multi-context-coredata/
Saving the context in the UIApplicationDelegate
methods applicationDidEnterBackground:
and applicationWillTerminate:
has always been fine for me. I also save in special circumstances like a big data import or something similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With