Core Data is saving only the last item - ios

I'm still new at Core Data.
I'm trying to loop three times over an array and at each loop, I'm saving the index number.
But it's only showing the last index number when fetching the results. It's overriding everything that was inserted before.
My code is written in the AppDelegate.
Here's my code:
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *tagsDB = [NSEntityDescription insertNewObjectForEntityForName:#"Tags" inManagedObjectContext:context];
for (int i = 0 ; i < 3 ; i++)
{
[tagsDB setValue:i forKey:#"ID"];
}
[self saveContext];
...
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}

You have to create your entity for each value.
NSManagedObjectContext *context = [self managedObjectContext];
for (int i = 0 ; i < 3 ; i++)
{
NSManagedObject *tagsDB = [NSEntityDescription insertNewObjectForEntityForName:#"Tags" inManagedObjectContext:context];
[tagsDB setValue:i forKey:#"ID"];
}
[self saveContext];

In your for loop - the code that gets reiterated simply changes the value of the new inserted item. What you need to be doing in the for loop is insertNewObjectForEntityForName which will insert a new, separate entity for each iteration.

Related

How to store table value into core data entity in IOS

I am having data Like This:
Appliance Average Power Rating (Watts) Alternate Power Rating (Watts)
Fridge/Refrigerator 120 55
Microwave 1000 1000
Mixie 700 200
Roti Maker 30 300
I want to store this data into my entity in CoreData. Just I have created an entity called EY_Appliance with attributes applianceId, applianceName, watts and amountPerWatts.
You have to write code in this way. This will insert new Object for your entity with following attributes. You can edit it as per your requirement.
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *powerDesc = [NSEntityDescription insertNewObjectForEntityForName:#"EY_Appliance" inManagedObjectContext:context];
[powerDesc setValue:self.applianceId.text forKey:#"applianceId"];
[powerDesc setValue:self.applianceName.text forKey:#"applianceName"];
[powerDesc setValue:self.watts.text forKey:#"watts"];
[powerDesc setValue:self.amountPerWatts.text forKey:#"amountPerWatts"];
// Save the context
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Saving Failed!, Error and its Desc %# %#", error, [error localizedDescription]);
}
For that you can create and add the core data object as follows
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:#"EY_Appliance" inManagedObjectContext:context];
[object setValue:self.applianceIdValue forKey:#"applianceId"];
[object setValue:self.applianceNameValue forKey:#"applianceName"];
[object setValue:self.wattsValue forKey:#"watts"];
[object setValue:self.amountPerWattsValue forKey:#"amountPerWatts"];
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Saving Failed with error %#", error);
}

Update a Core Data record in iOS application

I've just read some tutorials and decide to add Core Data storage to my project. Then I implement "create" and "read" methods. It works OK.
But then I encountered a problem with "update" method.
- (void)updateForecastPlace:(NSString *)placeString
{
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:ENTITY_NAME inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
WFForecast *forecastToUpdate;
for (WFForecast *forecast in fetchedObjects)
{
if ([[forecastToUpdate timestamp] compare:[forecast timestamp]] == NSOrderedAscending)
{
forecastToUpdate = forecast;
}
}
[forecastToUpdate setPlace:placeString];
error = nil;
if ([context save:&error])
{
NSLog(#"Forecast information was updated!");
}
else
{
NSLog(#"The forecast information was not updated: %#", [error userInfo]);
}
}
I'm fetching objects from context. (It's OK)
Then choose one to update.
Setup new value to its property( [forecastToUpdate setPlace:placeString];)
Then save the context. ( [context save:&error] )
It seems like it works (it's rise no errors and send success massage to console log). But when I read this object it appears to be non-updated.
I read a lot of stuff on this problem but didn't figure out how to fix it.
Any suggestions, please?
UPDATE: I check the value of my updated object property place
[forecastToUpdate setPlace:placeString];
NSLog(#"---arg value %#", placeString);
NSLog(#"---updated value %#", [forecastToUpdate place]);
and got the output like:
---arg value Sydney, Australia
---updated value (null)
Any idea what caused such mistake?
Unfortunately the problem was in my inattentiveness :(
I forgot to assign fetched object with my objectToUpdate pointer before compare values and do other stuff.
WFForecast *lastestForecast = fetchedObjects[0]; // <- missed this row
for (WFForecast *forecast in fetchedObjects)
{
NSLog(#"%#", [forecast place]);
if ([[lastestForecast timestamp] compare:[forecast timestamp]] == NSOrderedAscending)
{
lastestForecast = forecast;
}
}

How to update transformable attribute in core data

I am in a situation where i need to update transformable attribute in my entity in core data, until now i've tried every possible answer from google and stack overflow but did't achieve anything.
This is the method where i am saving object in core data, and my object which i am saving is an NSMutablDictionary type object.
-(void)didSaveToCoreData :(NSMutableDictionary *)newDict
{
#try {
AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext ;
DataModelSupport *entity = [NSEntityDescription insertNewObjectForEntityForName:#"CPIEntity" inManagedObjectContext:context];
if (newDict != nil) {
[entity.fixed_Model removeAllObjects];
entity.fixed_Model = newDict;
}
NSError *error ;
[context save:&error];
if(error)
{
NSLog(#"Error in Saving Data");
}
else
{
[self didFetchFromCoreDataModel];
NSLog(#"Successfully saved");
}
}
#catch (NSException *exception) {
[self spareMeFromTheCrash:exception];
}
#finally {
}
}
in this method i am saving a dictionary object of 19 key/value, at the first time and i am fetching it correctly in didFetchFromCoreDataModel method, but when i refresh the data and get dictionary of 18 key/value i save that dictionary in core data using the same method didSaveToCoreData and fetch it in the same way from didFetchFromCoreDataModel but it still show 19 key/value
DataModelSupport is a subclass of NSManagedObject.
In DataModelSupport.h:
#property (nonatomic,weak) NSMutableDictionary *fixed_Model;
In DataModelSupport.m:
#dynamic fixed_Model;
This is it for the DataModelSupport class.
Now here in this method i am fetching the same object form core data
-(void)didFetchFromCoreDataModel
{
#try {
AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext ;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"CPIEntity" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setReturnsDistinctResults:YES];
[request setReturnsObjectsAsFaults:NO];
[request setResultType:NSDictionaryResultType];
[request setEntity:entity];
NSError *error ;
NSArray *arr = [context executeFetchRequest:request error:&error];
updatedfinalArr = [arr valueForKey:#"fixed_Model"];
if(error)
{
NSLog(#"Error");
}
else
{
}
}
#catch (NSException *exception) {
[self spareMeFromTheCrash:exception];
}
#finally {
}
}
And this is how my core data looks like:-
Any help is appreciated.
EDIT
I've implemented some changes in my code now in didSaveToCoreData method i am using this line of code to fetch the Entity by name
NSEntityDescription *descriptor = [NSEntityDescription entityForName:#"CPIEntity" inManagedObjectContext:context];
by this i am not creating new entity every time i call didSaveToCoreData method.
and this is how i am saving NSMutlableDictionary object
DataModelSupport *entity = [[DataModelSupport alloc]initWithEntity:descriptor insertIntoManagedObjectContext:context];
[entity.fixed_Model removeAllObjects]
entity.fixed_Model = newDict;
but still i am not getting correct result.
now when i refresh the data and save it using the above procedure explained in EDIT section, and fetch it, i get the updated data but it increase the number of objects, like on first attempt when i fetch i got 1 object in array, and on second attempt i got 2 objects and it goes like this, so when ever new data is added its not updating it but instead it add it in the entity s fixed_Model attribute and increase the number of object.
Lastly now i am using this line of code to get the last and update object from array in didFetchFromCoreDataModel method
NSDictionary *ddd = [[arr valueForKey:#"fixed_Model"]lastObject];
updatedfinalArr = [NSMutableArray arrayWithObject:ddd];
Your save method creates a new CPIEntity object each time. So, unless you delete the old object elsewhere in your code, I suspect your fetch is returning several objects, the first of which has the dictionary with 19 key/value pairs in the fixed_Model attribute, and the second/subsequent objects contain the 18 key/value pairs.
When you save, you should try to fetch the existing object first, and if you get zero results then create a new object. Then set the fixed_Model attribute of the new/existing object to your new dictionary.
EDIT
You are still inserting a new object each time (DataModelSupport *entity = [[DataModelSupport alloc]initWithEntity:descriptor insertIntoManagedObjectContext:context];). See below for an example of "fetch or create":
AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext ;
NSEntityDescription *descriptor = [NSEntityDescription entityForName:#"CPIEntity" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
request.entity = descriptor;
NSError *error;
NSArray *results = [context executeFetchRequest:request error:&error];
if (results == nil) {
// This implies an error has occurred.
NSLog(#"Error from Core Data: %#", error);
} else {
if (results.count == 0) {
// No objects saved, create a new one...
DataModelSupport *entity = [[DataModelSupport alloc]initWithEntity:descriptor insertIntoManagedObjectContext:context];
entity.fixed_Model = newDict;
} else {
// At least one object saved. There should be only one
// so use the first...
DataModelSupport *entity = [results firstObject];
entity.fixed_Model = newDict;
}
}
I've assumed for simplicity that newDict is not nil; amend as appropriate to handle that case.
Can you narrow down the problem?
Ie. can you compare the two Dictionaries..the original one with 19 values and the new one with 18 values?
Is there a particular entry which is not being 'removed'? That might point to a challenge with 'delete' (or the lack there of).
Alternatively, if you completely replace the content, what result do you get on fetch?

Can't overwrite Core data iOS/objective C

so I'm trying to overwrite/update a value saved from core data. when the back button is pressed (gets the textfield data and then overwrites the data using that). But it just keeps adding new data in. Here's my code in the back button:
The IF statement is just checking what the index is so it knows which view controller to go back to. goBackMVC just takes it back to a certain view controller.
- (IBAction)btnBack:(UIBarButtonItem *)sender {
if (self.viewControllerIndex == 3) {
NSLog(#"test");
[self saveDataMethod];
[self goBackMVC];
[self.navigationController popViewControllerAnimated:YES];
}
saveDataMethod:
- (void) saveDataMethod {
NSManagedObjectContext *context = [self managedObjectContext];
// Create a new managed object
FavouriteItem *favouriteItem = [NSEntityDescription insertNewObjectForEntityForName:#"FavouriteEntity" inManagedObjectContext:context];
favouriteItem.webName = self.txtName.text;
favouriteItem.webURL = self.txtURL.text;
favouriteItem.imageURL = self.txtImageURL.text;
NSLog(#"favouriteItem.webName %#", favouriteItem.webName);
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
}
My question is how can I overwrite the data instead of just adding it? Thanks.
edit: I've searched around and a lot of solutions have arrays, but I'm not allowed to use arrays
This is because you insert a new entity to your core data :
FavouriteItem *favouriteItem = [NSEntityDescription insertNewObjectForEntityForName:#"FavouriteEntity" inManagedObjectContext:context];
Instead fetch the required entity :
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"Favorits" inManagedObjectContext:context]];
To get the required entity create an NSPredicate instance to filter the required entity (in case you have more than one) and use it in your request :
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:<Your filter string>];
[fetchRequest setPredicate:filterPredicate];
NSError *error = nil;
NSArray* entities = [context executeFetchRequest:fetchRequest error:&error];
if ([entities count] == 1) {
// Get the entity and update necessary fields and save in context
}

Update CoreData iOS

i want to know how can I update a coredata record that was selected from a tableView
my code to save the coredata is:
- (IBAction)juardar:(id)sender {
NSUserDefaults *defs=[NSUserDefaults standardUserDefaults];
NSString *sedef_mat=[NSString stringWithFormat:#"%#",[defs objectForKey:#"Materia"]];
//NSLog(#"%#",sedef_mat);
NSManagedObjectContext *context = [self managedObjectContext];
// Create a new managed object
NSManagedObject *newtarea = [NSEntityDescription insertNewObjectForEntityForName:#"Tareas" inManagedObjectContext:context];
[newtarea setValue:self.Nombre.text forKey:#"nombre"];
[newtarea setValue:self.Descripcion.text forKey:#"descripcion"];
[newtarea setValue:sedef_mat forKey:#"materia"];
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
//NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
}
Thanks
Just set the new values then save the context just as you did above. But you'll be working with the fetched results:
for (Tareas *object in fetchedResultsController.fetchedObjects)
{
Tareas *t = (Tareas *)object;
if ([t.nombre isEqualToString:#"NewValue1"])
{
Tareas.nombre = #"NewValue1";
Tareas.description = #"NewValue2";
Tareas.materia = #"NewValue3";
}
}
then save context like you did above:
if (![context save:&error])
etc.

Resources