-
Notifications
You must be signed in to change notification settings - Fork 40
Data Providers
Data providers act as the connection between an initial origin of contacts and the data source. Ohana includes two data providers, used to access system contacts, and provides a protocol for making your own data providers.
At their simplest, data providers must conform to the OHContactsDataProviderProtocol
, but can build off of that. For instance, the system contacts data providers use a delegate protocol to handle authentication.
The OHCNContactsDataProvider
provides access to system contacts using the Contacts framework. This data provider can only be used on devices running iOS 9 or greater (see Using the System Data Providers below). The data provider requires you to provide a delegate conforming to OHCNContactsDataProviderDelegate
to handle system authentication. You can also display any pre-auth notifications at this time.
OHCNContactsDataProvider *dataProvider = [[OHCNContactsDataProvider alloc] initWithDelegate:self];
- (void)dataProviderDidHitAuthenticationChallenge:(OHCNContactsDataProvider *)dataProvider
{
// Ask user for contacts permissions
}
The OHABAddressBookContactsDataProvider
provides access to system contacts using the Address Book framework. This data provider should only be used on pre-iOS 9 devices (see Using the System Data Providers below) since it has many disadvantages from the OHCNContactsDataProvider
. The data provider requires you to provide a delegate conforming to OHABAddressBookContactsDataProviderDelegate
to handle system authentication. You can also display any pre-auth notifications at this time.
OHABAddressBookContactsDataProvider *dataProvider = [[OHABAddressBookContactsDataProvider alloc] initWithDelegate:self];
- (void)dataProviderDidHitAuthenticationChallenge:(OHABAddressBookContactsDataProvider *)dataProvider
{
// Ask user for contacts permissions
}
By combining the built-in data providers, you can support pre-iOS 9 devices while getting the benefits of using the OHCNContactsDataProvider
on iOS 9+ devices. If you are not supporting devices older than iOS 9, you should use the OHCNContactsDataProvider
only.
- (id<OHContactsDataProviderProtocol>)systemDataProvider {
if ([CNContact class]) {
return [[OHCNContactsDataProvider alloc] initWithDelegate:self];
} else {
return [[OHABAddressBookContactsDataProvider alloc] initWithDelegate:self];
}
}
#pragma mark - OHCNContactsDataProviderDelegate, OHABAddressBookContactsDataProviderDelegate
- (void)dataProviderDidHitAuthenticationChallenge:(id<OHContactsDataProviderProtocol>)dataProvider
{
if ([dataProvider isKindOfClass:[OHCNContactsDataProvider class]]) {
CNContactStore *contactStore = [[CNContactStore alloc] init];
[contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError *_Nullable error) {
if (granted) {
[dataProvider loadContacts];
}
}];
} else if ([dataProvider isKindOfClass:[OHABAddressBookContactsDataProvider class]]) {
ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool granted, CFErrorRef error) {
if (granted) {
[dataProvider loadContacts];
}
});
}
}
All data providers must conform to the OHContactsDataProviderProtocol
. A custom data provider will look something like this:
@interface MyCustomDataProvider : NSObject <OHContactsDataProviderProtocol>
@end
@implementation MyCustomDataProvider
// Synthesize the properties required by protocol
@synthesize onContactsDataProviderFinishedLoadingSignal = _onContactsDataProviderFinishedLoadingSignal, onContactsDataProviderErrorSignal = _onContactsDataProviderErrorSignal, status = _status, contacts = _contacts;
- (instancetype)init
{
if (self = [super init]) {
_onContactsDataProviderFinishedLoadingSignal = [[OHContactsDataProviderFinishedLoadingSignal alloc] init];
_onContactsDataProviderErrorSignal = [[OHContactsDataProviderErrorSignal alloc] init];
_status = OHContactsDataProviderStatusInitialized;
}
return self;
}
#pragma mark - OHContactsDataProviderProtocol
- (void)loadContacts
{
NSError *error;
// Try to load contacts into self.contacts, or set error if you can't
if (success) {
_status = OHContactsDataProviderStatusLoaded;
self.onContactsDataProviderFinishedLoadingSignal.fire(self);
} else {
_status = OHContactsDataProviderStatusError;
self.onContactsDataProviderErrorSignal.fire(error, self);
}
}
+ (NSString *)providerIdentifier
{
return NSStringFromClass([MyCustomDataProvider class]);
}
@end
Data providers have been provided for the system frameworks, but the potential for data providers is much larger. You can create data providers to load contacts from a local database, social networks, remote server, etc.