NSFetchController and many-to-many in coredata - ios

For better understanding my problem imagine your facebook friends; I have one entity "user" and I use that for displaying relationship between friends;
I don't know how to get friends of concrete user using NSFetchRequest
I have two "to many" relationship(see above) and I try to get friends using NSPredicate, but in the end array is empty.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = (NSEntityDescription *)[_dbManager userEntity];
[fetchRequest setEntity:entity];
User *userByUid = [_dbManager userByUid:_currentUid];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:#"sortId" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(friends IN %#)", userByUid];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchBatchSize:10];
NSArray *array = [_fetchedResultsController.managedObjectContext executeFetchRequest:fetchRequest error:nil];

You have to use the inverse relationship and "ANY":
[NSPredicate predicateWithFormat:#"ANY beFriendsWith == %#", userByUid]

Related

Join and Group by SQL to NSFetchRequest Statements

I am using core data first time and facing issue in fetching data from two Tables/Entity.
SQL is as below which is working fine:
Select * from ZMESSAGE msg Left Join ZCONTACT c ON c.ZCHANNEL = msg.ZCHANNEL group by msg.ZCHANNEL Order by msg.ZDATE
Can you please suggest, How to write in NSFetchRequest Statement?
My Entity as below:
I have tried some cases and last one is as below:
NSFetchRequest* fetchGroupSummary = [NSFetchRequest fetchRequestWithEntityName:#"Message"];
NSEntityDescription* entity = [NSEntityDescription entityForName:#"Message" inManagedObjectContext:self.managedObjectContext];
NSRelationshipDescription *groupName = [entity.relationshipsByName objectForKey:#"channels"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"date" ascending:YES];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"channels.channel == channel"];
[fetchGroupSummary setEntity:entity];
[fetchGroupSummary setSortDescriptors:#[sortDescriptor]];
[fetchGroupSummary setPropertiesToFetch:[NSArray arrayWithObjects:groupName, nil]];
[fetchGroupSummary setPropertiesToGroupBy:[NSArray arrayWithObject:groupName]];
[fetchGroupSummary setResultType:NSDictionaryResultType];
[fetchGroupSummary setPredicate:predicate];
NSError* error = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchGroupSummary error:&error];
return results;
Thanks

core data :fetching data from entity

i have to use following query for fetching data:
SELECT * FROM t1.guides AS t1 JOIN guide_category_int AS t2 ON t1.id = t2.guide_id WHERE t2.category_id = 'category_id' AND t1.start_date >= 'today()' AND t1.end_date <= 'today()' ORDER BY t1.name ASC
How can I use this in core data?
Your fetch request will be something like this:
NSManagedObjectContext *context = ...
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Guides" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"guide.category_id == %# and start_date >= %# and end_date <= %#", #"category_id", [NSDate date], [NSDate date]]];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[sort release];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if ([fetchedObjects count] > 0) {
//...
}
[fetchRequest release];
Also you can enable SQLDebug to see raw sql requests, and play with predicate and sort descriptor as you want. How to enable described there

select one to many relation in core data fetch don't work

i used this code to select all products that related to specific category but it doesn't work ,, what is the correct predicate that i can use to get all products related to this category
NOTE:
i get the categories list from server alone and insert them ,, and then get products list from server and inserting them ,, but i figured out now that the product don't know his category ,, i'm using restkit library to parse and insert in the database ,, so how i can tell the products that the category ,, the restkit do all the work automatically
how to set to the product list thet i get from server their category ?
//--fetching inserted Results from core data
// Getting products
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"productId" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor , nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// NSPredicate *predicate = [NSPredicate predicateWithFormat:#"category = %# ",tempCategoryHolder];
// [fetchRequest setPredicate:predicate] ;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Product"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
fetchedObjectsProducts = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
I would do it like this, assuming tempCategoryHolder holds a categoryId:
NSError *error = nil;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Product"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"category.categoryId = %#", tempCategoryHolder];
fetchRequest.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"productId" ascending:YES]];
NSArray *fetchedObjectsProducts = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
Otherwise update the predicate to refer to category object, or different category attribute.

Core Data - Fetch last objects of an array of objects?

Using below code, I am fetching an array of emails from Core Data. I pass an array of emailId as the predicate to the fetch and it returns all emails for each of the emailIds.
However, I only need last object (or last email) of each of the emailIds in the predicate. Currently, I take the output of this fetch and use separate sorting to filter the objects I want. However, I would like the filtering in this fetch itself. Is there any way to do that?
- (NSFetchedResultsController *)getLatestEmail:(NSArray *)emailId
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"email_id IN %#", emailId];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Emails"
inManagedObjectContext:self.context];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"last_update_timestamp" ascending:NO];
NSArray *sortDescriptors = #[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:self.context
sectionNameKeyPath:nil
cacheName:#"Master"];
aFetchedResultsController.delegate = self;
self.emailFetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.emailFetchedResultsController performFetch:&error])
{
NSLog(#"getLatestEmail failed %#, %#", error, [error userInfo]);
}
NSArray *emails = [[self.context executeFetchRequest:fetchRequest error:&error] mutableCopy];
return _emailFetchedResultsController;
}
I tried adding .lastobject to [[self.context executeFetchRequest:fetchRequest error:&error] mutableCopy], but didn't work. I couldn't also find any documentation that suggests that this is possible. However, I am sure, someone would have tried it before and would like to hear their opinion.
Invert your sort descriptor, then just set the batch size to 1 and the offset to zero.

How to update data available in coredata?

Here I got the value in fetchedObjects. How can I update the value in the array?
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Reserve" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
//NSSortDescriptor tells defines how to sort the fetched results
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"number" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSLog(#"sort count%d",[sortDescriptors count]);
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(number = 100)", self.txtReserve.text];
// [fetchRequest setPredicate:predicate];
[fetchedResultsController.fetchRequest setPredicate:predicate];
self.fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSLog(#"Count of array::::%d",[fetchedObjects count]);
NSManagedObject *device = [fetchedObjects objectAtIndex:0];
NSLog(#"device::::%#",device);
I suggest that you read/watch some of the many books/tutorials on Core Data. You are missing a very basic understanding of the technology.
First, the objects you receive represent objects in the database, you have to know the entity descriptions to get the data. For example, the most basic way to get the "number" attribute of the "Reserve" entity would be...
[managedObject valueForKey:#"number"];
If you use Xcode (or a tool called mogenerator) you can have subclasses generated for your entities, and can more easily access the data via custom accessor methods.

Resources