TLIndexPathController Class Reference
Inherits from | NSObject |
Conforms to | NSFetchedResultsControllerDelegate |
Declared in | TLIndexPathController.h |
Overview
TLIndexPathController
is TLIndexPathTools' version of NSFetchedResultsController
.
It should not come as a surprise, then, that you must use this class if you want
to integrate with Core Data.
Although it primarily exists for Core Data integration, TLIndexPathController
works
interchangeably with NSFetchRequest
or plain ‘ol arrays of arbitrary data. Thus,
if you choose to standardize your view controllers on TLIndexPathController
,
it is possible to have a common programming model across all of your table and collection views.
TLIndexPathController
also makes a few nice improvements relative to NSFetchedResultsController
:
- Items do not need to be presorted by section. The data model handles organizing sections.
- Changes to your fetch request are animated. So you can get animated sorting and filtering.
- There is only one delegate method to implement (versus five for
NSFetchedResultsController
).
The basic template for using TLIndexPathController
in a (table) view controller is as follows:
#import <UIKit/UIKit.h>
#import "TLIndexPathController.h"
@interface ViewController : UITableViewController TLIndexPathControllerDelegate
@end
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) TLIndexPathController *indexPathController;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.indexPathController = [[TLIndexPathController alloc] init];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.indexPathController.dataModel.numberOfSections;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.indexPathController.dataModel numberOfRowsInSection:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
id item = [self.indexPathController.dataModel itemAtIndexPath:indexPath];
//configure cell using data item
return cell;
}
#pragma mark - TLIndexPathControllerDelegate
- (void)controller:(TLIndexPathController *)controller didUpdateDataModel:(TLIndexPathUpdates *)updates
{
[updates performBatchUpdatesOnTableView:self.tableView withRowAnimation:UITableViewRowAnimationFade];
}
@end
This template works with plain arrays or NSFetchRequests
. With plain arrays, you
simply set the dataModel
property of the controller (or set the items
property
and get a default data model). With NSFetchRequests
, you set the fetchRequest
property and call performFetch:
. From then on, the controller updates the data
model interinally every time the fetch results change (using an internal instance
of NSFetchedResultsController
and responding to controllerDidChangeContent
messages).
In either case, whether you explicitly set a data model or the controller converts
a fetch result into a data model, the controller creates the TLIndexPathUpdates
object for you and passes it to the delegate, giving you an opportunity to perform batch updates:
- (void)controller:(TLIndexPathController *)controller didUpdateDataModel:(TLIndexPathUpdates *)updates
{
[updates performBatchUpdatesOnTableView:self.tableView withRowAnimation:UITableViewRowAnimationFade];
}
Tasks
Creating controllers
-
– initWithItems:
-
– initWithDataModel:
-
– initWithFetchRequest:managedObjectContext:sectionNameKeyPath:identifierKeyPath:cacheName:
Configuration information
-
delegate
property -
fetchRequest
property -
managedObjectContext
property -
cacheName
property -
+ deleteCacheWithName:
-
ignoreDataModelChanges
property
Accessing and updating data
Batch updates
Core Data Integration
-
– performFetch:
-
isFetched
property -
ignoreFetchedResultsChanges
property -
coreDataFetchedObjects
property -
inMemoryPredicate
property -
inMemorySortDescriptors
property
Properties
cacheName
The name of the file used by this classe’s internal NSFetchedResultsController to cache section information.
@property (strong, nonatomic) NSString *cacheName
Discussion
Unlike NSFetchedResultsController, this property is writeable. After changing
the fetch request, performFetch:
must be called to trigger updates.
Declared In
TLIndexPathController.h
coreDataFetchedObjects
Returns the underlying core data fetched objects without the application of in-memory filtering or sorting.
@property (strong, nonatomic, readonly) NSArray *coreDataFetchedObjects
Declared In
TLIndexPathController.h
dataModel
The data model representation of the items being tracked by the controller.
@property (strong, nonatomic) TLIndexPathDataModel *dataModel
Discussion
Setting this property causes the any changes to be propagated to the controller’s delegate. The type of items and configuration of the new data model need not necessarily be the same as the previous data model, provided that the controller’s delegate is prepared to handle the changes.
Declared In
TLIndexPathController.h
delegate
The controller’s delegate.
@property (weak, nonatomic) id<TLIndexPathControllerDelegate> delegate
Declared In
TLIndexPathController.h
fetchRequest
The controller’s fetch request.
@property (strong, nonatomic) NSFetchRequest *fetchRequest
Discussion
Unlike, NSFetchedResultsController, this property is writeable. After changing
the fetch request, performFetch:
must be called to trigger updates.
Declared In
TLIndexPathController.h
ignoreDataModelChanges
Determines whether data model changes are ignored.
@property (nonatomic) BOOL ignoreDataModelChanges
Discussion
This property can be set to YES to prevent calling the didUpdateDataModel
delegate method when the data model changes. This can be useful if the view
controller wants to reload the table without animation by calling reloadData
,
rather than having the batch updates performed.
Declared In
TLIndexPathController.h
ignoreFetchedResultsChanges
Determines whether incremental fetch request changes are ignored.
@property (nonatomic) BOOL ignoreFetchedResultsChanges
Discussion
This property can be set to YES to temporarily ignore incremental fetched results changes, such as when a table is in edit mode. This can also be useful for explicitly setting the data model and not having the changes overwritten by the fetch request.
Declared In
TLIndexPathController.h
inMemoryPredicate
The in-memory predicate.
@property (strong, nonatomic) NSPredicate *inMemoryPredicate
Discussion
This optional predicate will be evaluated in-memory against the underlying fetched
result. If the controller is already fetched, it is not necessary to call
performFetch:
again after setting this property because the batch updates
are processed immediately.
Declared In
TLIndexPathController.h
inMemorySortDescriptors
The in-memory sort descriptors.
@property (strong, nonatomic) NSArray *inMemorySortDescriptors
Discussion
These optional sort descriptors will be applied in-memory against the
underlying fetched result. If the controller is already fetched, it is not necessary
to call performFetch:
again after setting this property because the batch
updates are processed immediately.
Declared In
TLIndexPathController.h
isFetched
Returns YES if performFetch:
has ever been called.
@property (nonatomic) BOOL isFetched
Discussion
This property does not indicate whether the fetched results are fresh or stale.
For example, if the fetchRequest
is modified after performFetch:
has been
called, the isFetched
property will continue to return YES.
Declared In
TLIndexPathController.h
items
The items being tracked by the controller.
@property (strong, nonatomic) NSArray *items
Discussion
Setting this property causes a new data model to be created and any changes propagated
to the controller’s delegate. This new data model preserves the configuration of
the previous data model. The type of items need not necessarily be the same
as the previous data model, provided they are consistent with the configuration,
such as indetifierKeyPath
. If the new data model requires a different configuration,
set the dataModel
property directly.
Declared In
TLIndexPathController.h
managedObjectContext
The managed object context in which the fetch request is performed.
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext
Discussion
Unlike, NSFetchedResultsController, this property is writeable. After changing
the fetch request, performFetch:
must be called to trigger updates.
Declared In
TLIndexPathController.h
Instance Methods
initWithDataModel:
Returns an index path controller initialized with the given data model.
- (instancetype)initWithDataModel:(TLIndexPathDataModel *)dataModel
Parameters
- dataModel
the data model
Return Value
the index path controller with the given data model representation
Declared In
TLIndexPathController.h
initWithFetchRequest:managedObjectContext:sectionNameKeyPath:identifierKeyPath:cacheName:
Returns an index path controller initialized with the given fetch request and configuration parameters.
- (instancetype)initWithFetchRequest:(NSFetchRequest *)fetchRequest managedObjectContext:(NSManagedObjectContext *)context sectionNameKeyPath:(NSString *)sectionNameKeyPath identifierKeyPath:(NSString *)identifierKeyPath cacheName:(NSString *)name
Return Value
the index path controller with a default data model representation of the given fetch request
Discussion
@param fetchRequest @param context @param sectionNameKeyPath @param identifierKeyPath @param cacheName
Declared In
TLIndexPathController.h
initWithItems:
Returns an index path controller initialized with the given items.
- (instancetype)initWithItems:(NSArray *)items
Parameters
- items
the aray of items
Return Value
the index path controller with a default data model representation of the given items
A default data model is initialized with items where the properties identifierKeyPath
,
sectionNameKeyPath
are all nil
. If any of these are required, use initWithDataModel:
instead.
Declared In
TLIndexPathController.h
performBatchUpdates:completion:
Allows for making multiple changes to the controller with only a single controller:didUpdateDataModel: delegate callback. For example, change the fetch request (and perform fetch), in-memory sort descriptors, and in-memory predicate as a single update.
- (void)performBatchUpdates:(void ( ^ ) ( void ))updates completion:(void ( ^ ) ( BOOL finished ))completion
Parameters
- completion
a block to be executed after the batch updates are performed. Note that controller:didUpdateDataModel: is called before this block.
This method is not to be confused with table or collection view batch udpates. It is strickly for batch changes to this controller (which may result in batch updates happening to the table or collection view through the delegate method).
- udpates
a block that makes changes to the controller
Declared In
TLIndexPathController.h
performFetch:
Calling this method executes the fetch request and causes a new data model to be created with the fetch result and any changes propagated to the controller’s delegate. Unlike NSFetchedResultsController, repeated calls to this method will continue to propagate batch changes. This makes it possible to modify the fetch request’s predicate and/or sort descriptors and have the new fetch result be propagated as batch changes.
- (BOOL)performFetch:(NSError *__autoreleasing *)error
Declared In
TLIndexPathController.h