Search for the index of a Core Data array that contains a certain date attribute - ios

I have been looking around everywhere online and can't seem to get a solid answer. If I have an event with multiple attributes stored in Core Data in an array and I can display all of these individual events in a tableView. Lets say one of the attributes is a date. Is there away to search for all of the events that contain a certain date and display only those in the tableView? I was thinking of using NSPredicate from what I am seeing online but I am not familiar with this. Maybe somehow find the index of the event that contains that date and only display that index? Any ideas?

Table views are designed to implement a one to one relationship with the underlying array of data. The usual approach is to use a fetchRequest to only get the data you want to display ( I personally like to have all my requests pre-defined in the data model so I can keep track of how data is accessed).
But, if your array of managed record must contain more elements than what you want to display, you should consider basing your tableView datasource responses on an intermediate array that only contains (or refers to) the objects you want to show.
For example:
let allEvents:[EventRecord] = GetAllEvents()
var filteredEvents:[EventRecord] = allEvents.filter({ $0.eventDate.isEqualToDate(dateToDisplay) })
and use filteredEvents as your underlying store for your datasource.
This will make it easy to dynamically change the filtering conditions and reload the tableview without having to go back to the database for each filter change.

Related

Advice - How to model detail list

I am working with a single TableViewController
The object that is displayed in TableViewController is Task
struct Task{
var type: String
var children = [Task]()
}
I store the base Task objects in a TaskStore. The TaskStore has a member pivot, which I use to track the current element in TaskStore. By Default, pivot is -1, and the TableViewController lists all objects in TaskStore. When a user clicks on a row in the TableViewController, I update pivot with the selected row, and display the Task objects in TaskStore.sharedInstance.get(pivot).children. The back button sets pivot back to -1 and displays the base TaskStore.
I am worried that this is overly complex. It works without a real problem, but I do need to add an exception whenever Pivot is not -1.
Is there a more suitable way to display the children of a Task object in TaskStore without the need to create a new TableViewController?
Thanks for any advice
The reason you are unhappy is that you are doing a lot of complicated work in your cellForRowAtIndexPath to pick up the right data. It has to interpret the pivot and dive appropriately into the task store. I suggest you forget all that. Knowing how to dive into the task store is not the business of the table view's data source!
What I would do, therefore, is separate the overall hierarchical model from the table's actual data source. The data source, at any given moment, should just consist of an array of Tasks, a [Task].
The problem then devolves into maintaining that array. When the user taps a row, you can replace that array of Tasks with whatever you like and call reloadData. In this way you maintain a direct correspondence between the table rows and tasks array. cellForRowAtIndexPath just asks for the info from that row of the Tasks array and it's done. Simple and clear.
Meanwhile, the work of knowing about your hierarchy all happens in the TaskStore, which is not, itself, the data source for the table. You might also need some sort of pointer into the TaskStore saying what the currently displayed parent is, but again, that bookkeeping will happen outside the array and outside the knowledge of your cellForRowAtIndexPath.
You thus end up with encapsulation of functionality. The task store understands its internal hierarchy and how to fetch a desired set of tasks. The table view knows how to grab its rows using a simple one-to-one correspondence with the current tasks list.

How to use NSFetchedResultsController and UISearchController together?

I have a view that contains a tableView. I'm using NSFetchedResultsController to display my results from Core Data.
I'd like to add a UISearchController (not a UISearchDisplayController as this one is deprecated in iOS 8) but I don't know how to link them.
Should I have only one NSFetchedResultsController or two?
I guess there is a way to fetch all the data with the NSFetchedResultsController and then just sort them according to the UISearchController am I wrong?
Thanks for the help you can give me on this.
A few thoughts...
When you create the resultsController for the searchController, you can pass to it the data that you wish to search. If you are using an NSFetchedResultsController in your main table, you could pass the fetchedObjects array. Then in response to changes to the search text, you filter the array (you could use a predicate and filteredArrayUsingPredicate to create a separate array with the search results, or you could iterate through the array to build it). The disadvantages of this route are that (unless you implement it manually) the search results will not be broken into separate sections, and the search results will not update automatically if the underlying data changes (eg. on a background thread).
I guess you could have a second NSFetchedResultsController: that would facilitate using sections, and could potentially permit the results to be updated automatically (using the delegate methods) if your data is being updated in the background, for example. But I would be nervous of the complexity that it introduces.
Another option, if you opt to apply the search in situ (i.e. specify resultsController = nil), would be to use the search criteria to update the NSFetchedResultsController itself (i.e. amending the underlying predicate and reperforming the fetch). That way your search table looks and feels exactly like the main table (including sections, if you use that) but the rows displayed obviously reduce as the search criteria become finer. This option needs care to ensure that the FRC is properly rebuilt, and might be unacceptable performance-wise, if you have a large dataset.

ios UITableView with fetchedresultscontroller - add custom rows

I have a UITableView with data coming from NSFetchedResultsController.
Here is my tablewView:
I need to add a row "All types". It also needs to be:
Sortable with all other items
Selectable (Design is now selected)
Selecting "All types" should deselect other rows
Give something to understand that it's an "All types" row when selected
I've read Add extra row to a UITableView managed by NSFetchedResultsController and NSFetchedResultsController prepend a row or section. Given approaches makes impossible to sort data or will look so hacky and produce so much hard-maintailable code, that it will be impossible to change logic and maintain code.
Are there any other good options?
PS. I understand, that my question may sound "broad" and doesn't containt code, but I think it's very common problem.
I do not think this is a very common problem at all. I can see it seems natural to do what you are trying but lets analyse your situation: What you generally have are 2 arrays of objects which you wish to sort as a single array. Now that is quite a common situation and I believe everyone knows how to solve this issue. You need to create a single array of objects and then sort it.
The way I see it you have 3 options:
Fetch all the items, merge the 2 arrays, sort and present them. This is not a very good idea since your memory consumption can be a bit too large if there are a lot of items in the database.
Put the extra data into the database and use a fetch result controller as you would normally. This should work good but you will probably need to mark these items so they are later removed or keep it in the database but ignore them where you wish not to display them.
Create a temporary database combined with what needs to be fetched from the database and your additional data. This approach is great if your data are meant for read-only in this list (which actually seems to be the case in what you posted). Still it is best if you create some kind of link between the objects. For instance some kind of ID would be great, this way when user selects an object from the second database you simply read the ID and fetch the object from the original database.

Can I (or Should I) use NSFetchedResultsController for One Table Section?

I have one section of a table which will display an initial set of comments, and then as new comments are entered and merged into core data, it will display those as well. I could simply tack all the new comments onto the end of the current array using a standard fetch, but I would also like to handle any potential comments that were added in the meantime, and may be mixed into the sort order of the current comments.
I was trying to decide how easiest to do all of this with NSMutableOrderedSet, but really nsfrc already does everything I need, except it works with multiple sections.
Is it wise to try and shoe-horn that in there?
If you are using Core Data, NSFetchedResultsController should probably be used for all your table views which display core data entities. Even those which are not updating in the background.
In this case you do have things being merged in the background, so NSFetchedResultsController is the logical and correct choice.

Insert extra row into UITableView like Tweetbot iOS

I have NSFetchedResultsController like datasource of my UITableView. It displays some entities with predicate from my database. I try to find an elegant solution to insert utility row between my data rows. I don't want to create fake entity in my database cause I don't want to mix View and Model. But I need to have ability to recreate this utility row (e.g. on other application launch). Any suggestions?
It should look something like this:
You're best bet, in my opinion, is to use a section header or footer for that "utility" row. In the case of Tweetbot, they're most likely caching results locally and then merge in data when the plus button is tapped. Your table will take multiple data sets as arrays (an array of arrays) and treat each separate array as a chunk and put it into its own section.
Any way you implement you'll want to wrap your results from the database with some sort of metadata. I think you're going to have to get away from a fetched results controller, unless you use a separate instance for each chunk, keeping track of the date range for each chunk.

Resources