Skip to content
This repository has been archived by the owner on Dec 3, 2019. It is now read-only.

Selection Filters

Nick Entin edited this page Aug 7, 2016 · 1 revision

How Selection Filters Work

Selection filters are components attached to a data source that allow for the filtering of contacts marked for selection or deselection before the action occurs. Selection filters can be added to the data source at initialization or can be dynamically added to or removed from the data source at runtime. Each selection filter can filter contacts on selection, deselection, or both.

Existing Selection Filters

Ohana provides a set of selection filters to help you get started. These selection filters are sufficient for a variety of use cases, but you can always create your own if you don't see what you need. The existing selection filters can be found under the SelectionFilters directory.

OHMaximumSelectedCountSelectionFilter

The OHMaximumSelectedCountSelectionFilter adds the concept of a maximum number of selected contacts to the data source. The maximum number of selected contacts can be dynamically changed at runtime by modifying the post processor's maximumSelectedCount property. The post processor also provides three signals:

  • onContactsDataSourceSelectedContactsReachedMaximumCountSignal - fired when the data source reaches the maximum number of selected contacts
  • onContactsDataSourceSelectedContactsAttemptedToExceedMaximumCountSignal - fired when the data source attempts to exceed the maximum number of selected contacts
  • onContactsDataSourceSelectedContactsNoLongerAtMaximumCountSignal - fired when the data source drops below the maximum number of selected contacts after having reached it

If a selection attempt is made that would cause the data source to exceed the maximum number of selected contacts, the selection filter will cause the attempt to fail. It will not select any contacts, even if some of the contacts in the attempt could have been selected without exceeding the maximum.

// Set maximum number of selected contacts to 10
OHMaximumSelectedCountSelectionFilter *selectionFilter = [[OHMaximumSelectedCountSelectionFilter alloc] initWithDataSource:dataSource maximumSelectedCount:10];

[selectionFilter.onContactsDataSourceSelectedContactsReachedMaximumCountSignal addObserver:self callback:^(typeof(self) self) {
    // Data source now has 10 contacts
}];

[selectionFilter.onContactsDataSourceSelectedContactsAttemptedToExceedMaximumCountSignal addObserver:self callback:^(typeof(self) self, NSOrderedSet<OHContact *> *failedContacts) {
    // Data source attempted to select more than 10 contacts
    // failedContacts contains the contacts it failed to select
}];

[selectionFilter.onContactsDataSourceSelectedContactsNoLongerAtMaximumCountSignal addObserver:self callback:^(typeof(self) self) {
    // Data source had 10 contacts selected, but now has less than 10 selected
}];

OHMinimumSelectedCountSelectionFilter

The OHMinimumSelectedCountSelectionFilter adds the concept of a minimum number of selected contacts to the data source. The minimum number of selected contacts can be dynamically changed at runtime by modifying the post processor's minimumSelectedCount property. The post processor also provides three signals:

  • onContactsDataSourceSelectedContactsReachedMinimumCountSignal - fired when the data source reaches the minimum number of selected contacts from above
  • onContactsDataSourceSelectedContactsAttemptedToDropBelowMinimumCountSignal - fired when the data source attempts to drop below the minimum number of selected contacts
  • onContactsDataSourceSelectedContactsNoLongerAtMinimumCountSignal - fired when the data source exceeds the minimum number of selected contacts after having only had the minimum selected

If a deselection attempt is made that would cause the data source to drop below the minimum number of selected contacts, the selection filter will cause the attempt to fail. It will not deselect any contacts, even if some of the contacts in the attempt could have been deselected without dropping below the minimum.

If the number of selected contacts is less than the minimum when the selection filter is added, the selection filter will allow all selection attempts, but will not allow any deselection attempts until the minimum is exceeded.

// Set minimum number of selected contacts to 1
OHMinimumSelectedCountSelectionFilter *selectionFilter = [[OHMinimumSelectedCountSelectionFilter alloc] initWithDataSource:dataSource minimumSelectedCount:1];

[selectionFilter.onContactsDataSourceSelectedContactsReachedMinimumCountSignal addObserver:self callback:^(typeof(self) self) {
    // Data source had more than 1 contact selected, but now has exactly 1 contact selected
}];

[selectionFilter.onContactsDataSourceSelectedContactsAttemptedToDropBelowMinimumCountSignal addObserver:self callback:^(typeof(self) self, NSOrderedSet<OHContact *> *failedContacts) {
    // Data source had at least 1 contact selected and attempted to deselect them
}];

[selectionFilter.onContactsDataSourceSelectedContactsNoLongerAtMinimumCountSignal addObserver:self callback:^(typeof(self) self) {
    // Data source had only 1 contact selected, but now has more than 1 selected
}];

OHRequiredFieldSelectionFilter

The OHRequiredFieldSelectionFilter requires that contacts have at least one contact field of a provided type in order to be selected. Any contacts passed into the filter that do not meet that requirement will be removed and the remaining contacts will be passed on for selection. No filtering applies to deselection.

// Require contacts to have a phone number to be selected
OHRequiredFieldSelectionFilter *selectionFilter = [[OHRequiredFieldSelectionFilter alloc] initWithFieldType:OHContactFieldTypePhoneNumber];

Creating Your Own Selection Filters

All selection filters must conform to the OHContactsSelectionFilterProtocol. A custom selection filter will look something like this:

@interface MyCustomSelectionFilter : NSObject <OHContactsSelectionFilterProtocol>

@end

@implementation MyCustomSelectionFilter

#pragma mark - OHContactsSelectionFilterProtocol

// This is where you filter contacts that have been marked for selection
// Implementing this method is optional
- (NSOrderedSet<OHContact *> *_Nullable)filterContactsForSelection:(NSOrderedSet<OHContact *> *)preFilteredContacts
{
    NSMutableOrderedSet *filteredContacts = [[NSMutableOrderedSet alloc] init];
    
    // Filter your contacts

    return filteredContacts;
}

// This is where you filter contacts that have been marked for deselection
// Implementing this method is optional
- (NSOrderedSet<OHContact *> *_Nullable)filterContactsForDeselection:(NSOrderedSet<OHContact *> *)preFilteredContacts
{
    NSMutableOrderedSet *filteredContacts = [[NSMutableOrderedSet alloc] init];
    
    // Filter your contacts

    return filteredContacts;
}

@end