Last active
February 1, 2023 11:28
-
-
Save HeshamMegid/4701741 to your computer and use it in GitHub Desktop.
Lookup a contact name/photo using phone number in ABAddressBook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import "Contact.h" | |
@interface AddressBookManager : NSObject | |
+ (NSString *)nameForContactWithPhoneNumber:(NSString *)phoneNumber; | |
+ (UIImage *)photoForContactWithPhoneNumber:(NSString *)phoneNumber; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "AddressBookManager.h" | |
#import <AddressBook/AddressBook.h> | |
#import "NSString+UnformattedPhoneNumber.h" | |
@implementation AddressBookManager | |
+ (NSArray *)allContactsFromAddressBook { | |
static NSMutableArray *contacts = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
contacts = [[NSMutableArray alloc] init]; | |
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000 | |
ABAddressBookRef addressBook = ABAddressBookCreate(); | |
#else | |
CFErrorRef *error = nil; | |
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error); | |
#endif | |
__block BOOL accessGranted = NO; | |
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 | |
// Semaphore is used for blocking until response | |
dispatch_semaphore_t sema = dispatch_semaphore_create(0); | |
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { | |
accessGranted = granted; | |
dispatch_semaphore_signal(sema); | |
}); | |
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); | |
} | |
else { // we're on iOS 5 or older | |
accessGranted = YES; | |
} | |
if (accessGranted) { | |
NSArray *allPeople = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); | |
for (id person in allPeople) { | |
Contact *contact = [[Contact alloc] init]; | |
NSString *firstName = @""; | |
NSString *lastName = @""; | |
// Get the name of the contact | |
firstName = (__bridge_transfer NSString*)ABRecordCopyValue((__bridge ABRecordRef)(person), kABPersonFirstNameProperty); | |
lastName = (__bridge_transfer NSString*)ABRecordCopyValue((__bridge ABRecordRef)(person), kABPersonLastNameProperty); | |
[contact setName:[NSString stringWithFormat:@"%@ %@", firstName, lastName]]; | |
// Get the photo of the contact | |
CFDataRef imageData = ABPersonCopyImageData((__bridge ABRecordRef)(person)); | |
UIImage *image = [UIImage imageWithData:(__bridge NSData *)imageData]; | |
[contact setPhoto:image]; | |
// Get all phone numbers of the contact | |
NSMutableArray *tempArray = [[NSMutableArray alloc] init]; | |
ABMultiValueRef phoneNumbers = ABRecordCopyValue((__bridge ABRecordRef)(person), kABPersonPhoneProperty); | |
// If the contact has multiple phone numbers, iterate on each of them | |
NSInteger phoneNumberCount = ABMultiValueGetCount(phoneNumbers); | |
for (int i = 0; i < phoneNumberCount; i++) { | |
NSString *phoneNumberFromAB = [(__bridge_transfer NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, i) unformattedPhoneNumber]; | |
[tempArray addObject:phoneNumberFromAB]; | |
} | |
CFRelease(phoneNumbers); | |
[contact setNumbers:tempArray]; | |
[contacts addObject:contact]; | |
} | |
} | |
CFRelease(addressBook); | |
}); | |
return contacts; | |
} | |
+ (Contact *)findContactWithPhoneNumber:(NSString *)phoneNumber { | |
NSArray *contacts = [AddressBookManager allContactsFromAddressBook]; | |
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"numbers contains %@", phoneNumber]; | |
NSArray *filteredArray = [contacts filteredArrayUsingPredicate:predicate]; | |
Contact *matchedContact = [filteredArray lastObject]; | |
return matchedContact; | |
} | |
+ (NSString *)nameForContactWithPhoneNumber:(NSString *)phoneNumber { | |
return [[AddressBookManager findContactWithPhoneNumber:phoneNumber] name]; | |
} | |
+ (UIImage *)photoForContactWithPhoneNumber:(NSString *)phoneNumber { | |
return [[AddressBookManager findContactWithPhoneNumber:phoneNumber] photo]; | |
} | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface Contact : NSObject | |
@property (nonatomic, strong) NSString *name; | |
@property (nonatomic, strong) NSArray *numbers; | |
@property (nonatomic, strong) UIImage *photo; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "Contact.h" | |
@implementation Contact | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface NSString (UnformattedPhoneNumber) | |
- (NSString *)unformattedPhoneNumber; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "NSString+UnformattedPhoneNumber.h" | |
@implementation NSString (UnformattedPhoneNumber) | |
- (NSString *)unformattedPhoneNumber { | |
NSCharacterSet *toExclude = [NSCharacterSet characterSetWithCharactersInString:@"/.()- "]; | |
return [[self componentsSeparatedByCharactersInSet:toExclude] componentsJoinedByString: @""]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment