Skip to content

forzafootball/FRZDatabaseViewMapper

Repository files navigation

FRZDatabaseViewMapper is a class that manages multiple YapDatabaseViewMappings.

Features

  • Handles all boilerplate for updating the user interface with animations
  • Is agnostic to what kind of view it is updating - works with UITableView and UICollectionView out of the box, but can manage any view conforming to FRZDatabaseViewMappable.
  • 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!

Usage example

@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];

About

A class that handles multiple YapDatabaseViewMappings + the view mapping boilerplate

Resources

License

Stars

Watchers

Forks

Packages

No packages published