I wonder when I should use Core Data and when I just should keep it easy and use delegate variables?
Delegate is a design pattern, CoreData a persistence framework. You are comparing things, that are not compare-able.
Edit
Delegate:
A delegate is an "entry point" where an objects allows you to define some custom action.
It is similair to callbacks in some language or interface in Java.
Technically a delegate is just a pointer to an object that conforms to a defined protocol
Delegation is a simple and powerful
pattern in which one object in a
program acts on behalf of, or in
coordination with, another object. The
delegating object keeps a reference to
the other object—the delegate—and at
the appropriate time sends a message
to it. The message informs the
delegate of an event that the
delegating object is about to handle
or has just handled. The delegate may
respond to the message by updating the
appearance or state of itself or other
objects in the application, and in
some cases it can return a value that
affects how an impending event is
handled. The main value of delegation
is that it allows you to easily
customize the behavior of several
objects in one central object.
CoreData
CoreData is a Framework for organizing persistence data.
In simplest terms, Core Data is an
object graph that can be persisted to
Disk. [...] Core Data can do a lot
more for us. It serves as the entire
model layer for us. It is not just the
persistence on disk, but it is also
all the objects in memory that we
normally consider to be data objects.
—Marcus Zarra, Core Data
Related
I am writing an app that has a form spread across multiple ViewControllers and a main menu with the submit button on it that opens an e-Mail with the text fields data displayed in it, the only problem i have is that the text boxes don't 'remember' what's been written in them when switching between sections of the form. I have had a look through threads regarding persistent data but have found nothing. I want my application to remember what's been entered in the text fields when switching between views so it can populate the e-Mail with the data but then 'forget' the data again when the user minimises the app. Any advice or pieces of code would be much appreciated.
So create a data model singleton and have your view controllers read/write their values from properties of that singleton.
(In viewWillAppear, fetch a pointer to the model singleton and install values from properties of the singleton into your VC's fields. When the user changes a value in a field, have your VC modify the corresponding property of the singleton.
You can write your singleton to listen for the "will enter background" notification and archive it's settings to disk, and make it's init method try to read saved values from disk (or set the values to a defined starting state if they have never been set). You can use NSUserDefaults, NSCoding, or a variety of other approaches for archiving your data.
There are lots of options to persist data. I currently favoring Realm, but previously I've used Core Data, YapDatabase, and even simply serializing objects to disk. Note that if this is your first foray into saving data on iOS, I strongly advise AVOIDING Core Data, as it is very complex and Feature Rich (also, difficult to use correctly until you know it fluently). I recommend you start with serializing objects yourself, then either Realm or YapDatabase.
You should create a singleton NSObject class and keep data in that class ... As singleton objects hold data until the application is terminated.
I am currently using singleton instances to access and maintain various NSObject in the app.
For instance, I have :
VariableStores, that maintain several objects such as currentUser (custom NSObject), lastLocation (CLLocation), etc.
TaskManager, containing a NSMutableArray of NSOperations that have failed in order to be re-executed later (such as Instagram with failed upload).
If I kill the app, singleton instances are destroyed and :
- some data must be retrieved from the server side (for instance, the currentUser) which increase the length duration
- some data cant be retrieved from the server-side, such as the NSOperation in the TaskManager (as they are only managed locally)
Thus, I would like to go further and maintain that kind of objects even if the app is totally killed.
What should I consider as a good practice? Serializing object into NSUserDefaults and deserialize ? Is there other best practices?
In case of serializion, serializing objects in -applicationWillTerminate delegate and deserializing them in appropriate -init methods of singleton (that are instantiated in the appDidFinishLaunching) can be considered as acceptable ?
the idea of singleton pattern is just to transfer data between controllers without worrying about details ..
what you need to do is a persisting data of your App ..
you can use core data if you see that the data that you need to store is a little big for plists.. or you can use sqlite but that will give you a little pain for writing a lot of sql statements..
or you can use regular plist or nsUserDefaults (i don't like that option) but it's a little slow if the data is too much ..
you can save this data when app go to background or terminated..
I have an NSManagedObject subclass to represent a person on Flickr. I have to grab all the properties to be stored in Core Data of the internet with a URL request. I want to put the functions to grab the data off the web in the Person class. However, the request will be done asynchronously, and the properties will be set on the object in a completion block. Will this cause an error because Core Data is not thread safe?Would it be best to have a seperate class for loading, or would the NSManagedObject Subclass work?
I would put it in a separate class. Not so much for the different threads issue (which is relatively simple to solve by using NSManagedObjectContext's performBlock: method), but for your separation of concerns. The data model should just store the data. It shouldn't have to worry about downloading it. Create a class that downloads the data, and then pass raw data to the NSManagedObject subclass (a method named +objectFromDownloadedData:(NSData *) comes to mind) to create an actual data object that your app can work with.
You could put networking code in an NSManagedObject subclass.
It would be spectacularly poor design to do so, however. Putting networking code in a model class is just terrible app architecture. It could work, but it will be some of the ugliest, most awful code ever seen on iOS.
task details:
I'm developing an app that communicates with 1-30 hardware devices simultaneously, each device has it's own tcp connection.
Therefore I created an entity "hardwareObject" which shall represent some properties of that device, e.g. value1 and value2.
I created a connection handler class which I defined as a transient attribute of my "hardwareObject" entity. On UI changes the core data object is modified and the core data object itself tells it's connection to send changes of value1 or value2.
I want to inform an instance of "hardwareObject" when new data arrived via a delegate method, therefore it's a delegate of it's attribute.
I'm wondering if making a NSManagedObject a delegate of s.th. is a good practice?
Might that cause any problems regarding faulting or other core data related things?
Or should I better create a sharedInstance master connection handler object which takes care of each of the connection handlers and talk to my core data objects only on demand?
That's a totally valid design. NSManagedObjects may be managed by their (managed object) context, but if you retain an NSManagedObject it will remain valid, and you're free to implement any special business logic in that class or make it a delegate. In fact, one of the resounds that Core Data allows you to subclass NSManagedObject is such that you can do these things.
Just make sure to unregister your class as the delegate if you need to delete the object from the context.
It sounds like a bad idea. Delegates need to exist for at least as long as the object they are a delegate for, and you don't have control over the lifecycle of managed objects - this is taken care of by the context.
As you mention in your question, faulting could also be an issue - any state information could disappear at any point, again, out of your control.
In addition, this sounds like quite a serious violation of MVC, if that concerns you.
I have a navigation based application using Core Data and several levels of drill-down navigation. At the last level of the navigation I add records to the managed object store.At each level of navigation I create an array of view controllers for the next UITableView.
My question concerns the placement of the Core Data stack methods which create the managedObjectContext, managedObjectModel and the persistentStoreCoordinator.
Do I create these methods in the highest level view controller that needs to fetch data from the persistentStore and then pass a context object to the lower level viewcontrollers? Do I also need to pass a coordinator?
Many questions seem to point to putting these methods in the App Delegate but then many answers say "Do Not" put them in the app delegate. So where is the best place for these methods and which objects need to be passed to allow all necessary levels to fetch from the data store?
First, some pre-requisites:
If you're building an application that uses Core Data, then you will most probably encounter situations where you will need to have more than one managed object context (MOC) around. You will however need one MOC that will "live" throughout the whole application session. Call that your main MOC (since you'll be accessing it from the main thread only!!).
More rarely and depending on your application, you may also encounter situations where you will need more than one NSPersistentStoreCoordinator. In my answer I will stick to the case where a single coordinator is required. As for your NSManagedObjectModel, that is entirely dependent on your application. Usually, you only need one of those.
To answer your questions:
I suggest having your main MOC be owned by the AppDelegate, since the latter is a singleton that lives for as long as the application lives. You can put the methods for creating/saving the main MOC in the AppDelegate, or delegate these tasks to a utility class. I find the second option a little cleaner, as you can use that utility class to add methods that create other MOCs on the fly, or to get a reference to the main MOC, from any controller in your application. That way, you avoid calling the AppDelegate all the time.
Note also, that if you already have a NSManagedObject in your hands, you can get the reference to the MOC that it's registered with, simply by calling [yourManagedObject managedObjectContext]. Once you have the MOC reference, you can get the associated NSPersistentStoreCoordinator and NSManagedObjectModel references. (This is to answer your question about "passing the coordinator": I prefer working with NSManagedObjects and the NSManagedObjectContext since they are at the top-most level of the abstraction, instead of passing around the coordinator or the model).
Hope this helps!
Apple puts the Core Data stack in the app delegate which works for the majority of cases.
It sounds to me like you are under utilizing Core Data. It sounds like your app design just uses Core Data to persist some data after you've gone down a hierarchy of views that are populated by arrays. Although you can get this work, you lose a lot of the automatic functionality of Core Data.
Core Data is not primarily about saving data. Instead it is an API for creating the model layer in a Model-View-Controller design app. As such, Core Data usually comprises the actual logical "guts" of the application. Apple puts the stack in the app delegate because it is assumed that Core Data will be used throughout the app.
In the standard design, you would use Core Data to populate all your views so you would need Core Data at the top an bottom of any hierarchy.