Multiple NSFetchedResultsController's with one UITableView? - ios

Visually I have a UITableView with a UISegmentedControl to allow 'mode' selection which will change the table's sort order .
Using NSFetchedResultsController's I am thinking I should keep a separate controller for each different sort configuration then swap between which one is being displayed based on the currently selected 'mode'.
However I can see this will get tricky with 4 different NSFetchedResultsController all sending delegate messages to update the UITableView. To deal with this I am planning to use a switch() block in each of the relevant methods to ignore all but the currently 'active' NSFetchedResultsController.
Does this sound like the right approach or am I missing something obvious here?
-I can see potential for disaster if the user changes the 'mode' just as an update comes through (ie between controllerWillChangeContent: and controllerDidChangeContent:)

I've used a segment control to change sorting/grouping in several Core Data apps. In all of them, I've always just used a single NSFetchedResultsController, and re-queried the database when the segment changes.
As you correctly realized, it is a far simpler implementation that way, fewer chances of unexpected errors, and is also more scalable. E.g. what if I decide to add a new sorting/grouping segment based on customer feedback? How many NSFetchedResultsController's are you going to keep adding? At some point (5 or 6) it just becomes ridiculous.
Also graver's comment above that you could set all of their delegates, except the "active one" to nil won't scale (you would have to modify many lines of code to make all the other delegates nil, which will make maintaining the code hard.
So my suggestion is to go with the simpler implementation, which is a single NSFetchedResultsController, and recreate it every time the segment changes. If you're interested in caching, you could use a separate cache name for each segment. A unique cache name can be generated for each segment by concatenating something like:
[NSString stringWithFormat:#"Cache_%d", segment_index]

Isn't it more logical when the segmented control's selected index is changed, to change the sort descriptors and performFetch?
self.fetchedResultsController.fetchRequest.sortDescriptors = [NSArray ... ];

Related

what's the best way to get notified when entity updates (when saved) in Core Data?

There's an article object that I am trying to keep monitoring in one ViewController. From my research there are couple of ways to achieve this but I am not sure which one is the most suitable one:
1, let the ViewController (or repository or viewModel if we are talking about clean architecture) be an observer to listen to the notification when core data saves.
2, in my Core Data abstract layer, add a completion block callback for when save() is called.
3, Use NSFetchedResultsController. I know this is designed for UITableView and UICollectionView, but I have seen people use this just to do the monitoring.
Among these 3 paths I am incline towards the third one but I am not 100% sure if that's the best practice since most people use it 1 to 1 on UITableView or UICollectionView.
If you want to observe when the object is changed, 1 and 2 will not necessarily help you.
You could do 3 - NSFetchedResultsController is very powerful - but you could also do the same thing that NSFetchedResultsController does internally, and it might be simpler:
You could register as an observer of NSManagedObjectContextObjectsDidChange.
It's posted once per pass through the run loop, if changes have been made, after the side-effects of such changes have been worked out. So it's safe to use if many changes are expected -- you'll only be notified once -- and double-ended relationships will be consistent.
It has a rich userInfo dictionary. Your task could be as simple as: check the userInfo's NSUpdatedObjectsKey and NSRefreshedObjectsKey for your object, and if it's there, refresh the views. Then check NSDeletedObjectsKey and NSInvalidatedObjectsKey too, and if your object is there, dismiss the view controller or return it to an "empty" state.

In Xcode, is there a way to set up a table which is not for UI but like an 'engine' for processing data

I'm wondering if there is some sort of way to set up something similar to a spreadsheet in Xcode. I'm trying to create a 'tapping game' or a 'clicker game' and storing so many variables in regular coding would be really tough.
Having this 'table' would enable me to keep track of multipliers and upgrade levels instead of clogging my coding with it.
Preferably, I could then just tell my code what to pull and what to look for off of the table. The table would be an 'engine' of sorts and it would not be UI. The table would do all of the work behind scenes, then show it through UI based on labels and buttons.
As traxido is saying, without more details we can't point you to a concrete example/solution. Base on the title the answer is yes. It's not a ui component though. It doesn't even need to be one.
What you want is a data structure to hold your data in a way that's convenient to access (save and retrieve). You could create a class which is a composite of other data structures like arrays and dictionaries and possibly other data structures. You might end up having many questions before you're through.
So: the answer is yes. Try it yourself and ask new questions if you get stuck.
Provide the code and error messages and I bet you quickly get answers.
Yes, you can.
Create a shared or singleton instance and retain all the data in instances of it.
(or) create a custom data structure and overide set or get methods to autoprocess the exiting data everytime you add or delete data element
Ex: If you want to maintain an array thats is always sorted. MySortedArray is the custom structure that inherits NSMutableArray and maintain a protected NSMutableArray instance. Overide addObject method to ensure sorting it whenever a new object is added.

Implementing many similar views with similar input fields

I'm writing an app that tests some RPCs sent over a tcp transport to some connected hardware. There are approximately 35 different RPCs with varying inputs.
The user selects one of the messages they want to send and a view controller is pushed that asks for input specific to that RPC. The inputs for the RPCs can change based on what the user has done previously during the session. Some common UI objects used would be text, sliders, and pickers.
My question is about code organization. Right now I can think of two broad strategies for implementing this application.
The first is to use storyboards and create a custom view controller for every one of the messages. This is probably the easiest and most understandable, but messiest implementation.
The second is to create a custom view controller that responds to messages to layout input fields and build RPCs. This requires a model backing each of the different types of RPCs and some long case statements to differentiate between the different types.
Does Objective-C have a common design pattern for handling this type of situation?
One nice way of handling this is to use a tableview. Write a cell for each of your possible input types (these might do their layouts in code or be backed by NIBs). Register all the cell types with the table view, and return the ones you need based on the current RPC from -tableView:cellForRowAtIndexPath:.
I'd probably just generate a list of strings that describe the inputs when the view is first loaded with a new RPC, and reference that to figure out which cell is needed for a given indexPath.

Notification when UITableView changes

I often have a UITableViewController with an edit button, which I like to disable when there are no rows in the table. To keep this in sync, I enable/disable the button every time something happens that might update its dataSource - adding the first row, deleting the last row, in viewDidLoad, etc. Whenever I add some new functionality that can affect the contents of the table, I have to remember to incorporate this logic.
Is there some delegate of the UITableView that I can use to simplify this? A way to know whenever the table (or it's dataSource) is modified, where I can check the number of items in the dataSource and enable/disable accordingly.
Alternatively, any other approaches would be welcomed.
You are the data source. So you do know whenever the data source changes, if you care to know. In other words, the reason you're having this problem is that you're treating the model (in the model-view-controller architecture) as an alien being. Instead, treat the model as something of your own. Take charge of your model. For example, is the model an array? Then wrap it in a class of your own, to which all commands to change the array must be given. That way, it can emit a notification whenever it is told to change the array.
It is also possible under certain circumstances to use Key-Value Observing to get notified when something changes, and you could look into it, but with primitives like arrays and dictionaries it is possible that this will be more trouble than it's worth. Again, you're likely to be happier wrapping your model storage in your own class, whose observability via KVO you can manage yourself.

How do I Handle NSFetchedResultsControllerDelegate updates for custom results view

I am currently working on a CoreData based iPhone app with a map view that will have its annotations generated from an NSFetchedResultsController. The idea of the map view is that it will show a number of saved locations for the user.
One of the advantages of using an NSFetchedResultsController is that I can set my map view as a delegate on NSFetchedResultsController and get notified of any changes made to the set of saved locations that happen on another device or on a website when the user is logged in.
I am currently having a bit of trouble getting my head around how to deal with a number of different kinds of updates that are sent to my NSFetchedResultsControllerDelegate implementation. The documentation: http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html doesn't seem to tell you how these different updates should be handled as it seems more geared towards integrating with a UITableView, which does most of the work.
I am keeping an NSDictionary of my annotations that maps them to the NSIndexPath inside the result set. The issue is, for example, when I receive 10 move, 3 insert and 4 delete updates, what order should I process these in? Some of these indexPaths will have a number of conflicting indices and the order in which they are processed will have an affect on the actual annotations I need to move, insert or delete. If I perform all the move updates first, then the insert indices will cause the final order to be different to their final order if I inserted first.
Are there any existing small libraries/classes that will translate a set of indices prior to an update to a set of post update indices given those update messages? If not, can anyone explain how this stuff works so I can write my own?
Any help will be greatly appreciated!
The flow of the NSFetchedResultsControllerDelegate methods for one update cycle is like this:
controllerWillChangeContent: (called once)
controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: (called X times)
controllerDidChangeContent: (called once)
Every call to the didChangeObject method will be about just one object / indexPath. You should apply the changes in the order that you receive them via those calls to didChangeObject. That will keep them consistent.
If you are using sections, you could also have calls to controller:didChangeSection:atIndex:forChangeType: intermixed with the object changed calls.

Resources