I have a User Class and UserType Class.
User Entity Structure and UserType Structure is listed below.
UserTypes.Type can be employee, student or any other thing.
NSFetchRequest *userRequest=[[NSFetchRequest alloc] initWithEntityName:#"User"];
NSSortDescriptor *sortByName=[[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
[req setSortDescriptors:#[sortByName]];
userFetchController = [[NSFetchedResultsController alloc] initWithFetchRequest:userRequest managedObjectContext:self.managedContext sectionNameKeyPath:#"newRelationshilp.type" cacheName:nil];
[userFetchController performFetch:nil];
Now, if the Employee type wants only 5 results it should fetch first 5. If the "Student" type wants only 1 , it should only fetch the first one. So, in short, the showNumberOfEntries should be considered as limit for every type that is fetched.
For solving of you're problem you should use fetchLimit of the NSFetchRequest
[userRequest setFetchLimit:5];
Related
Want to sort by name which have one to one relationship using NSSortDescriptor in NSFetchedResultsController. Here my code
NSFetchRequest <studentDetail *> *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[studentDetail entityName]];
NSSortDescriptor *sortDescriptorForSchoolName = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(#selector(schoolName))
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *sortDescriptorForSchool = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(#selector(school))
ascending:YES];
[fetchRequest setSortDescriptors:#[sortDescriptorForSchool, sortDescriptorForSchoolName]];
[fetchRequest setFetchBatchSize:4];
NSManagedObjectContext *mainContext = [[coreDataManager sharedManager] managedObjectContext];
NSFetchedResultsController *FRC = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:mainContext
sectionNameKeyPath:nil
cacheName:nil];
[FRC setDelegate: self];
NSError *fetchError = nil;
if (![FRC performFetch: &fetchError])
NSLog(#"fetch error: %#", fetchError);
[self setStudentDetailFetchedResultsController: FRC];
Example DB format:
School and student are entity name.
School relationship with student one to many.
Total 4 school. Each school have 4 student.
Now I want to show all student list with name ascending sort.
In UITableView I am showing student details. There is a option to sort students are sort by school entity. In my FRC have studentDetail. How can I sort those details with FRC?.
From studentDetail entity have one to one relationship with school.
Update
school entity one to many
school1
relationship
->student1
->student2
->student3
->student4
school2
relationship
->student5
->student6
->student7
->student8
school3
relationship
->student9
->student10
->student11
->student12
school4
relationship
->student13
->student14
->student15
->student16
student entity one to one
student1
relationship
->school1
student2
relationship
->school1
student3
relationship
->school1
student4
relationship
->school1
student5
relationship
->school2
student6
relationship
->school2
student7
relationship
->school2
student8
relationship
->school2
student9
relationship
->school3
student10
relationship
->school3
student11
relationship
->school3
student12
relationship
->school3
student13
relationship
->school4
student14
relationship
->school4
student15
relationship
->school4
student16
relationship
->school4
Got answer from thanks to #RunLoop. But this need few change which I want.
As I mention in my code for to sort NSStringFromSelector(#selector(school)) like, example: [NSSortDescriptor sortDescriptorWithKey[NSString stringWithFormat:#"%K.%K", NSStringFromSelector(#selector(school)), NSStringFromSelector(#selector(schoolName))] ascending:YES] Instead of [NSSortDescriptor sortDescriptorWithKey:#"school.schoolName" ascending:YES]
If I use this kind of method, In feature if I change any name in entity it's show warning and static one school.schoolName doesn't. Is that possible?
I tried this method with NSPredicate that doesn't show any warning. How should I solve this?
The following code will fetch the students, ordered by schoolName then by studentName:
NSFetchRequest *fr = [NSFetchRequest fetchRequestWithEntityName:#"Student"];
NSSortDescriptor *schoolNameSD = [NSSortDescriptor sortDescriptorWithKey:#"school.schoolName" ascending:YES];
NSSortDescriptor *studentNameSD = [NSSortDescriptor sortDescriptorWithKey:#"studentName" ascending:YES];
fr.sortDescriptors = #[schoolNameSD, studentNameSD];
NSManagedObjectContext *moc = [[coreDataManager sharedManager] managedObjectContext];
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fr
managedObjectContext:moc
sectionNameKeyPath:nil
cacheName:nil];
[frc performFetch:nil];
If you only want to sort by studentName, simply remove the schoolNameSD and ask frc to perform the fetch again.
I'm trying to build app with UITableView with data from NSFetchedResultsController. The problem is - I need to show some additional data from other models in table view.
Assume I have 2 models: Students and Groups (I think the relation is obvious: group consists of many students and student can be only in one group). I'm trying to build UITableView with list of groups. I would also like number of students in each group.
(NSFetchedResultsController *) fetchController {
if (!_fetchController) {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"GroupModel" inManagedObjectContext:[NSManagedObjectContext MR_defaultContext]];
[fetchRequest setEntity:entity];
NSPredicate *messageInChatPredicate = [GroupModel getMyChatsPredicate];
[fetchRequest setPredicate:messageInChatPredicate];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
_fetchController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[NSManagedObjectContext MR_defaultContext] sectionNameKeyPath:nil cacheName:#"main"];
_fetchController.delegate = self;
}
return _fetchController;
}
I wonder how I can I add additional information (such as number of students in each group)?
Why not just use group.students.count to get the value from the group entity? You only need one fetchedResultsController and I think you will find Core Data performance is fine.
Your terminology is a bit confusing, usually a model is a core data model created in Xcode and has a number of entities e.g. Group, Student. Sometimes you can use two different models and/or different versions of the models.
Your objects are usually know as Entities and both would belong to the same Core Data model.
EDIT:
To get the count of subgroups, such as girls or boys you can do the following
NSMutableArray *boys = [[NSMutableArray alloc] init];
[NSPredicate predicateWithFormat:#"gender = %#",#"MALE"];
[boys addObjectsFromArray:[group.students filteredArrayUsingPredicate:predicate]];
NSLog(#" boys count is %d", boys.count);
Assuming of course that gender is an attribute of Student.
Create another NSFetchedResultsController that is responsible for the other model (i.e student).
You have basically two options to get additional information such as the number of students in each group.
The first option is to count the students in the Group-Student relation. To serve this request the NSManagedObjectContext will load all students in memory to get a suitable result. Personally, I don't really like this option.
The second option is to store the number of students who belong to a group in a property of the group so that it can be directly add. Yes, you have to maintain the correct number manually. Depending on the amount of data that has to be loaded, this approach is more preferable. Crucially since it's way fas
I am using an NSFetchedResultsController to display data in a table. The data store contains lots of rows that have a groupID, and multiple entities can share a groupID.
Each entity has an insertion date property as well.
I would like to get a list of distinct groupID ordered by the insertion date property. The following code works, except it is not sorted by the insertion date property. I assume that since that property is not one of the ones being fetched, it is not available for sorting.
And I am using MagicalRecord as well, fwiw.
Is there a way to use other properties of the entity for sorting but not have them as part of the result? Adding in the insertion date to the fetched properties makes distinct superfluous since the dates are all unique as they are.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"userID like[c] %#", THEUSERUSERID];
NSFetchRequest *fetchRequest = [AnEntity MR_requestAllWithPredicate:predicate];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setPropertiesToFetch:#[#"groupID"]];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"inDate" ascending:NO];
[fetchRequest setSortDescriptors:#[sortDescriptor]];
_frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[NSManagedObjectContext MR_rootSavingContext] sectionNameKeyPath:nil cacheName:nil];
Chadbag ... I had the same problem. I researched the setPropertiesToFetch and found out it requires an NSArray of NSPropertyDescriptions ... not just the attribute name.
I think if you REMOVE this:
[fetchRequest setPropertiesToFetch:#[#"groupID"]];
and ADD this:
NSDictionary *entityProperties = [entity propertiesByName];
NSPropertyDescription *propDescription = [entityProperties objectForKey:#"groupID"];
NSArray *propArray = [NSArray arrayWithObject:propDescription];
[fetchRequest setPropertiesToFetch:propArray];
That should work for you ... it did for me!
I've done some reading up on multiple similar issues and sites and I just cannot make any understanding of this.
I have a NSFetchedResultsController which displays information from a user adding information into a ModalViewController with text fields. The user is presented with a ModalView and they put in some words into the fields, click save and that makes up the single sectioned row of tables in the TableView, which implements the NSFetchedResultsController protocol.
What I would like to do now is:
On one of the text fields, be able to create a new section out of the information provided in that one textField.
My fetchrequest is:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Transaction" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"whoBy.name" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
The attribute I want to do display is occasion.date, which means it is a relationship from the Transaction entity to the Occasion Entity (occasion) and the createdDate is an attribute on the Occasion entity.
I can see the sectionNameKeyPath:nil needs to be updated, but what do I update it to, and also do I have to change any of the datasource methods, titles, etc?
Any help on this would be massively appreciated.
Thanks,
The precise answer depends on what should be displayed as section headers and how the
sections should be sorted.
But generally, you have to add a property to the entity, which is then used as sectionNameKeyPath parameter. In addition, you have to add a first sort descriptor
using the same key (this condition can be relaxed slightly).
For example, if you simply add a string attribute sectionName to the entity and use
that as sectionNameKeyPath and as the first sort descriptor key, then all objects
with the same value for sectionName will be grouped into one section,
and the sections will be sorted by sectionName.
The remaining
sort descriptors are used to sort the objects within each section.
Another example would be to define a separate entity "Section" with a string attribute
"title" and an integer attribute "index", add a to-one relationship "section" from
"Transaction" to "Section", and use section.index as sectionNameKeyPath.
Again, all objects with the same section are grouped together, but the sections are
now sorted by the value of section.index, and you can modify
tableView:titleForHeaderInSection: so that the title is displayed in the section
header instead of the index.
This is quite general, but I hope that it gets you started.
I have data model, with 4 entities:
1. abstract entity "Term"
2. two inherited entities from "Term" - "Section" and "Type" with defined relations to "Seminar" Entity
Here is my model (can't attach image here due to low reputation): core data model
I'm fetching entity "Term" and everything was fine.
How can I write predicate to fetch entities where in inherited entities set "seminars" count > 0 ?
[NSPredicate preditcateWithFormat:#"seminars.#count > 0"] of course isn't working, because there is now definition of this relation in abstract "Term".
I've allready tried to move relationships "seminar" to abstract "Term", but I can't figure out how to define relations from "Seminar" entity to "Type" end "Section".
BTW, I'm using fetchedResultController in such way for UITableView cells/section/updates/notifications magic. I can filter results programmatically and fill controller model myself, but if there is any way to stay in core data paradigm it will be great.
In some moment Xcode get crazy and crashed until I've discarded all changes to the model.
My code is rather simple:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Term" inManagedObjectContext:self.managedObjectContext];
fetchRequest.entity = entity;
fetchRequest.fetchBatchSize = 20;
NSArray *sortDescriptors = #[[[NSSortDescriptor alloc] initWithKey:#"vid" ascending:NO],
[NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)]];
fetchRequest.sortDescriptors = sortDescriptors;
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"vid" cacheName:CACHE_NAME];
Thanks for help.