I have a core data model that has two entities, Bid and Result.
I want them sorted initially in a section where the bid has no result i.e. the relationship from Bid to Result is nil, then I want this sub sorted by date.
Ideally I would have two sections:
Bids with no Result sorted by date
Bids with a result sorted by date
Due to the relationship being potentially nil I see very erratic results. Using two NSSortDescriptors first sorting on the relationship and then on the date will work for a few entries then seems to randomly blow up.
E.g.
NSSortDescriptor *sectionSortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"result" ascending:YES];
NSSortDescriptor *dateSortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date" ascending:NO];
How should I sort entities by a relationship that could potentially be nil?
A nil should evaluate to zero and non-nil to non-zero so you can sort on nils. I think the problem maybe elsewhere.
I would suggest trying to sort just with the nils and see if that works. That at least will tell you where the problem is.
Related
I'm looking to display data from a Core Data model in a UITableViewController. Model has two entities, with a one-to-many relationship. I want the items from the many entity to be the rows, broken down into sections by the one. In the event no rows exist, I still want the section header to display.
I have a working NSFetchedResultsController table working for the many table only, but I need to expand it to the one-to-many relationship. I'm having no luck making that work, and haven't found any examples on how to do this.
The table will display all items, not a subset.
Any suggestions?
Since you didn't provide any details about the model objects your using, my example will use the following model.
The first thing I would suggest doing is look at the documentation for NSFetchedResultsController, specifically initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:. it tells you everything you need to know about fetching you data into sections.
The important part is that the first sort descriptor must return a similar order as the sectionNameKeyPath.
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Book"];
NSSortDescriptor *librarySort = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSSortDescriptor *bookSort = [[NSSortDescriptor alloc] initWithKey:#"title" ascending:YES];
[fetchRequest setSortDescriptors:#[librarySort, bookSort]];
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context
sectionNameKeyPath:#"library.name"
cacheName:nil];
i am simply do a executedFetchRequest for an ENtity say #"tanId" it contiains 5 records 1,2,3,4,5
--> problem is first time it shows like 2,3,4,5,1
--> if again running it shows like 4,2,1,3,5
super dooper good
any one tell how to rectify this problem.
You can use an NSSortDescriptor to sort your NSFetchRequest. Otherwise, order is not guaranteed. There are some examples in the Fetching Managed Objects section of the Core Data Programming Guide.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"firstName" ascending:YES];
[request setSortDescriptors:#[sortDescriptor]];
Currently I have the following data model in my app:
Record is an abstract entity with timestamp, type, name. I have 3 types of entities that subclass Record. My NSFetchedResultsControllers pull Record objects and I sort them by class in my table views:
Event1 has record as abstract parent, there will be 10000 such events
Event2 has record as abstract parent, there will be 100 such events
Event3 has record as abstract parent, there will be 100 such events
Event 1 is generated by the system, while events 2 and 3 are created by the user.
The intention of this system is so it is easier to display data when all data is required.
However, I'm running into an issue where I want to display only partial data - user-created events and allow the user to edit them.
I'm wandering if my current data model is an effective way of filtering and displaying only user events (core data would have to separate only a handful events from the system-generated events). Should I make the system-generated events a separate entity? Should I even worry about things like this, or is core data optimized enough so stuff like this does not matter?
Below is the NSFetchedResultsController that made me ask this question:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
//system-generated events do not have type defined, while user events do have a type
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"SELF.type > %0"];
[fetchRequest setPredicate:predicate];
//^What are the performnance implications of the above predicate?
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:#"Master"];
Alex,
If all you want are the user events then just use a fetch request on that entity, not the superclass.
Andrew
How to obtain an ordered list of coredata managed objects via accessing them via a relationship?
That is:
have the following entities: LIST, LIST_ITEM (includes an 'Order' field), and ITEM.
assume that I have already fetched the list I want to work with
I can then use the coredata relationships to get the LIST_ITEMS via using the relationship: e.g. "list1.listItems", and then for each of these LIST_ITEMS I can get the ITEM ("listItem1.item")
But if I really just want, from the LIST, an ordered list of ITEMS from the list, based on the "Order" field in the LIST_ITEM, what is the easiest way of doing this?
You can sort the items returned by the relationship using an NSSortDescriptor just as you would in a regular fetch request. For example:
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"order" ascending:YES] autorelease];
NSArray *sortedListItems = [list1.listItems sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
The key method here is [NSSet sortedArrayUsingDescriptors:]
I think that I understand the question correctly, but I think the best way to get lists from CoreData is create a compoun predicate and then search for items that way. For example if I am looking for only Events (entity) on a certain day, for a specific User (another entity). Then I can create an NSFetchRequest for the Event entry and specify and NSPredicate in the form of (user.name==%#) AND (event.date==%#) specifying the user's name and date
So I have the following structure.Basically a tree view.
Each node has a set (NSSet of nodes), each node is a object that contains an NSDate.
-4
-1
-3
-2
-5
-7
-6
-8
Is it possible to write a Core data query that returns the following result (Each node contains information about it's parent)
{1,2,3,4,5,6,7,8}
Items in each level should be sorted by date
Have you tried NSSortDescriptor... for ex:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"timeStamp" ascending:NO];
More tutorial from this site.
Short answer; no.
First, Core Data works with objects not raw values like this.
Second, a NSFetchedResultsController is designed to return a set of objects that are of the same entity type and potentially separated into sections. What you are describing is a multi-level structure and does not fit into the goal of the NSFetchedResultsController.
Update
If you are just looking to get back a NSArray of XEntity sorted by yProperty without regard to the parent/child relationship within XEntity then you don't need a NSFetchedResultsController. Just create a NSFetchedRequest with the -setEntity: set to XEntity and add a NSSortDescriptor that sorts on yProperty and execute the fetch against the NSManagedObjectContext.
If you want to be updated when that data changes then you would want to use a NSFetchedResultsController with that same NSFetchRequest.