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
Related
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
I am trying to wrap my head around CoreData. So I am having a static tableview for statistics with labels like: "number of entries", "total distance", "total time" etc. I have my coredata entity called "Recording" and its attributes "startDate","duration",... and I would like to fetch all entries from the CURRENT week and then on one hand display the number of entries and on the other hand the total time. I know how to set up a fetch request (thank you, google)
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
if (self.managedObjectContext)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Recording" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"startDate" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
frc.delegate = self;
self.fetchedResultsController = frc;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
return _fetchedResultsController;
}
but I am stuck with this special idea and I am not even sure if I need to do it with this...
I solved it now using:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *theType = [NSEntityDescription entityForName:#"Recording" inManagedObjectContext:self.managedObjectContext];
fetchRequest.entity = theType;
NSDate *firstDayOfCurrentWeek = [self firstWeekday:[NSDate date]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"((startDate > %#) AND (startDate <= %#))",firstDayOfCurrentWeek, [NSDate date]];
fetchRequest.predicate = predicate;
NSSortDescriptor *theDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"startDate" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObjects:theDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
and finding the sum/total like this:
NSFetchedResultsController *fetchedResults = self.fetchedResultsController;
NSInteger allWorkouts = [[fetchedResults fetchedObjects] count];
CGFloat totalDistance = [[[fetchedResults fetchedObjects] valueForKeyPath: #"#sum.distance"] floatValue];
Thanks for the hint with the predicate :)
NSPredicate is what you're searching for.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html
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]
in my app I am sorting an entity using only one NSSortDescriptor, but now I need to filter the data for 4 different attributes. This is the code for the current sorting, the result are all records from the entity sorted by the attribute 'displayOrder', but I need to filter the records by four other attributes(year,month,day,group), all of them integer32 except group which is string :
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController) return fetchedResultsController;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity =
[NSEntityDescription entityForName:#"FavoriteThing"
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"displayOrder"
ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc]
initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:nil cacheName:#"ThingsCache"];
aFetchedResultsController.delegate = self;
[self setFetchedResultsController:aFetchedResultsController];
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
}
I have tried adding a predicate:
NSNumber *yearSearched = 1965;
NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:#"todoYear = %#", yearSearched];
[fetchRequest setPredicate:yearPredicate];
But after running the app there is an error EXC_BAD_ACCESS at the line NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:#"todoYear = %#", yearSearched];
Where the attribute 'todoYear' is from type Integer32
Your NSNumber creation is wrong (you're just setting the pointer to an integer). It should be:
NSNumber *yearSearched = #1965;
NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:#"todoYear = %#", yearSearched];
[fetchRequest setPredicate:yearPredicate];
I am trying to pull all the Actions which belong to the latest Session.
In SQL this would be a simple JOIN ... WHERE Session.startTime = MAX(Session.startTime), but with Core Data I can't figure out how to do this without resorting to two steps as below. Any ideas?
// Step 1. Get the latest session
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Session" inManagedObjectContext:self.managedObjectContext]];
[request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"startTime" ascending:NO]]];
[request setFetchLimit:1];
Session *lastSession = nil;
NSArray *objects = [self.managedObjectContext executeFetchRequest:request error:NULL];
if ([objects count] > 0)
{
NSLog(#"max: %#", [objects objectAtIndex:0]);
lastSession = [objects objectAtIndex:0];
}
// Step 2. Get that session's actions
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Action" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sectionSort = [[NSSortDescriptor alloc] initWithKey:#"session.startTime" ascending:NO selector:nil];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"startTime" ascending:NO selector:nil];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sectionSort, sort, nil]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"session.startTime = %#", lastSession.startTime];
//**Can't I do something like this instead?**
//NSPredicate *predicate = [NSPredicate predicateWithFormat:#"session.startTime = session.#max.startTime"];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchBatchSize:10];
[self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"session.startTime" cacheName:#"ActionHistory"];
self.fetchedResultsController.delegate = self;
NSError *error;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort(); // Fail
}
Edit: I do need to stick with using NSFetchedResultsController due reasons not fully detailed above.
I would advise you to make a relationship beetwen Session and Action.
Then, after you fetch the session you need, you could get all that session's actions as easy ss lastSession.actions.
Edit
Maybe you can do
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"session = %#",lastSession];