I just cant seem to figure out how to update core data object after I fetch the object that I want to modify.
This is what I'm trying to do :
1) Find 1st object from core data matching predicate conditions :
NSInteger storeId = 235; //find object with this id in core data
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[self.managedObjectContext persistentStoreCoordinator]];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Store"
inManagedObjectContext:context];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"id == %i",storeId];
[request setPredicate:predicate];
NSArray *results = [context executeFetchRequest:request error:NULL];
2) If match found, update matching object (This is where I need help) :
if (results != nil && [results count] > 0)
{
/** Not sure how to get the correct context and modify object **/
Store *matchingObject = [results objectAtIndex:0];
[context setValue:[NSNumber numberWithInteger:storeId] forKey:"id"];
}
/** Save the context */
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
//abort();
}
Thank you for any help you can provide...
Try modifying the object property directly and saving it:
matchingObject.id = [NSNumber numberWithInteger:storeId];
The object was originally fetched with context so you should be able to save your changes by calling save on context.
Related
I am trying to update int data by using CoreData but I think I am missing some parts before updating the object. Here what I am trying to do to save the int value. Here I want to both save and update only first object value.
- (IBAction)btnYakClicked:(UIButton *)sender
{
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Kalorimetre" inManagedObjectContext:context]];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
NSManagedObject* kaloriObject = [results objectAtIndex:0];
NSNumber *valWeek = [NSNumber numberWithInteger:300];
NSNumber *valMonth = [NSNumber numberWithInteger:1000];
[kaloriObject setValue:valWeek forKey:#"thisweek"];
[kaloriObject setValue:valWeek forKey:#"thismonth"];
}
I don't see the line where you're saving it. For example:
NSError *saveError;
if (![context save:&saveError]) {
NSLog(#"Error: %# %#", saveError, [saveError localizedDescription]);
}
It might also be a good idea to limit the fetch request since you're only looking for the first object:
[request setFetchLimit:1];
I would hope that this would improve performance but cannot confirm.
I have two methods,
In first method, I do save values in Core Data, while in other, I simply fetch them.
After inserting, when I fetch data in same method, it shows value, but when I try to fetch in other method if returns me null.
My saving Method is
-(void) saveloginData:(NSString *)facebookTok username:(NSString *)userName password:(NSString*)password flag:(NSString *)flag {
NSError *error;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"SignIn" inManagedObjectContext:context]];
[fetchRequest setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSString *facebookTokenData = facebookTok;
NSString *usernameData = userName;
NSString *passwordData = password;
NSString *flagData = flag;
NSLog(#"Facebook Token%#\nUsername%#\npassword%#\nflat%#\n",facebookTokenData,usernameData,passwordData,flagData);
SignIn *signIn = [NSEntityDescription
insertNewObjectForEntityForName:#"SignIn"
inManagedObjectContext:context];
signIn.facebookToken = facebookTokenData;
signIn.username = usernameData;
signIn.password = passwordData;
signIn.flag = flagData;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SignIn"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedArray = [context executeFetchRequest:fetchRequest error:&error];
for (SignIn *info in fetchedArray) {
\\ THis executes and shows values, proves that value are inserted.
NSLog(#"Name ~~~~ : %#", info.username);
NSLog(#"Password ~~~~~~~~ :%#", info.password);
NSLog(#"FLAG ~~~~~~~~~~~ %#",info.flag);
NSLog(#"Facebook Token %#", info.facebookToken);
}
}
My retrieve Method is
-(NSArray*) getLoginData {
NSError *error;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SignIn"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedData = [[NSArray alloc] init];
fetchedData = [context executeFetchRequest:fetchRequest error:&error];
NSLog(#"The count of Array %d", [fetchedData count]); \\ HERE COUNT IS ZERO, WHY?
for (SignIn *info in fetchedData) {
NSLog(#" FF Name ~~~~ : %#", info.username);
NSLog(#"Password ~~~~~~~~ :%#", info.password);
NSLog(#"FLAG ~~~~~~~~~~~ %#",info.flag);
NSLog(#"Facebook Token %#", info.facebookToken);
}
return fetchedData;
}
Please guide that where I am doing mistake.
Your problem is that you need to save conext to get the entity it later.
NSManagedObjectContext save: Attempts to commit unsaved changes to registered objects to their persistent store.
- (BOOL)save:(NSError **)error
Parameters: error: A pointer to an NSError object. You do not need to create an NSError object. The save operation aborts after the first failure if you pass NULL.
Return Value YES if the save succeeds, otherwise NO.
So you need to save context after you modify your object:
signIn.facebookToken = facebookTokenData;
signIn.username = usernameData;
signIn.password = passwordData;
signIn.flag = flagData;
[context save:NULL]; // NULL if you don't need to handle error
I have 2 entity, Units and BUnits, the Units entity have a data that will be replaced many time, and the BUnits will be the backup of the Units entity before clearing it's data.
So, I've created a NSManagedObjectContext instance, then I've retrive an instance for each entity by using
NSManagedObjectContext *context = [mainDelegate managedObjectContext];
NSEntityDescription *unitsEntity = [NSEntityDescription entityForName:#"Units" inManagedObjectContext:context];
NSEntityDescription *bUnitsEntity = [NSEntityDescription entityForName:#"BUnits" inManagedObjectContext:context];
but i've didn't managed to copy the Units entity records to the BUnits entity, other than make a loop for each records, but i believe that there is a better solution.
What do you think about this, is there a better solution?
UPDATE:
The solution i've used in case anyone could use it is in my answer, I think there is a better way to do this, i will keep checking for it and i will update the question if i found anything.
Here is what i've used, using looping for each record:
- (void) copyEntities:(NSString *)sourceEntity And:(NSString *)destinationEntity {
NSManagedObjectContext *context = [mainDelegate managedObjectContext];
NSEntityDescription *Units = [NSEntityDescription entityForName:sourceEntity inManagedObjectContext:context];
NSEntityDescription *BUnits = [NSEntityDescription entityForName:destinationEntity inManagedObjectContext:context];
NSFetchRequest *dataRequest = [[NSFetchRequest alloc] init];
[dataRequest setEntity:Units];
NSError *error = nil;
NSArray *dataArray = [context executeFetchRequest:dataRequest error:&error];
for (UnitsClass *unit in dataArray) {
UnitsClass *savedUnits;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:BUnits];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(code = %#)", unit.code];
NSPredicate *pred1 = [NSPredicate predicateWithFormat:#"(code2 = %#)", unit.code2];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:pred, pred1, nil]];
[request setPredicate:compoundPredicate];
NSError *error = nil;
NSArray *objects = [context executeFetchRequest:request error:&error];
//this if to indicate if we inserting to the BUnits or updating it.
if ([objects count] > 0) {
//Found the record, update The info
savedUnits = [objects objectAtIndex:0];
} else {
savedUnits = [NSEntityDescription insertNewObjectForEntityForName:destinationEntity inManagedObjectContext:context];
}
savedUnits.code = unit.code;
/*Add your updated info*/
NSError *errors;
if (![context save:&errors]) {
NSLog(#"Whoops, couldn't save: %#", [errors localizedDescription]);
}
}
NSLog(#"BUnits count = %d",[context countForFetchRequest:[NSFetchRequest fetchRequestWithEntityName:destinationEntity] error:&error]);
}
Based on the given information, there is no better way than looping each unit object and creating the backup object.
So I'm trying to create a simple (if such one exists) login process for my app, and I am getting an error with the below block of code.
NSManagedObject *context = _managedObjectContext;
NSFetchRequest *request= [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Account" inManagedObjectContext:context];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"username==%#",self.textFieldUsername.text];
[request setEntity:entity];
[request setPredicate:predicate];
NSError *error = nil;
// Below line is giving me error
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
if (array != nil) {
NSUInteger count = [array count]; // may be 0 if the object has been deleted.
NSLog(#"Username may exist, %#",count);
}
else {
NSLog(#"Username does not exist.");
}
`
The above code right now is ran when the user clicks the Login button.
Xcode is giving me an error of:
No visible #interface for 'NSManagedObject' declares the selector 'executeFetchRequest:error.'
When I read the above statement it just seems greek to me. The name of the file I am working on is ViewControllerWelcome.m and can be viewed in it's entirety at the following link. If it matters, I am using the stock boilerplate core data code.
Bonus: How do I get objective-c code highlighting when I post on here (SO)?
Change:
NSManagedObject *context = _managedObjectContext;
To
NSManagedObjectContext *context = _managedObjectContext;
and
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
should be
NSArray *array = [context executeFetchRequest:request error:&error];
P.S.
If you want the username search to be case insensitive use "username ==[c] %#" for the predicate...
I use core data in my application. When I delete object with [context deleteObject:obj], object is not deleted only with empty fields. How can I delete object permanently? Thanks in advanced. I use table view and when this view is filled with data from core data, there are empty rows where were deleted objects. This is the code:
LNAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
self.context = [appDelegate managedObjectContext];
self.accounts = [[NSArray alloc] init];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Accounts" inManagedObjectContext:self.context];
[fetchRequest setEntity:entity];
NSError *error;
self.accounts = [self.context executeFetchRequest:fetchRequest error:&error];
Are you making sure to save the context after you make the change?
NSError *error = nil;
if(![self.managedObjectContext save:&error])
{
/*
//Handle error
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
Also make sure that you are referencing the correct context, as you can have more than one.