How to observe managed object context - iphone

Whenever i make a change in the objects in the first tab of my application the updates are automatically upated in tab 2 becuase it uses a fetchedResultsController. Now i have a third tab that should also update itself, but how can i do that?
I only have a nsmangedObjectContext in the third tab to get the appropriate data. How can i receive notifications whenever the objects in this context change?
I am also struggeling with the question how i can make my data fetching more efficient, becuase tab 2 and 3 use the same set of data. I am currently making another fetch in tab 3, to get the same data as tab 2. I dont know how i can use the data from tab2 without disturbing the fetchedresultscontroller.
Information on this subject would really be appreciated!!

If your tableviews are very closely related, then you can just have a single UITableViewDataSource that provides data for both of them, and have it manage the NSFetchedResultsController. From your description, this case seems very likely.
If the tableviews are not very similar, such that having a single UITableViewDataSource would create excessive if() logic, then move your NSFetchedResultsController into an separate model object and post NSNotifications when it receives delegate call-backs. Your UITableViewDataSources can then observe those notifications to update themselves when they are on-screen.

Related

Using KVO to reload data in UITableView

I've been expanding my horizons recently and am trying to start utilizing KVO more in my programming.
I have a view controller in my iPhone application which acts as the datasource and delegate for a UITableView. I also have a singleton model controller which coordinates populating my model with data fetched from the web.
In my view controller, I request that the model's controller load new data from the web. Then I can observe the "dataset" property of the singleton and receive KVO notifications when items are added to or removed from the set.
Now, each cell in my table view has an indicator which specifies whether the content in that cell has been read or not (like the blue "unread" dot in mail). Like mail, when a row is selected, I'll display details about that row. In the viewDidLoad for the detail view, I set the object's "read" property to YES. I would like the original view controller to be able to observe this "read" property of each object in the dataset, so that [tableView reloadData] can automatically be called as necessary and redraw the cells without the blue dot.
In researching this, I found the following link: http://homepage.mac.com/mmalc/CocoaExamples/controllers.html#observingACollection
According to this, it looks like I will do the following:
1) Be an observer of the array
2) Whenever I get a notification of a change to the array, I add (or remove) myself as an observer for the individual properties I am interested in.
3) When I get a notification of a change to the property I'm interested in, I can call [tableView reloadData]
I'm currently in the process of attempting to implement this approach. Can anyone with experience doing this offer some advice on this approach? If this the best way to handle this type of situation?
If this is the correct approach, would anyone be willing to share their implementation of adding/removing the observers for objects in the collection when the collection changes?
Thanks!
I think you can accomplish this task by using Core Data and the Fetched Results Controller.
I'm sure this can save you a lot of work.
Here's a good guide: Ray Wenderlich Core Data Tutorial, getting started

Disable animation of UITableView with NSFetchedResultsController when many rows are being changed

In my UIView I've got a UITableView (UITV) which is controlled by an NSFetchedResultsController (NSFRC). The UIView is inside a UINavigationController.
When the view is about to be loaded/displayed I start some background activities which fetch data from a remote server (JSON) and parse into Core Data.
The NSFRC is being called when the parsing is done and the threaded NSManagedObjectContext have been merged into the main context.
The problem is that sometimes many rows are being inserted to Core Data at once, a lot of table cells are being added and there is quite a delay from that the actual fetching and parsing is done, until the rows are being displayed.
Now I wonder if anyone knows of any solution to, for example:
hook up a spinner to some "fetched results controller inserted all its rows for this time" (or something) notification/delegate call to at least tell the user that "something is going to show up soon"?
Or might the best solution simply be to not initialize the NSFRC until the background fetching and processing is completed?
Thanks!
If I understand your question correctly, you may want to look into the NSFetchedResultsControllerDelegate methods, with documentation available here: http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html
There are delegate methods available for pre changes with controllerWillChangeContent:, post changes with controllerDidChangeContent and during changes with didChangeSection: and didChangeObject.
I hope it helps!
Rog

Getting a UIButton to send commands to another View Controller

Question..
I'm currently making a conversion app. I have for the first tab where the information is entered. Views 2 and 3 are where the information from view 1. I'm having an issue.. I'm not sure how to send the information from view 1 to view 2 and 3.
I've looked at examples.. but I'm still not quite grasping the idea of it. any suggestions?
Thanks!
Instead of thinking in terms of sending information between views, create a "model object" that contains all the data that is shared between views, and let controller classes take care of updating the views when the model is changed.
Also, take a look at the documentation for NSNotificationCenter for a way to "broadcast" data updates throughout your app.

NSFetchedResultsControllerDelegate in a second view controller (not firing?)

I am running into an issue similar to the one described here: NSFetchedResultsControllerDelegate not firing
(the delegate for my NSFetchedResultsControllerDelegate are not being called on my second view controller)
I can't seem to get the proposed solutions to work. I have a main view that loads information from Core Data just fine, but when it pushes a separate controller (and passes the managed object to it), the delegate methods won't fire. I've read about 'mergeChangesFromContextDidSaveNotification' but I don't understand how to synchronize the two manage objects and/or get the delegate methods to be called.
Any help would be greatly appreciated. Thank you,
Mike
Note sure I understand your problem exactly but a NSFetchedResultsController only calls its delegate when something changes in the part of the Core Data object graph that the controller monitors. Simply passing a managed object between two view controllers doesn't change the Core Data graph itself and therefore does not fire the the delegate methods.
To fire the delegate you have to make a change to the data that the fetchedResults controller monitors. This means changing one of entities that the fetchedResults controller fetches. You either have to add or remove an instance of an entity or you have to change an attribute or relationship of an existing entity.
...but I don't understand how to
synchronize the two manage objects
and/or get the delegate methods to be
called.
From your description, you don't have two managed objects but just one that is passed from the first view controller to the next. Perhaps you meant managed object context?
mergeChangesFromContextDidSaveNotification:
... is a method of NSManagedObjectContext and is only used when you have need to combine the data from two separate context. That is an advanced operation that you only use when you are trying to integrate the data of two independent context. For example, when you are updating a database to a new version.

Building a list of favorites from Core Data

I'm building an app with two tabs. The first tab has a main tableview that connects to a detail view of the row. The second tab will display a tableView based on the user adding content to it by tapping a button on the detail view.
My question is this. What is the correct design pattern to do this? Do I create a second ManagedObjectContext/ManagedObjectContextID then save that context to a new persistent store or can the MOC be saved to the existing store without affecting the original tableview?
I've looked at CoreData Recipes and CoreData Books and neither deal with multiple stores although books does deal with multiple MOC's. Any reference would be great.
A single NSManagedObjectContext is more than sufficient for this design. What you want to do is implement the dependency injection design pattern. What this translates to is that when you create each of your tabs, you pass the singular NSManagedObjectContext instance into each of them. Each NSViewController is then responsible for accessing the NSManagedObjectContext as needed.
update
If you are seeing the same data then that is an issue with your 'NSFetchedResultsController' and not the 'NSManagedObjectContext'. The 'NSManagedObjectContext' has access to all of the data, the 'NSFetchedResultsController' is what does all of the filtering based on it's 'NSFetchRequest'.
Perhaps you should post the 'NSFetchedResultsController' for each of your controllers (by editing your question here) so that we can see what is going on.
update
The MOC does not get destroyed, at all, ever. You simply have more than one reference/pointer to the same MOC. The MOC is the scratchpad for the NSManagedObject instances that you are accessing. When you call -save: on that MOC, it takes the changes in that scratchpad and persists them out to disk.
Except in some very, highly unusual, situations, you only ever need one MOC per thread. In your design that you have described so far, one MOC is more than sufficient.