issues with Searching in Core Data - ios

I am using this piece of code to find the existance of data. But i am getting this error that Use of Undeclared Identifier "appDelegate".
- (IBAction)findContact:(id)sender {
CoreDataAppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
NSEntityDescription *entityDesc =
[NSEntityDescription entityForName:#"Contacts"
inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred =
[NSPredicate predicateWithFormat:#"(name = %#)",
_name.text];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request
error:&error];
if ([objects count] == 0) {
_status.text = #"No matches";
} else {
matches = objects[0];
_address.text = [matches valueForKey:#"address"];
_phone.text = [matches valueForKey:#"phone"];
_status.text = [NSString stringWithFormat:
#"%lu matches found", (unsigned long)[objects count]];
}
}
I have included the #import <CoreData/CoreData.h> .Will I have to include some other file. When i save data it works fine.

Ensure you have imported the app delegate header
#import "CoreDataAppDelegate.h"
Try casting the AppDelegate as CoreDataAppDeleage
CoreDataAppDelegate *appDelegate = (CoreDataAppDelegate*)[[UIApplication sharedApplication] delegate];

CoreDataAppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
Replace above line to below line
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

For deleting text based on Id
#pragma mark - delete tracking details
- (void)deleteTrackingId:(NSString *)trackingId
{
appDelegate = [[UIApplication sharedApplication] delegate];
managedObjectContext = appDelegate.managedObjectContext;
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityOne = [NSEntityDescription entityForName:#"TrackingList" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityOne];
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"trackingId == %#",trackingId];
[fetchRequest setPredicate:predicate];
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
NSLog(#"Could not delete Entity Objects");
}
for (TrackingList *trackingObject in fetchedObjects) {
[managedObjectContext deleteObject:trackingObject];
}
[appDelegate saveContext];
}

Related

Store NSDictionary In CoreData ios not working

Since I get into a requirement of saving NSDictionary offline and populate the table from it when the user is offline.
This is the code I have so far:
Everytime the resulting NSDictionary was getting as nil
I have made this attribute set as transformable
+ (void) insertIntoCoredata :(NSString *) table : (NSString *) attribute : (NSArray *) dic {
AppDelegate *appDelegate =(AppDelegate*)
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
appDelegate.managedObjectContext;
NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:dic];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:table
inManagedObjectContext:context];
[object setValue:myData forKey:attribute];
NSError *error;
if (![context save:&error]) {
NSLog(#"Failed to save - error: %#", [error localizedDescription]);
}
}
+ (id) getFromCoredata :(NSString *) table : (NSString *) attribute {
AppDelegate *appDelegate =(AppDelegate*)
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
appDelegate.managedObjectContext;
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:table
inManagedObjectContext:context];
[fetch setEntity:entityDescription];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetch error:&error];
if([fetchedObjects count] == 1)
return [fetchedObjects objectAtIndex:0];
else
return nil;
}
What went wrong with this code.

Update existing object in Core Data with reference to NSArray

I fetched the objects in an core data entity. Then I cross check with a NSArray and find out what are the existing objects in the data base.
Then I insert new objects to database. I am struggling in how to update existing objects in this code. Please help me to do it in best way.
// get manageObjectContext
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSArray *arrIds = [arr valueForKeyPath:#"anId"];
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SomeEntity"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"%K IN %#", #"anId", arrIds];
NSArray *existingItems = [context executeFetchRequest:fetchRequest error:&error];
//Get the existing ids:
NSArray *existingIds = [existingItems valueForKeyPath:#"anId"];
for (NSDictionary *item in arr) {
if ([existingItems containsObject:topic[#"anId"]]) {
// update exsising item
}
else{
// Insert new items done .........
}
you can use this code!!
AppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
NSEntityDescription *entityDesc =
[NSEntityDescription entityForName:#"Qr_code"
inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred =
[NSPredicate predicateWithFormat:#"(user_ID=%#)",
kText];
[request setPredicate:pred];
matches = nil;
NSError *error;
updatedata = [context executeFetchRequest:request
error:&error];
if ([updatedata count] == 0) {
} else {
matches=updatedata[0];
}

Fetching data from entity in one to many relationship in Core data

I have 2 entities. 1 called WishListElement and other WishListContainer.
-(BOOL)addElementToWishList:(WishListElement*)element
{
ASAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
_managedObjectContext = [appDelegate managedObjectContext];
WishListElement *wishList = [NSEntityDescription insertNewObjectForEntityForName:#"WishListElement" inManagedObjectContext:_managedObjectContext];
[wishList setAppName: element.appName];
[wishList setAppPrice: element.appPrice];
[wishList setAppCategory: element.appCategory];
[wishList setAppSummary: element.appSummary];
[wishList setAppCopyright:element.appCopyright];
[wishList setAppAuthor: element.appAuthor];
[wishList setAppImage:element.appImage];
NSError *error = nil;
[_managedObjectContext save:&error];
WishListContainer *wishListContainer = [NSEntityDescription insertNewObjectForEntityForName:#"WishListContainer" inManagedObjectContext:_managedObjectContext];
[wishListContainer addContainsObject:wishList];
if (![_managedObjectContext save:&error])
{
return NO;
}
else
{
return YES;
}
}
-(NSMutableArray*)getWishListElement
{
ASAppDelegate *appDelegate = (ASAppDelegate*) [[UIApplication sharedApplication]delegate];
_managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"WishListContainer" inManagedObjectContext:_managedObjectContext];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *fetchRequest = [[_managedObjectContext executeFetchRequest:request error:&error]mutableCopy];
[self setWishListArray:fetchRequest];
WishListContainer *container = [fetchRequest objectAtIndex:0];
NSLog(#"%d",container.contains.count);
return [container.contains.allObjects mutableCopy];
}
But the problem is that when I try to display the wishlist contents using the above code, it shows an empty table view.
WishListContainer *container = [fetchRequest objectAtIndex:0];
NSLog(#"%d",container.contains.count);
return [container.contains.allObjects mutableCopy];
The above lines are showing 0. Please help me.
First of all, create an inverse relationship. As explained here https://stackoverflow.com/a/764572/3429577 it is necessary for data integrity.

Editing specific CoreData entries

Once again, since Core Data is new to me, I need assistance. Basically, I need to edit a specific Core Data object from a view outside the tableview, save it, and reload the tableview. I can manage reloading the tableview, but I cannot figure out how to find the specific Core Data object for that indexPath entry. I don't have any code because I cannot find anything to suit my purpose.
Detail (Editor)
-(IBAction)cancel:(id)sender{
NSLog(#"Sent!");
// [self dismissViewControllerAnimated:YES completion:nil];
// [self.view.superview removeFromSuperview];
OweDetails *details = info.details;
[info setValue:oField.text forKey:#"name"];
info.name = oField.text;
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.master = [[MasterViewController alloc]init];
[self dismissSemiModalViewController:self];
[self.master.tableView reloadData];
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];
}
Master (TableView)
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"I tapped myself!");
OweInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
self.tdModal = [[TDSemiModalViewController alloc]init];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
FooterViewController *fvc = [[FooterViewController alloc]init];
OweDetails *details = info.details;
[self.tdModal setDetailItem:info.name];
[self.tdModal setMoneyItem:details.money];
// [self.view addSubview:test.view];
self.tdModal.managedObjectContext = self.managedObjectContext;
self.tdModal.managedObjectContext = self.managedObjectContext;
OweInfo *info2 = (OweInfo *)[nameArray objectAtIndex:indexPath.row];
self.tdModal.info = info2;
[self presentSemiModalViewController:self.tdModal];
}
If you're using an NSFetchedResultsController, ask it for the objectAtIndexPath:.
AppDelegate* appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext* context = [appDelegate managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"YOUR_ENTITY_NAME" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SOME_PREDICATE_USED_TO_UNIQUELY_IDENTIFY_YOUR_INDEXPATH ==%#", #"VALUE"];
[fetchRequest setPredicate:predicate];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setPredicate:predicate];
NSError* error;
NSArray* array = [context executeFetchRequest:request error:&error];
if (error)
{
NSLog(#"Error fetching data. %#", error);
return nil;
}
if (array.count != 1)
{
NSLog(#"Invalid number (%d) of objects found", array.count);
return nil;
}
return [array objectAtIndex:0];
Edit: This is in response to you asking about more details.
The code above can be its own function. I will give you a simple example of how you can use it.
-- In the VC where you have the table and are displaying the data
1: Let us assume your entity is called MyEntity and that it has an integer unique identifier field called myEntityUniqueId.
2: In your cellForRowAtIndexPath, you would write:
cell.tag = myCurrentEntity.myEntityUniqueId
-- Now lets go to your other VC where you want to retrieve the instance of MyEntity represented by the cell that was tapped.
1: Write the function:
-(void) findMyEntityForId:(int) tappedUniqueId
{
AppDelegate* appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext* context = [appDelegate managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"MyEntity" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"myEntityUniqueId ==%d", tappedUniqueId];
[fetchRequest setPredicate:predicate];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setPredicate:predicate];
NSError* error;
NSArray* array = [context executeFetchRequest:request error:&error];
if (error)
{
NSLog(#"Error fetching data. %#", error);
return;
}
if (array.count != 1)
{
NSLog(#"Invalid number (%d) of objects found", array.count);
return;
}
MyEntity* foundResult = [array objectAtIndex:0]; // <-- This is the instance you are looking for.
}
2: Now call the above function with the correct argument.
I haven't tested the code but it should be fine.

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

Resources