Reputation: 3221
I'm a bit confused about saving entities using Core Data. I'm making a screen that will allow users to save their settings (contact information), which can be changed later if they wish.
From what I understand, my code below will save multiple entities each time the 'save' button is pressed.
- (IBAction)saveSettings:(id)sender {
AppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
NSManagedObject *userSettings;
userSettings = [NSEntityDescription
insertNewObjectForEntityForName:@"UserSettings"
inManagedObjectContext:context];
[userSettings setValue: _firstName.text forKey:@"firstName"];
[userSettings setValue: _lastName.text forKey:@"lastName"];
[userSettings setValue: _userEmail.text forKey:@"userEmail"];
[userSettings setValue: _zipCode.text forKey:@"zipCode"];
}
What I don't understand how to do is save one entity, and then change the values of the attributes later on whenever the user types in new values in the appropriate text fields and presses 'save'.
Upvotes: 0
Views: 1549
Reputation: 21536
Yes - because you use insertNewObjectForEntityForName:
, a new UserSettings object is created each time that method is run. What you probably want to do is to fetch the existing settings from the database, update your textFields with that data, present the view and let the user amend the details as necessary, and then (when they press the save button), save that data back to the database.
I would add userSettings as a property:
@property (strong, nonatomic) NSManagedObject *userSettings;
and in your method delete the declaration of userSettings, and the line where you use insertNewObjectForEntityForName
.
Then create a new method to handle fetching the data from the database and assigning it to your textFields, as follows:
-(void)loadSettings {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"UserSettings"];
NSError *error;
NSArray *results = [context executeFetchRequest:fetch error:&error];
if (results == nil) {
// some error handler here
}
if ([results count] > 0) {
userSettings = [results lastObject];
_firstName.text = [userSettings valueForKey:@"firstName"];
_lastName.text = [userSettings valueForKey:@"lastName"];
_userEmail.text = [userSettings valueForKey:@"userEmail"];
_zipCode.text = [userSettings valueForKey:@"zipCode"];
} else {
// set your text fields to some defaults values??
}
}
Call this method when your view controller loads, in the viewDidLoad
method. I've assumed that you will normally have only one UserSettings
object (hence lastObject
will be the only object!). If you could have many UserSettings objects, you would need to filter the fetch to get only the one you want. To do that you would need to set a predicate
for the fetch - look at the documentation for NSPredicate
.
Upvotes: 1
Reputation: 917
You are actually overwriting those properties everytime you "set". The correct way to store individual properties is to assign them and save, like so:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *userSettings;
userSettings = [NSEntityDescription insertNewObjectForEntityForName:@"UserSettings"
inManagedObjectContext:context];
userSettings.firstName = _firstName.text;
userSettings.lastName = _lastName.text;
userSettings.userEmail = _userEmail.text;
userSettings.zipCode = _zipCode.text;
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Error Saving: %@", error);
}
Upvotes: 0