Check Core Data for results and delete [duplicate] - ios

This question already has an answer here:
Delete objects from NSManagedObjectContext from another method
(1 answer)
Closed 8 years ago.
I need to create a method for my Core Data. This method should check wether there is any results in the entities Section and Fixtures. If there are then delete all og the objects in them.
How can I do this? I've tried this, but does not do anything.
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *numberOfFixtures = [NSEntityDescription
insertNewObjectForEntityForName:#"Fixture"
inManagedObjectContext:context];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Fixture" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
self.theFixtures = [[context executeFetchRequest:fetchRequest error:nil] mutableCopy];
for (numberOfFixtures *fixture in self.theFixtures) {
[context deleteObject:fixture];
}
NSError *error;
[context save:&error];

Try this,
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Fixture" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
self.theFixtures = [[context executeFetchRequest:fetchRequest error:nil] mutableCopy];
for (NSManagedObject *fixture in self.theFixtures) {
[context deleteObject:fixture];
}
NSError *error;
[context save:&error];

Related

Core Data: Fetch all children in a 1 to many relationship

I have 1-many relationship and I am successfully putting data into it. The problem is that I am not able to fetch it out via the relationship attribute.
My ADD Code:
NSManagedObjectContext *context = [[CBICoreDataController sharedInstance] masterManagedObjectContext];
NSManagedObject *orders = [NSEntityDescription
insertNewObjectForEntityForName:#"UnsyncedOrders"
inManagedObjectContext:context];
[orders setValue:[dictionary valueForKey:#"specialInstructions"] forKey:#"specialInstructions"];
[orders setValue:[dictionary valueForKey:#"poNumber"] forKey:#"poNumber"];
[orders setValue:[dictionary valueForKey:#"specialInstructions"] forKey:#"specialInstructions"];
[orders setValue:[dictionary valueForKey:#"deliveryDate"] forKey:#"deliveryDate"];
[orders setValue:[dictionary valueForKey:#"account"] forKey:#"account"];
NSMutableSet *muteSet=[orders mutableSetValueForKey:#"items"];
for (NSDictionary *dict in [dictionary valueForKey:#"items"]) {
NSManagedObject *items = [NSEntityDescription
insertNewObjectForEntityForName:#"UnsyncedOrderItems"
inManagedObjectContext:context];
[items setValue:[dict valueForKey:#"arraykey"] forKey:#"arrayKey"];
//Other Sets Here
[muteSet addObject:items];
}
[orders setValue:muteSet forKey:#"items"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Error saving in writeToMenuCostingDetailsTable: %#", [error localizedDescription]);
}
What I have for the fetch now but it does not work:
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"arrayKey" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSEntityDescription *parent = [NSEntityDescription entityForName:#"UnsyncedOrders"
inManagedObjectContext:context];
NSEntityDescription *child = [NSEntityDescription entityForName:#"UnsyncedOrderItems"
inManagedObjectContext:context];
[fetchRequest setEntity:child];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"orders == %#", parent];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
NSError *error;
[aFetchedResultsController performFetch:&error];
NSArray *fetchedObjects = [aFetchedResultsController fetchedObjects];
Your orders relationship relates to a specific instance of UnsyncedOrders. However when you try to perform a fetch, you do this:
NSEntityDescription *parent = [NSEntityDescription entityForName:#"UnsyncedOrders"
inManagedObjectContext:context];
[...]
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"orders == %#", parent];
[fetchRequest setPredicate:predicate];
You're trying to fetch instances where the orders relationship points to the UnsyncedOrders entity itself, not those that relate to a specific instance of UnsyncedOrders. That's always going to fail. In fact there's a good chance that if you were checking the result of performFetch: that it's returning NO and providing you with some sort of error describing the problem.
If you want to fetch the UnsyncedOrderItems that relate to a specific instance of UnsyncedOrders, you need to use a predicate that refers to a specific instance. However, if you already have that instance, you don't need to fetch-- just ask the UnsyncedOrders instance for the value of its items relationship.
This is the solution that I ended up using:
NSManagedObjectContext *context = [[CBICoreDataController sharedInstance] masterManagedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"UnsyncedOrders"
inManagedObjectContext:context];
NSError *error = nil;
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (UnsyncedOrders *info in fetchedObjects) {
[mutableArray addObject:info.items];
}

How to update fetched managed objects?

I'm having troubles in updating a specific record in my core data. What happens in my code is it does change the value but when I rerun the app it goes back to its original value. Why that happens?
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Wish" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
// Specify criteria for filtering which objects to fetch
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"itemWish = %#", self.wishItemStr];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
[fetchedObjects setValue:#"YES" forKeyPath:#"isAchieved"];
if (fetchedObjects == nil) {
NSLog(#"no fetched objects!");
}
You need to save the context.
[managedObjectContext save:&error];
I suggest you to read these very good tutorials and articles on objc.io.

How to fetch data from NSManaged object context

NSFetchRequest *fetchLLObjects = [[NSFetchRequest alloc] init];
[fetchLLObjects setEntity:[NSEntityDescription entityForName:#"CustomerOrder" inManagedObjectContext:self.managedObjectContext]];
[fetchLLObjects setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSError *error = nil;
NSArray *allObjects = [self.managedObjectContext executeFetchRequest:fetchLLObjects error:&error];
Here array is showing nil. But in database I could see that there are data. I don't know what might be the reason.
Please add your predicate in the fetchrequest
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"CustomerOrder"
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"managedObjectID == %#", managedObjectID]] inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
Set following 2 properties and you are done.
fetchRequest.returnsDistinctResults = YES;
fetchRequest.resultType = NSDictionaryResultType;
Hope this helps.
Edit
NSFetchRequest *fetchRequest= [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Songs" inManagedObjectContext:myManagedObjectContext];
//Take properties dictionary
NSDictionary *entityProperties = [entity propertiesByName];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:#"song_type"]]];
NSArray * result = [myManagedObjectContext executeFetchRequest:fetchRequest error:nil];
You said: "But in database I could see that there are data."
I'm skeptical of that statement. I suspect that no CustomerOrder objects exist in the Core Data store. The only way to "see" the data inside the store is to turn off journaling mode and use 3rd party software to peak inside the .sqlite file.
Despite what others have said, your fetch request is fine. So double check your code where you insert objects into the store and save to the context.

iOS NSManagedObject Data <fault> while deleting

I am having some difficulties in deleting an entry from Core Data.
It works but the NSManagedObject data has no values (fault), and so sometimes the wrong entry will be deleted.
In my deleteWholeDatabase method the objects are filled with values.
And in the deleteEntryFromDatabase method are no values. But why?
Here are my methods:
-(NSArray*)databaseRequest{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:currentEntity inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSError *error;
NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
return items;
}
-(void)deleteWholeDatabase{
for (NSManagedObject *objectToDelete in [self databaseRequest]) {
[managedObjectContext deleteObject:objectToDelete];
NSLog(#"%# object deleted",objectToDelete);
}
[self saveContext];
NSLog(#"All entries deleted!");
}
-(void)deleteEntryFromDatabase:(NSManagedObjectContext*)context forEntry:(NSIndexPath*)indexPath{
NSManagedObject *objectToDelete=[[self databaseRequest] objectAtIndex:indexPath.row];
[managedObjectContext deleteObject:[managedObjectContext objectWithID:[objectToDelete objectID]]];
[self saveContext];
NSLog(#"%# deleted!",[managedObjectContext objectWithID:[objectToDelete objectID]]);
}
The wrong entry is being deleted because each request return the itens in a different order. Try deleting the intens by comparing their memory adress
Instead of keeping a calling [self databaseRequest] everywhere, I would keep a local copy of NSManagedObjectID's as an array.
- (void)init {
self.entities = [self databaseRequest];
}
-(NSArray*)databaseRequest{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:currentEntity inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSError *error;
NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSMutableArray *itemIDs = [[NSMutableArray alloc] initWithCapacity:[items count]];
for (NSManangedObject *item in items) {
[itemIDs addObject:[item objectID]];
}
return items;
}
Then everywhere where you call [self databaseRequest], you will get an have the correct NSManagedObjectID. Then you just need to get the correct entity from the ID.

ios core data - copy entity records to another entity

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.

Resources