core data for 'add to favorites' button?
i've had difficulty finding examples/tutorials/information for this. i'd like to have an 'add to favorites' button in my application. this would take a cell from one tableview and populate that cell into the 'favorites' tableview. is core data the proper direction for approaching this?开发者_运维技巧 i've seen some hints about using nsmutablearray and/or nsuserdefaults. not really sure which way to go. any advice is appreciated.
I added this functionality to my detail view. My entity has a "favorite" attribute. Pressing the "favorite" button in the detail view sets a string for the favorite attribute and toggles a star image on and off:
- (IBAction)flagButtonPressed:(id)sender {
if (flagButtonSelected == 0) {
[flagButton setSelected:YES];
flagButtonSelected = 1;
[flagButtonImage setImage:[UIImage imageNamed:@"yesFavorite.png"]];
[myCoolEntity setValue:@"yesFlag" forKey:@"flagSet"];
} else {
[flagButton setSelected:NO];
flagButtonSelected = 0;
[flagButtonImage setImage:[UIImage imageNamed:@"noFavorite.png"]];
[myCoolEntity setValue:@"noFlag" forKey:@"flagSet"];
}
NSManagedObjectContext *context = myCoolEntity.managedObjectContext;
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Tried to save fav. Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
Then back in my main table view, I have a favorites button in the nav bar that pushes a new view controller with a NSFetchedResultsController and predicate that looks for all the entities that have the "flagSet" attribute set to "yesFlag".
- (NSFetchedResultsController *)fetchedResultsController {
// Set up the fetched results controller if needed.
if (fetchedResultsController == nil) {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyCoolEntity" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"flagSet like 'yesFlag'"];
[fetchRequest setPredicate:predicate];
//set batch size
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"name" cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
}
return fetchedResultsController;
}
Also, in viewDidLoad for the detail view I display the star image on the favorites button as appropriate:
//flag button
if ([myCoolEntity.flagSet isEqual:@"yesFlag"]) {
[flagButtonImage setImage:[UIImage imageNamed:@"yesFavorite.png"]];
[flagButton setSelected:YES];
flagButtonSelected = 1;
} else {
[flagButtonImage setImage:[UIImage imageNamed:@"noFavorite.png"]];
[flagButton setSelected:NO];
flagButtonSelected = 0;
}
Core Data is likely the best way to go if you need a persistent store across user sessions. NSUserDefaults is more for -- just that -- user defaults. While I think it'd be appropriate to save, say, a user's home page, in NSUserDefaults, something that could get large (like favorites) should probably go in a data store.
If you never need to search the list, and you just want to save and display it, look at plist files as well. NSArray can write data directly to a plist file with writeToFile:atomically:
. You can get that data back with arrayWithContentsOfFile:
.
If you go with the above approach, one thing to watch out for - arrayWithContentsOfFile:
is a static class method, not an instance method.
Core Data is, though, by far the most flexible option. Try the template application in XCode for "Navigation-based App" with "Use Core Data". Most of the example code is right there.
If the number of favorites is likely to remain manageable (say up to 100-200 or so), you'd probably better just use the NSUserDefaults
approach. In that case I would only suggest using Core Data if you also have other needs for it. It's not trivial to use Core Data. Storing the data in a separate plist is also a good reasonable approach.
Not to scare you away from Core Data. It's great stuff, and I encourage you to learn it, but you may be over-engineering if you use it for this scenario.
精彩评论