I have a method that is called in the app delegate by the UIViewControllers which deletes the core object that matches the selected objects name. It deletes from the UIListView which is correct and the refresh method (which checks core data for all objects)doesn't bring it back to the list view. However, when I close the application and restart it it brings back the just deleted objects. Here is the method:
-(void)deleteObject:(NSString *)configName
{
//Generates the request context for core data
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"StoredSetups" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(config_name = %#)", configName];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if (objects.count == 0)
{
NSLog(#"No Matches");
}
else
{
matches = objects[0];
[context deleteObject:matches];
}
}
Any help or feed back will be greatly appreciated. Thanks in advance!
you have to save the context after delete like this :
if (objects.count == 0)
{
NSLog(#"No Matches");
}
else
{
matches = objects[0];
[context deleteObject:matches];
[context save:&error];
}
Related
I have two entity in my core data named "History" and "Favorite". i want to delete some specific data like "Dhaka" from "History" entity. How to delete this. Thanks in advance.
Hope it will help you.
NSString* aType = #"History";
NSString *tp = #"Dhaka";
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:aType inManagedObjectContext:self.managedObjectContext]];
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"(type == %#)",tp ]; //where type is the attribute
[request setPredicate:predicate];
NSArray* ar = [self.managedObjectContext executeFetchRequest:request error:nil];
NSLog(#"############# Data from DB : %#",ar);
for(id anObj in ar){
[managedObjectContext deleteObject:anObj];
}
[self.managedObjectContext save:nil];
predicate=nil;
try this:
objAppDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = [objAppDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:#"History"];
NSArray *recordArray =[[NSArray alloc]initWithArray:[context executeFetchRequest:request error:nil]];
objDataClass = [recordArray objectAtIndex:0]; // here objDataClass is a instance of DataClass derived from NSObject which define column name
[context deleteObject:objDataClass]; // Delete particular data with index
if ([context hasChanges])
{
[context save:nil];
}
else
{
NSLog(#"Object Deleted.....");
}
Hope it will help you. :)
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 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.
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...