How to update fetched managed objects? - ios

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.

Related

Coredata is not updated

I wanted to update one record in my core data entity and I write code for it but the data is not updated .
There is Entity posts and it has data with id
i have to update the record for one particular id .
Here is function to update the record
-(void)updateDataInDB:(NSString*)withID WithDes:(NSString*)newData{
NSManagedObjectContext * context = [self getManagedContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"News" inManagedObjectContext:context];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"postId == %#",withID];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchLimit:1];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *arrResult = [context executeFetchRequest:fetchRequest error:&error];
if(arrResult.count>0){
NSManagedObject *news = [arrResult objectAtIndex:0];
[news setValue:newData forKey:#"fullDesc"];
}
[self saveContext];
}
Please Help if anything wrong
My core data contains duplicate records and i updated only first records so that the problem with update. After I updated all array records the code working fine.

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 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.

Check Core Data for results and delete [duplicate]

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

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