Skip to content

Instantly share code, notes, and snippets.

@fictorial
Last active August 29, 2015 14:03
Show Gist options
  • Save fictorial/0b1e6c0ab6bedc6e3f59 to your computer and use it in GitHub Desktop.
Save fictorial/0b1e6c0ab6bedc6e3f59 to your computer and use it in GitHub Desktop.
Trying to get Facebook social profile from AddressBook
@interface LocalContact : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, copy, readonly) NSString *fullName;
@property (nonatomic, copy) NSString *mobileNumber;
@property (nonatomic, copy) NSString *normalizedMobileNumber;
@property (nonatomic, copy) NSString *facebookID;
@property (nonatomic, copy) NSString *facebookUsername;
@end
typedef void (^ ContactsLoaderCompletionBlock)(BOOL succeeded, NSArray *contacts);
@interface ContactsLoader : NSObject
+ (instancetype)sharedLoader;
- (void)loadContacts:(ContactsLoaderCompletionBlock)completionHandler;
@end
//
// ContactsLoader.m
// Balloon
//
// Created by Brian Hammond on 7/8/14.
// Copyright (c) 2014 J32 Productions LLC. All rights reserved.
//
#import "ContactsLoader.h"
#import <AddressBook/AddressBook.h>
#import "NBPhoneNumberUtil.h"
@interface ContactInfo ()
@property (nonatomic, copy, readwrite) NSString *fullName;
@end
@implementation ContactInfo
- (NSString *)fullName
{
return [NSString stringWithFormat:@"%@ %@", _firstName, _lastName];
}
- (void)setMobileNumber:(NSString *)phoneNumber
{
_mobileNumber = [phoneNumber copy];
if (phoneNumber.length == 0) {
return;
}
NSError *error = nil;
NBPhoneNumber *myNumber = [[NBPhoneNumberUtil sharedInstance] parse:phoneNumber defaultRegion:@"US" error:&error];
if (error) {
DDLogError(@"error with phone number [%@]: %@", phoneNumber, [error localizedDescription]);
return;
}
error = nil;
self.normalizedMobileNumber = [[NBPhoneNumberUtil sharedInstance] format:myNumber numberFormat:NBEPhoneNumberFormatE164 error:&error];
if (error) {
DDLogError(@"error with phone number [%@]: %@", phoneNumber, [error localizedDescription]);
return;
}
}
@end
@interface ContactsLoader ()
@property (nonatomic, copy) NSArray *contacts; // ContactInfo
@end
@implementation ContactsLoader
+ (instancetype)sharedLoader
{
static dispatch_once_t onceToken;
static ContactsLoader *loader;
dispatch_once(&onceToken, ^{
loader = [ContactsLoader new];
});
return loader;
}
- (void)loadContacts:(ContactsLoaderCompletionBlock)completionHandler
{
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
ABAuthorizationStatus authStatus = ABAddressBookGetAuthorizationStatus();
if (authStatus == kABAuthorizationStatusNotDetermined) {
__weak typeof(self) weakSelf = self;
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (!granted) {
completionHandler(NO, nil);
} else {
[weakSelf loadContactsFromAddressBook:addressBook completionHandler:completionHandler];
}
});
} else {
[self loadContactsFromAddressBook:addressBook completionHandler:completionHandler];
}
}
- (void)loadContactsFromAddressBook:(ABAddressBookRef)addressBook completionHandler:(ContactsLoaderCompletionBlock)completionHandler
{
NSMutableArray *allContacts = [NSMutableArray array];
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
if (allPeople) {
for (CFIndex i = 0; i < CFArrayGetCount(allPeople); i++) {
ABRecordRef who = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(CFArrayGetValueAtIndex(allPeople, i)));
// First/Last Name
ContactInfo *aContact = [ContactInfo new];
aContact.firstName = CFBridgingRelease(ABRecordCopyValue(who, kABPersonFirstNameProperty));
aContact.lastName = CFBridgingRelease(ABRecordCopyValue(who, kABPersonLastNameProperty));
if (!aContact.firstName || !aContact.lastName) {
continue;
}
// Mobile
ABMultiValueRef phones = ABRecordCopyValue(who, kABPersonPhoneProperty);
if (phones) {
for (CFIndex i = 0; i < ABMultiValueGetCount(phones); i++) {
NSString *mobileLabel = (NSString *)CFBridgingRelease(ABMultiValueCopyLabelAtIndex(phones, i));
if ([mobileLabel isEqualToString:(NSString *)kABPersonPhoneMobileLabel] ||
[mobileLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel]) {
aContact.mobileNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, i));
}
}
CFRelease(phones);
}
// Facebook: info added by iOS to each contact as a "linked person" when the user enters their Facebook credentials in Settings > Facebook.
CFArrayRef linkedPeople = ABPersonCopyArrayOfAllLinkedPeople(who);
if (linkedPeople) {
for (CFIndex i = 0; i < CFArrayGetCount(linkedPeople); i++) {
ABRecordRef who = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(CFArrayGetValueAtIndex(linkedPeople, i)));
// Social Profile => Facebook ID
ABMultiValueRef socialProfiles = ABRecordCopyValue(who, kABPersonSocialProfileProperty);
if (socialProfiles) {
for (CFIndex i = 0; i < ABMultiValueGetCount(socialProfiles); i++) {
NSDictionary *socialProfile = CFBridgingRelease(ABMultiValueCopyValueAtIndex(socialProfiles, i));
NSString *serviceName = socialProfile[(NSString *)kABPersonSocialProfileServiceKey];
if ([serviceName isEqualToString:(NSString *)kABPersonSocialProfileServiceFacebook]) {
aContact.facebookID = socialProfile[@"identifier"];
}
}
CFRelease(socialProfiles);
}
// Facebook Messenger => Facebook Username
ABMultiValueRef im = ABRecordCopyValue(who, kABPersonInstantMessageProperty);
if (im) {
for (CFIndex i = 0; i < ABMultiValueGetCount(im); i++) {
NSDictionary *imInfo = CFBridgingRelease(ABMultiValueCopyValueAtIndex(im, i));
NSString* serviceName = [imInfo objectForKey:(NSString *)kABPersonInstantMessageServiceKey];
if ([serviceName isEqualToString:(NSString *)kABPersonInstantMessageServiceFacebook]) {
aContact.facebookUsername = ([imInfo objectForKey:(NSString *)kABPersonInstantMessageUsernameKey]);
}
}
CFRelease(im);
}
}
[allContacts addObject:aContact];
DDLogDebug(@"first=%@ last=%@ mobile=%@ fbID=%@ fbUsername=%@", aContact.firstName, aContact.lastName, aContact.normalizedMobileNumber, aContact.facebookID, aContact.facebookUsername);
CFRelease(linkedPeople);
}
}
CFRelease(allPeople);
}
CFRelease(addressBook);
completionHandler(YES, allContacts);
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment