Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
extern NSManagedObjectContext *GetContext(void);
@interface TableViewController () <NSFetchedResultsControllerDelegate>
@property (nonatomic) NSFetchedResultsController *controller;
@end
@implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Organization"];
request.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES] ];
request.fetchBatchSize = 10;
self.controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:GetContext() sectionNameKeyPath:nil cacheName:nil];
self.controller.delegate = self;
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:self.controller.managedObjectContext.parentContext queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[self.controller.managedObjectContext mergeChangesFromContextDidSaveNotification:note];
NSDictionary *userInfo = note.userInfo;
NSArray *items = [@[ userInfo[NSUpdatedObjectsKey] ?: [NSSet set], userInfo[NSInsertedObjectsKey] ?: [NSSet set], userInfo[NSDeletedObjectsKey] ?: [NSSet set] ] valueForKeyPath:@"@unionOfSets.self"];
[(NSManagedObjectContext *)note.object performBlock:^{
NSMutableSet *objectIDs = [NSMutableSet set];
for (NSManagedObject *object in items) {
if ([object isKindOfClass:[Employee class]]) {
[objectIDs addObject:((Employee *)object).organization.objectID];
}
}
dispatch_async(dispatch_get_main_queue(), ^{
for (NSManagedObjectID *objectID in objectIDs) {
Organization *organization = (Organization *)[self.controller.managedObjectContext objectWithID:objectID];
organization.name = organization.name; // <--- Magic is here!
}
});
}];
}];
__autoreleasing NSError *error;
[self.controller performFetch:&error];
if (error) {
NSLog(@"Fetch failed");
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TheCell" forIndexPath:indexPath];
if (cell) {
Organization *organization = [self.controller objectAtIndexPath:indexPath];
cell.textLabel.text = organization.name;
cell.detailTextLabel.text = [[organization valueForKeyPath:@"employees.@max.salary"] stringValue];
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.controller.sections[section] numberOfObjects];
}
- (IBAction)addOrganizationTapped:(UIBarButtonItem *)sender {
Organization *organization = [NSEntityDescription insertNewObjectForEntityForName:@"Organization" inManagedObjectContext:self.controller.managedObjectContext];
organization.name = [NSString stringWithFormat:@"Organization %u", arc4random()];
[organization addEmployees:[NSSet setWithObjects:[self employeeWithID:1], [self employeeWithID:2], nil]];
__autoreleasing NSError *saveError;
if (![self.controller.managedObjectContext save:&saveError]) {
NSLog(@"Save error: %@", saveError);
}
}
- (Employee *)employeeWithID:(NSUInteger)ID {
Employee *result = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.controller.managedObjectContext];
result.name = [NSString stringWithFormat:@"Employee %tu", ID];
result.salary = arc4random();
return result;
}
- (IBAction)increaseSalaryTapped:(UIBarButtonItem *)sender {
NSUInteger numberOfOrganizations = [self.controller.sections.firstObject numberOfObjects];
Organization *organization = [self.controller objectAtIndexPath:[NSIndexPath indexPathForRow:numberOfOrganizations - 1 inSection:0]];
NSManagedObjectID *maxSalaryEmployeeID = [[organization.employees sortedArrayUsingDescriptors:@[ [NSSortDescriptor sortDescriptorWithKey:@"salary" ascending:NO] ]].firstObject objectID];
NSManagedObjectContext *privateContext = self.controller.managedObjectContext.parentContext;
[privateContext performBlock:^{
Employee *maxSalaryEmployee = (Employee *)[privateContext objectWithID:maxSalaryEmployeeID];
int32_t delta = arc4random() % 1000;
maxSalaryEmployee.salary += delta;
__autoreleasing NSError *saveError;
if (![privateContext save:&saveError]) {
NSLog(@"Save error: %@", saveError);
}
}];
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableViewRowAnimation animation = UITableViewRowAnimationAutomatic;
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:@[ newIndexPath ] withRowAnimation:animation];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:@[ indexPath ] withRowAnimation:animation];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:@[ indexPath ] withRowAnimation:animation];
break;
case NSFetchedResultsChangeMove:
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.