Default fetchrequest result order changed every time - iphone

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]];

Related

NSFetchedResultsController with a one-to-many relationship

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];

iPhone iOS Core Data should I subclass an abstract entity for my entities?

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

Core data - FetchedResultController returning complicated data structures?

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.

Core Date One-To-One Sorting

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.

Is Core Data more efficient than custom indexing for "as-you-type" searching?

Actually, I'm working on a Core Data based iPhone application. I have two entities which contain more than 200000 rows each and I'm experiencing some performance issues during retrieval of data. For each fetch request, I must wait between 1 and 2 seconds before getting results.
I'm thinking of implementing a custom search engine to index my data but the problem is that the whole database is editable. The contents can be changed at anytime so indexing a dynamic content database is stupid.
I'm wondering if Core Data is efficient enough to provide instant search. In the Apple documentation, a thousand rows entity is considered as small. Is that right?
Does anyone have a solution to improve the speed of Core Data...? Or should I implement my own search engine?
The goal is to provide an instant search, a search as you type mecanism.
[UPDATE]
Below is a snippet of one of my fetch request...
NSString *predicateString = [NSString stringWithFormat:#"^(.*\\b)?%#(\\b.*)?$", searchString];
NSString *predicate = [NSString stringWithString:#"text MATCHES[cd] %#"];
NSArray *arguments = [NSArray arrayWithObjects:predicateString, nil];
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"MyEntity" inManagedObjectContext:[[HYDataManager instance] managedObjectContext]]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:predicate argumentArray:arguments]];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:#"length" ascending:YES], [[NSSortDescriptor alloc] initWithKey:#"subEntity.attr1" ascending:YES], [[NSSortDescriptor alloc] initWithKey:#"subEntity.attr2" ascending:YES], nil]];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:#"subEntity"]];
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[[HYDataManager instance] managedObjectContext] sectionNameKeyPath:nil acheName:nil];
You can try several things.
1) try using setFetchBatchSize: to reduce the working set of data in your app. In combination with an NSFetchedResultsController this will transparently faults batches on demand, showing the objects on your table as needed.
2) verify if you can use setResultType: with NSManagedObjectIDResultType. This will return only the ID of the matching objects; if you need to access just one or a few of them after performing the fetch request, then the additional overhead is really small, but the fetch is much faster. If you need to access all of the returned objects, then this is not the way to go.
3) if you instead need to retrieve the properties stored in your objects, use setPropertiesToFetch: as suggested by Hunter to retrieve only the ones you really need
4) if your model includes subentities of your entity, then verify if you can use setIncludesSubentities: passing NO as argument.
5) if you do not need to deal with all of the objects matching the predicate associated to your fetch request, then use setFetchLimit: to retrieve a fixed number of objects.
Hope this helps.
Have you tried marking all editable elements indexed in the data model? As you said it seems really odd to index everything but Core Data should be smart enough to handle this appropriately.