NSFetchRequest: fetch the object for which the predicate is true - ios

I have the following fetch. I want to fetch the Session object for which the predicate is true.
Am I doing this right? And how can I init/define indexPath, because it is not being recognized.
NSDate * searchDate = [formatter dateFromString:dateString];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Session" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate * predicate1 = [NSPredicate predicateWithFormat:#" timeStamp == %# ", searchDate];
[request setPredicate: predicate1];
[request setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
SessionViewController *sessionViewController = [[SessionViewController alloc] initWithNibName:#"SessionViewController" bundle:nil];
self.selectedSession = (Session *)[array objectAtIndexPath:indexPath];
sessionViewController.selectedSession = self.selectedSession;
[self.navigationController pushViewController:sessionViewController animated:YES];
[sessionViewController release];
[sortDescriptor release];
[request release];
[sortDescriptors release];

Then indexPath variable is usually supplied from a tableview delegate/datasource callback. The last two lines of code you provided should be placed in one of the following methods if you are using a UITableView.
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
The other lines should be in a method to get your data to display in the tableview.
-(NSArray*)sessionData
{
if(!_sessionData)
{
//FetchRequest stuff
NSError *error = nil;
_sessionData = [managedObjectContext executeFetchRequest:request error:&error];
//Error checking/logging
}
return _sessionData;
}
Now the following #" timeStamp == %# " will only work if the timestamp is that EXACT date to the millisecond. If this is what you want great, otherwise use a date range #" timeStamp >= %# AND timeStamp <= %# ".
Note: Your missing releases on several objects if you posted all of your code
requestsortDescriptorsortDescriptors

Related

How do I get a list of all online users in openfire/xmpp in iOS?

I am getting presence of user online / offline. this way if i need to check i have to send request every time to get presence
how would i able to check for multiple users or only online users ?
I have implement NSFetchedResultsControllerDelegate. i am getting
list of Online user in "SectionNum"=0. whenever user goes
offline/online controller's delegate method called.accordingly update
tableView.
// NSFetchedResultsController *fetchedResultsController; //instance variable
in viewWillAppear
//xmpp user array
self.xmppUserArray=[[[self fetchedResultsController] fetchedObjects] mutableCopy];
for (int i=0; i<[[self xmppUserArray] count]; i++) {
if ([[[[self xmppUserArray] objectAtIndex:i] valueForKey:#"sectionNum"] integerValue]==0) {
//this is user is online
[[[AKSGetCareerGlobalClass SharedInstance] onlineUserArray] addObject:[[[self xmppUserArray] objectAtIndex:i] valueForKey:#"nickname"]];
}
}
//also implement method
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
//remove previous data or clear array
[[self xmppUserArray] removeAllObjects];
[[[AKSGetCareerGlobalClass SharedInstance] onlineUserArray] removeAllObjects];
//get data from core data
self.xmppUserArray=[[[self fetchedResultsController] fetchedObjects] mutableCopy];
for (int i=0; i<[[self xmppUserArray] count]; i++) {
if ([[[[self xmppUserArray] objectAtIndex:i] valueForKey:#"sectionNum"] integerValue]==0) {
//this is user is online
[[[AKSGetCareerGlobalClass SharedInstance] onlineUserArray] addObject:[[[self xmppUserArray] objectAtIndex:i] valueForKey:#"nickname"]];
}
}
[[self msgTableView] reloadData];
}
-(NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController == nil)
{
NSManagedObjectContext *moc = [[self appDelegate] managedObjectContext_roster];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"XMPPUserCoreDataStorageObject"
inManagedObjectContext:moc];
NSSortDescriptor *sd1 = [[NSSortDescriptor alloc] initWithKey:#"sectionNum" ascending:YES];
NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:#"displayName" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sd1, sd2, nil];
//NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:#"displayName" ascending:YES];
//NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:#"userJID"];
//NSLog(#"My JID ====>%#",myJID);
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"subscription=='both'"];//take care about subscription
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchBatchSize:20];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:moc
sectionNameKeyPath:#"sectionNum"
cacheName:nil];
[fetchedResultsController setDelegate:self];
NSError *error = nil;
if (![fetchedResultsController performFetch:&error])
{
DDLogError(#"Error performing fetch: %#", error);
}
}
return fetchedResultsController;
}
Use the online users plugin on the server. This way you can get the online users via http.
Here is the link : https://github.com/candy-chat/onlineUsersPlugin

How do we Retrive Data Which is Saved By Using Core Data in iOS

I am New to Core Data.I have Developed an application. In my application i am having Registration, Login, Forgot password Forms.
In Registration Form i Write this code for registration.
NSEntityDescription *entitydesc = [NSEntityDescription entityForName:#"User" inManagedObjectContext:context];
NSManagedObject *newuser = [[NSManagedObject alloc]initWithEntity:entitydesc insertIntoManagedObjectContext:context];
[newuser setValue:self.registerUsername.text forKey:#"username"];
[newuser setValue:self.registerPassword.text forKey:#"password"];
[newuser setValue:self.registerConfirmPassword.text forKey:#"confirmpassword"];
[newuser setValue:self.registerMobileNumber.text forKey:#"mobilenumber"];
NSError *error;
[context save:&error];
In Login Form i write this Code:
NSEntityDescription *entitydesc = [NSEntityDescription entityForName:#"User" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"username like %# and password like %#",self.logUsername.text,self.logPassword.text];
[request setPredicate:predicate];
NSError *error;
NSArray *matchingData = [context executeFetchRequest:request error:&error];
if(matchingData.count<=0)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error!" message:#"Username and password does not match" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
else
{
NSString *username;
NSString *password;
for(NSManagedObject *obj in matchingData)
{
username = [obj valueForKey:#"username"];
password = [obj valueForKey:#"password"];
}
SecurityHome *securityhome = [[SecurityHome alloc]init];
[self.navigationController pushViewController:securityhome animated:YES];
}
}
Both were Working fine. Now i want to Display Password in Forgot password page if the user entered Username and Mobile number Correctly.How Can i Achieve this?
Set example predicate and sort orderings...
NSNumber *minimumSalary = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(lastName LIKE[c] 'Worsley') AND (salary > %#)", minimumSalary];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"firstName" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
// Deal with error...
}
You should have done some 'googling' before asking this question. Any how,Let me do it for you. Here you go.
Core Data NSFetchResult guide for developer
Ray wenderlich- Really nice tutorial
In both of the listed links, I am trying to suggest NSFetchResultControllers, as they are fast & easy. Here you can see the difference
Without NSFetchResultController,
NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:#"Employee" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
// Set example predicate and sort orderings...
NSNumber *minimumSalary = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(lastName LIKE[c] 'Worsley') AND (salary > %#)", minimumSalary];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"firstName" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
// Deal with error...
}
With NSFetchresultController
[[self managedObjectContext] fetchObjectsForEntityName:#"Employee" withPredicate:
#"(lastName LIKE[c] 'Worsley') AND (salary > %#)", minimumSalary];
These examples are for Famous employee table. Translate the code as per your requirement. If you are unable to work around with this code for any reason, let me know..
You can use this code for fetching details and pass the object to Forgot class and show there.
-(User*)getUserCredentialDetails:(NSUInteger)mobilenumber
{
NSError *error = nil;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"User" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"mobilenumber = %d",mobileNumber];
[request setPredicate:predicate];
NSArray * resultArray = [managedObjectContext executeFetchRequest:request error:&error];
[request release];
if (error != nil)
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
return [resultArray lastObject];
}

NSPredicate won't work?

I have a to-many relationship between 2 entities. Athlete(evals)<-->>Eval(whosEval). I am trying to display only the evals of the athlete who was selected. However, when I try to access the relationship through eval.whosEval, I get an undefined error. When I run the app, the table is empty, whereas if I comment out the predicate, it displays ALL Evals for ALL the Athletes. Am I missing something? Thank you.
allEvals.m
-(void)viewWillAppear:(BOOL)animated{
self.title = [NSString stringWithFormat:#"%#'s Evaluations",_athletesFullName];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSFetchRequest *athleteRequest = [[NSFetchRequest alloc] init];
[athleteRequest setEntity:[NSEntityDescription entityForName:#"Athlete" inManagedObjectContext:_managedObjectContext]];
NSError *athleteError = nil;
NSArray *results = [_managedObjectContext executeFetchRequest:athleteRequest error:&athleteError];
NSPredicate *athletePredicate = [NSPredicate predicateWithFormat:#"full == %#", _athletesFullName];
[request setPredicate:athletePredicate];
Athlete *currentAthlete = [results objectAtIndex:0];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"whosEval == %#", currentAthlete];
[request setPredicate:predicate];
NSEntityDescription *eval = [NSEntityDescription entityForName:#"Eval" inManagedObjectContext:_managedObjectContext];
[request setEntity:eval];
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"date_recorded"
ascending:NO
selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[_managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil){
//handle error
}
[self setEvalArray:mutableFetchResults];
[self.tableView reloadData];
NSLog(#"Athlete's Full Name is: %#",_athletesFullName);
}
Your predicate uses the athlete name when it should really use the athlete object:
#"whosEval == %#", self.athlete
You call
NSLog(#"This eval is for: %#", eval.whosEval);
But you declared eval as:
NSEntityDescription *eval = ...
So there is no way that class NSEntityDescription know what "whosEval" is.
Retrieve actual instance of Eval object from the mutableFetchResults and invoke whosEval on it:
if (mutableFetchResults == nil){
//handle error
} else {
[self setEvalArray:mutableFetchResults];
[self.tableView reloadData];
NSLog(#"Athlete's Full Name is: %#",_athletesFullName);
NSLog(#"This eval is for: %#", [[mutableFetchResults lastObject] whosEval]);
}

Weird NSPredicate Behavior?

I have an NSPredicate which checks the relationship of an entity called "Eval(whosEval)" and if the relationship whosEval matches the full name of another entity, "Athlete(evals)", with the athlete that was selected, it displays all the Evals for that particular Athlete. Unfortunately, my predicate is doing weird things. If I have no athletes, and then add one, then add an eval, it shows all their evals, then I add another, the second athlete won't display any evals I added for that athlete and instead displays all of the other athlete's evals. Am I doing something incorrectly? All evals view controller is displayed prior to add Eval view controller.
allEvals.m
-(void)viewWillAppear:(BOOL)animated{
self.title = [NSString stringWithFormat:#"%#'s Evaluations",_athletesFullName];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSFetchRequest *athleteRequest = [[NSFetchRequest alloc] init];
[athleteRequest setEntity:[NSEntityDescription entityForName:#"Athlete" inManagedObjectContext:_managedObjectContext]];
NSError *athleteError = nil;
NSPredicate *athletePredicate = [NSPredicate predicateWithFormat:#"full == %#", _athletesFullName];
[athleteRequest setPredicate:athletePredicate];
NSArray *results = [_managedObjectContext executeFetchRequest:athleteRequest error:&athleteError];
Athlete *currentAthlete = [results objectAtIndex:0];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"whosEval == %#", currentAthlete];
[request setPredicate:predicate];
NSEntityDescription *eval = [NSEntityDescription entityForName:#"Eval" inManagedObjectContext:_managedObjectContext];
[request setEntity:eval];
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"date_recorded"
ascending:NO
selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[_managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil){
//handle error
}
[self setEvalArray:mutableFetchResults];
[self.tableView reloadData];
}
addEval.m
-(void)saveEval{
//insert saving attributes here
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Athlete" inManagedObjectContext:_managedObjectContext]];
NSError *error = nil;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"full == %#", _whichAthletesEval];
[request setPredicate:predicate];
NSArray *results = [_managedObjectContext executeFetchRequest:request error:&error];
Athlete *currentAthlete = [results objectAtIndex:0];
[eval setWhosEval:currentAthlete];
NSLog(#"This Eval Belongs to: %#",eval.whosEval);
NSLog(#"whichAthletesEval value is equal to: %#", _whichAthletesEval);
}
NSError *error = nil;
if(![_managedObjectContext save:&error]){
//handle dat error
}
[self.navigationController popViewControllerAnimated:YES];
}
I have left inline comments (signed off with my initials) in your viewWillAppear: method that point out what I believe to be errors. Essentially, you fetch an arbitrary athlete instead of the one that's been selected (which I'm assuming is the source of _athletesFullName. As far as your saveEval method, your naming conventions are tough to follow so it's not clear to me what further issues you could have here.
-(void)viewWillAppear:(BOOL)animated{
self.title = [NSString stringWithFormat:#"%#'s Evaluations",_athletesFullName];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSFetchRequest *athleteRequest = [[NSFetchRequest alloc] init];
[athleteRequest setEntity:[NSEntityDescription entityForName:#"Athlete" inManagedObjectContext:_managedObjectContext]];
NSError *athleteError = nil;
// No predicate is used at all for the contents of results here - see below - CV
NSArray *results = [_managedObjectContext executeFetchRequest:athleteRequest error:&athleteError];
NSPredicate *athletePredicate = [NSPredicate predicateWithFormat:#"full == %#", _athletesFullName];
// This predicate never used as another predicate is set a few lines below - CV
[request setPredicate:athletePredicate];
// currentAthlete will not necessarily be the one conforming to athletePredicate
// just the first in the array of every Athlete you've fetched - CV
Athlete *currentAthlete = [results objectAtIndex:0];
// because currentAthlete is arbitrary, you're now creating a predicate you likely didn't intend to - CV
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"whosEval == %#", currentAthlete];
[request setPredicate:predicate];
NSEntityDescription *eval = [NSEntityDescription entityForName:#"Eval" inManagedObjectContext:_managedObjectContext];
[request setEntity:eval];
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"date_recorded"
ascending:NO
selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[_managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil){
//handle error
}
[self setEvalArray:mutableFetchResults];
[self.tableView reloadData];
}

Access value of an entity attribute

I have a Core Data to-many relationship that looks like this:
Athlete(evals)<->>Eval(whosEval)
I have a table view for Athletes which displays ALL the Athletes in the database. I want to set the subtitle text to a Eval attribute, let's say it is called "date_recorded" the problem is, there could be more than 1 eval for each Athlete. I need to select the last object in the evalArray, and then display the correlating Eval attribute for each Athlete, so each Athlete's subtitle text will probably be different. How would I do this for every cell in my table? Here is what i've got so far:
allathletes.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Athlete Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Athlete *athlete = (Athlete *)[athleteArray objectAtIndex:indexPath.row];
cell.textLabel.text =[athlete full];
cell.detailTextLabel.text = //eval attribute "date_recorded"
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSFetchRequest *athleteRequest = [[NSFetchRequest alloc] init];
[athleteRequest setEntity:[NSEntityDescription entityForName:#"Athlete" inManagedObjectContext:_managedObjectContext]];
NSError *athleteError = nil;
NSPredicate *athletePredicate = [NSPredicate predicateWithFormat:#"full == %#", athlete.full];
[athleteRequest setPredicate:athletePredicate];
NSArray *results = [_managedObjectContext executeFetchRequest:athleteRequest error:&athleteError];
Athlete *currentAthlete = [results objectAtIndex:0];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"whosEval == %#", currentAthlete];
[request setPredicate:predicate];
NSEntityDescription *eval = [NSEntityDescription entityForName:#"Eval" inManagedObjectContext:_managedObjectContext];
[request setEntity:eval];
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"date_recorded"
ascending:NO
selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[_managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil){
//handle error
}
NSMutableArray *lastEvalArray = mutableFetchResults;
Eval *lastEval = lastEvalArray.lastObject;
cell.detailTextLabel.text = lastEval.date_recorded;
return cell;
}
If date_recorded is an NSDate attribute, then you can just do
Athlete *athlete = (Athlete *)[athleteArray objectAtIndex:indexPath.row];
NSDate *lastRecorded = [athlete valueForKeyPath:#"#max.evals.date_recorded"];
and then use a NSDateFormatter to convert lastRecorded to an NSString and
assign it to cell.detailTextLabel.text.

Resources