MRTFetchedResultsController
provideds automatic Core Data change tracking and it's a port of NSFetchedResultsController
for OS X (it works on iOS too).
MRTFetchedResultsController
is a single class with no dependencies, just download and drag the MRTFetchedResultsController.{h,m}
files in your Xcode project. All the classes require ARC; if your project is not ARC you will have to compile them with the -fobjc-arc
flag.
// Creating a NSFetchRequest with entity/sort descriptor/predicate
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:@"Notes" inManagedObjectContext:context];
request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES], nil];
request.predicate = [NSPredicate predicateWithFormat:@"deleted = NO"];
// Creating the MRTFetchedResultsController
MRTFetchedResultsController *fetchedResultsController = [[MRTFetchedResultsController alloc] initWithManagedObjectContext:context fetchRequest:request];
fetchedResultsController.delegate = self;
// Retrieving the objects
NSError *error = nil;
[fetchedResultsController performFetch:&error];
if (error) {
NSLog(@"Unresolved error: %@ %@", error, [error userInfo]);
}
else {
NSLog(@"fetched objects %@", fetchedResultsController.fetchedObjects);
}
If you want to monitor changes to objects in the associated managed object context you can assign a delegate that respond to the MRTFetchedResultsControllerDelegate
. The controller notifies the delegate when result objects change.
#pragma mark - MRTFetchedResultsControllerDelegate
// Called one time for each batch of changes, BEFORE the changes are applied to the controller
- (void)controllerWillChangeContent:(MRTFetchedResultsController *)controller
{
}
// Called one time for each batch of changes, AFTER the changes are applied to the controller
- (void)controllerDidChangeContent:(MRTFetchedResultsController *)controller
{
}
// Called once per object that's being changed
- (void)controller:(MRTFetchedResultsController *)controller didChangeObject:(id)anObject atIndex:(NSUInteger)index forChangeType:(MRTFetchedResultsChangeType)type newIndex:(NSUInteger)newIndex
{
switch (type) {
case MRTFetchedResultsChangeDelete:
// The object was removed from the controller
break;
case MRTFetchedResultsChangeInsert:
// The object is newly inserted in the controller
break;
case MRTFetchedResultsChangeUpdate:
// One or more of the object property has been updated
break;
case MRTFetchedResultsChangeMove:
// One or more of the object property has been updated
// and that has changed the order in the controller
break;
default:
break;
}
}
MRTFetchedResultsController
supports in memory sorting and filtering without changing the NSFetchRequest (so you will continue to receive the correct Core Data changes notification).
You can sort your content by adding one or more NSSortDescriptor:
fetchedResultsController.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"order" ascending:YES], nil];
NSLog(@"sorted objects %@", fetchedResultsController.arrangedObjects);
And you can filter your objects by adding an NSPredicate:
fetchedResultsController.filterPredicate = [NSPredicate predicateWithFormat:@"text LIKE %@", someText];
NSLog(@"filtered objects %@", fetchedResultsController.arrangedObjects);
Objects fetched by MRTFetchedResultsController
can be accessed in two different way:
- the fetchedObjects property
- the arrangedObjects property
For having the results of a in-memory sort or filter you must use the arrangedObjects property, while fetchedObjects will always return your original contents. If you have not set any sortDescriptors or filterPredicate on the fetchedResultsController, calling the arrangedObjects property will just return the fetchedObjects.
Unit tests were performed on all the library for quality assurance. To run the tests, open the Xcode workspace, choose the
MRTFetchedResultsControllerTests target in the toolbar at the top, and select the menu item Product > Test
.
If you ever find a test case that is incomplete, please open an issue so we can get it fixed.
Thanks to Indragie Karunaratne for his initial work on SNRFetchedResultsController. It laid the foundation for MRTFetchedResultsController.
This project is distributed under the standard MIT License. Please use this in whatever fashion you wish - feel free to recommend any changes to help the code.