FRZDatabaseViewMapper
is a class that manages multiple YapDatabaseViewMappings.
- Handles all boilerplate for updating the user interface with animations
- Is agnostic to what kind of view it is updating - works with
UITableView
andUICollectionView
out of the box, but can manage any view conforming toFRZDatabaseViewMappable
. - Supports multiple view mappings in the same view, meaning you can show the same database object in multiple table view sections
- Supports animated toggling between different view mappings (for example when activating a search)
- Handles edge cases/hard to find bugs in
UICollectionView
The FRZDatabaseViewMapper
was born when we had to support showing the same match in multiple sections of a single UICollectionView
in Forza Football. We quickly realized that since it handled the boilerplate of updating the UI, it was useful in every place where
we had a YapDatabase-powered view. It is now used in several of our apps, and makes creating those views much easier!
@interface MyTableViewController : UITableViewController
@property (nonatomic, strong) FRZDatabaseViewMapper *viewMapper;
@end
@implementation MyTableviewcontroller
- (void)viewDidLoad {
[super viewDidLoad];
self.viewMapper = [[FRZDatabaseViewMapper alloc] initWithDatabase:database];
// Since self.view is a UITableView, viewMapper can update it automatically. It does support any object that conforms to FRZDatabaseViewMappable.
self.viewMapper.view = self.view;
// Now, initialize your view mappings normally. If needed, create multiple view mappings and they will be shown in the table view in the same order as in viewMapper.activeViewMappings!
YapDatabaseViewMappings *mappings = [YapDatabaseViewMappings mappingsWithGroups:@[@"group_1", @"group2"] view:"my_database_view"];
self.viewMapper.activeViewMappings = @[mappings];
// All done! self.view will now be automatically updated when the underlying my_database_view changes.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.viewMapper numberOfSections];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.viewMapper numberOfItemsInSection:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyObject *object = [self.viewMapper objectAtIndexPath:indexPath];
// Dequeue/configure cell normally
}
@end
If your app manages a long-lived UI connection itself (as discussed here), you can make the view mapper use that connection instead of managing its own, in the following way:
// Must be a long-lived read transaction
YapDatabaseConnection *connection = ...;
// The NSNotification that is posted when connection is updated. The posted notification must have connection set as "object", and contain the changes generated by [connection beginLongLivedReadTransaction] in userInfo.
NSNotificationName updateNotificationName = @"notification";
self.viewMapper = [[FRZDatabaseViewMapper alloc] initWithConnection:connection updateNotificationName:updateNotificationName];