CNContact display name objective c / swift - ios

I am working on app where I need to import contacts into NSMutableDictionary, but sometimes people not filling all contact details. So leaving just number or company name. Do I need to go through all contacts detail to check what field will be my "display name". In Android I know there is displayName variable. But how it is in Swift or Objective C?
My code:
BOOL success = [addressBook
enumerateContactsWithFetchRequest:request
error:&contactError
usingBlock:^(CNContact *contact, BOOL *stop){
NSString * contactId = contact.identifier;
NSString * firstName = contact.givenName;
NSString * lastName = contact.familyName;
}];

Use CNContactFormatter to build the display name. When specifying the keys for the request, use descriptorForRequiredKeysForStyle to make sure you requested the appropriate fields.
In Swift, it would be:
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
guard granted else {
print(error?.localizedDescription ?? "Unknown error")
return
}
let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
let formatter = CNContactFormatter()
formatter.style = .fullName
do {
try store.enumerateContacts(with: request) { contact, stop in
if let name = formatter.string(from: contact) {
print(name)
}
}
} catch let fetchError {
print(fetchError)
}
}
You suggested that you have situations where there is neither name nor company, but just phone number. Well, then, you'd have to manually handle that yourself:
let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as CNKeyDescriptor, CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
do {
try store.enumerateContacts(with: request) { contact, stop in
if let name = formatter.string(from: contact) {
print(name)
} else if let firstPhone = contact.phoneNumbers.first?.value {
print(firstPhone.stringValue)
} else {
print("no name; no number")
}
}
} catch let fetchError {
print(fetchError)
}
For Swift 2, see previous revision of this answer.

You can fetch contact name from your phone book using this code:-
- (void) fetchContacts
{
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusDenied) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:#"This app previously was refused permissions to contacts; Please go to settings and grant permission to this app so it can use contacts" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:TRUE completion:nil];
return;
}
CNContactStore *store = [[CNContactStore alloc] init]; [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
// make sure the user granted us access
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// user didn't grant access;
// so, again, tell user here why app needs permissions in order to do it's job;
// this is dispatched to the main queue because this request could be running on background thread
});
return;
}
// build array of contacts
NSMutableArray *contacts = [NSMutableArray array];
NSError *fetchError;
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:#[CNContactIdentifierKey, [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]]];
BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
[contacts addObject:contact];
}];
if (!success) {
NSLog(#"error = %#", fetchError);
}
// you can now do something with the list of contacts, for example, to show the names
CNContactFormatter *formatter = [[CNContactFormatter alloc] init];
for (CNContact *contact in contacts) {
if (!_contacts) {
_contacts = [[NSMutableArray alloc] init];
}
NSString *string = [formatter stringFromContact:contact];
NSLog(#"contact = %#", string);
[_contacts addObject:string];
}
[_contactatableview reloadData];
}];
}

#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>
- (IBAction)displayContact:(id)sender {
id keysToFetch = #[[CNContactViewController descriptorForRequiredKeys]];
CNContact *contact = [self.store unifiedContactWithIdentifier:self.contactIdentifier keysToFetch:keysToFetch error:nil];
self.controller = [[CNContactViewController alloc] init];
[self.controller.view setFrameSize:NSMakeSize(500, 500)];
[self presentViewController:self.controller asPopoverRelativeToRect:self.view.bounds ofView: self.view preferredEdge: NSMaxXEdge behavior:NSPopoverBehaviorTransient];
self.controller.contact = contact;
}

To fetch contacts from devices
if (isIOS9) { //checking iOS version of Device
CNContactStore *store = [[CNContactStore alloc] init];
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactEmailAddressesKey,CNContactPostalAddressesKey, CNLabelWork, CNLabelDateAnniversary];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
DLOG(#"cnContacts %lu",(unsigned long)cnContacts.count);
if (error) {
//error
} else {
for (CNContact *contact in cnContacts) {
//iterate over cnContacts to get details
}
}
} else {
//for below iOS 9
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef arrPersons = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex count = ABAddressBookGetPersonCount(addressBook);
NSLog(#"cnContacts %lu",(unsigned long)count);
for (int i = 0; i < count; i++) {
ABRecordRef record = CFArrayGetValueAtIndex(arrPersons,i);
//use kABPersonBirthdayProperty to get b’day
NSString *birthDay = (__bridge NSString *)(ABRecordCopyValue(record, kABPersonBirthdayProperty));
NSLog(#“B’day %#”, birthDay);
}
}

Related

List contacts with phone numbers

I'd like to fetch (in iOS using Objective-C) only the contacts that have a phone number, but how can I do that? I'm trying to form the predicate as in the code below, but obviously that doesn't work.
contacts = [contactStore unifiedContactsMatchingPredicate:[NSPredicate predicateWithFormat:#"phoneNumbers <> nil"] keysToFetch:KEYS error:nil];
So, what is the correct way of doing this? Thanks for any help!
#import <Contacts/Contacts.h>
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey, CNContactEmailAddressesKey];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
request.sortOrder = CNContactSortOrderGivenName;
request.unifyResults = YES;
NSError *error;
__block NSString* email;
BOOL success = [store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * __nonnull contact, BOOL * __nonnull stop)
{
if (error) {
NSLog(#"error fetching contacts %#", error);
} else {
NSString *fullName;
NSString* phone;
// for (CNContact *contact in cnContacts) {
DeviceContact *aContact = [DeviceContact new];
// copy data to my custom Contacts class.
NSString *firstName = contact.givenName;
NSString *lastName = contact.familyName;
if (lastName == nil) {
fullName=[NSString stringWithFormat:#"%#",firstName];
}else if (firstName == nil){
fullName=[NSString stringWithFormat:#"%#",lastName];
}
else{
fullName=[NSString stringWithFormat:#"%# %#",firstName,lastName];
}
if ([firstName trim].length > 0) {
aContact.nameForSorting = firstName; // 141116
}else if ([lastName trim].length>0 && aContact.nameForSorting.length<=0) {
aContact.nameForSorting = lastName; // 141116
}
aContact.name = fullName;
if (contact.phoneNumbers!=nil && [contact.phoneNumbers count]>0) {
for (CNLabeledValue *label in contact.phoneNumbers) {
phone = [CommonUtils removeAllSpecialCharactersFromPhoneNumber:[label.value stringValue]];
if ([phone length] > 0) {
[aContact.phoneNumber addObject:phone];
}
}
}
////Get all E-Mail addresses from contacts
/// if ([CommonUtils checkIsNullObject:[contact emailAddresses]] && [[contact emailAddresses] count]>0) {
for (CNLabeledValue *label in contact.emailAddresses) {
email = label.value;
if ([email length] > 0)
{
[aContact.email addObject:email];
}
}
// }
// 141116
if ([aContact.name trim].length <= 0) {
if (aContact.email.count>0) {
aContact.name = [aContact.email objectAtIndex:0];
}else if (aContact.phoneNumber.count>0){
aContact.name = [aContact.phoneNumber objectAtIndex:0];
}
}
if ([aContact.nameForSorting trim].length <= 0){
if (aContact.email.count>0) {
aContact.nameForSorting = [aContact.email objectAtIndex:0];
}else if (aContact.phoneNumber.count>0){
aContact.nameForSorting = [aContact.phoneNumber objectAtIndex:0];
}
}
[self.arrAllContacts addObject:aContact];
}
}];
if(success){
dispatch_async(dispatch_get_main_queue(), ^{
[CommonUtils hideLoader];
completionhandler(self.arrAllContacts);
});
}
}
else
{
// [CommonUtils showAlertMessageWithMessage:#"fdfdggfsgfdgfd" withDelegate:self withCancelTitle:OKAY isOtherButton:NO withOtherButtonTitle:nil withTag:0];
[CommonUtils hideLoader];
}
}];
use following method and import
#import <AddressBook/AddressBook.h>
#import <Contacts/Contacts.h>
-(void)contactsDetailsFromPhoneContactBook{
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey,CNContactGivenNameKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(#"error fetching contacts %#", error);
} else {
NSString *fullName;
NSString *firstName;
NSString *lastName;
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
firstName = contact.givenName;
lastName = contact.familyName;
if (lastName == nil) {
fullName=[NSString stringWithFormat:#"%#",firstName];
}else if (firstName == nil){
fullName=[NSString stringWithFormat:#"%#",lastName];
}
else{
fullName=[NSString stringWithFormat:#"%# %#",firstName,lastName];
}
[self.contactsArray addObject:fullName];
NSLog(#"working or not %#",self.contactsArray);
}
}
}
}];
}
Filtering out the contacts that don't have a phone number (or some other property) is not possible. In the docs we read:
CNContact Predicates
Predicates to match contacts. You can only use these predicates
with CNContactStore and CNContactFetchRequest.
predicateForContactsMatchingName: Returns a predicate to find the contacts matching the specified name.
predicateForContactsWithIdentifiers: Returns a predicate to find the contacts matching the specified identifiers.
predicateForContactsInGroupWithIdentifier: Returns a predicate to find the contacts that are members in the specified group.
predicateForContactsInContainerWithIdentifier: Returns a predicate to find the contacts in the specified container.
And additionally:
Compound predicates are not supported.
So, the only way to do the filtering would be to omit adding to the result array the contacts with no phone numbers. That could be done, for example, in the block of the enumerateContactsWithFetchRequest.

How to differentiate the phone numbers after fetching the details from local contact

I am fetching the mobile contacts by using below method
-(void)fetchContactsandAuthorization
{
// Request authorization to Contacts
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES)
{
//make sure that you have added the necessary properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey, CNContactPostalAddressesKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
NSLog(#"new %#",cnContacts);
if (error)
{
NSLog(#"error fetching contacts %#", error);
}
else
{
NSString *phone;
NSString *fullName;
NSString *firstName;
NSString *lastName;
NSString *companyName;
NSString *departmentName;
NSString *jobTitleName;
NSString *address;
NSString *iden;
NSString *emailAddress;
UIImage *profileImage;
NSMutableArray *contactNumbersArray = [[NSMutableArray alloc]init];
NSMutableArray *addressArray = [[NSMutableArray alloc]init];
NSMutableArray *emailAddressArray = [[NSMutableArray alloc]init];
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
firstName = contact.givenName;
lastName = contact.familyName;
iden = contact.identifier;
if (lastName == nil) {
fullName=[NSString stringWithFormat:#"%#",firstName];
}else if (firstName == nil){
fullName=[NSString stringWithFormat:#"%#",lastName];
}
else{
fullName=[NSString stringWithFormat:#"%# %#",firstName,lastName];
}
UIImage *image = [UIImage imageWithData:contact.imageData];
NSLog(#"imgold %#",image);
if (image != nil) {
profileImage = image;
}else{
profileImage = [UIImage imageNamed:#"person-icon.png"];
}
for (CNLabeledValue *label in contact.phoneNumbers) {
phone = [label.value stringValue];
if ([phone length] > 0) {
[contactNumbersArray addObject:phone];
}
}
NSLog(#"PhonenumberArray %#",contactNumbersArray);
User *user = [User new];
user.fullName=fullName;
user.image= profileImage;
user.phone= phone;
user.idUser= iden;
[contacts addObject:user];
}
dispatch_async(dispatch_get_main_queue(), ^{
[_selectContactListTblView reloadData];
});
}
}
}];
}
I am able to get all phone numbers associated with the contact and able to store in an array.
PhonenumberArray (
"98708\U00a001224",
"98920\U00a077702",
"93240\U00a077702",
1,
2,
3,
4,
5,
5,
6,
7,
8,
9
)
Now i want to differentiate the phonenumbers in array like home,mobile,fax,pager etc. Any help will be really appreciated.
The CNLabeledValue label property will return a string that represents home, mobile etc. Then call [CNLabeledValue localizedStringForLabel:labelString] to get a localized human readable string.
for (CNLabeledValue *label in contact.phoneNumbers) {
phone = [label.value stringValue];
labelString = label.label;
if ([phone length] > 0) {
[contactNumbersArray addObject:phone];
[contactNumbersLabelsArray addObject:labelString];
}
}
Check this blog https://genericswift.wordpress.com/, It will fetch all contacts from contact store and will differentiate it with home,mobile,fax,pager etc.
Code is in this Github link https://github.com/VinupriyaArivazhagan/AVContactPickerController
Just need a line of code to pesent view controller with all fetched contacts
AVContactPickerController.present(title: "Contact", maximumContactCount: nil, updateDesign: nil)
and can update design as well
AVContactPickerController.present(title: "Contact", maximumContactCount: 2, updateDesign: { controller in
controller.checkImage = #imageLiteral(resourceName: "Clicked")
controller.uncheckImage = #imageLiteral(resourceName: "Click")
controller.closeButton.setTitleColor(UIColor.red, for: .normal)
})

Facebook Photo Downloading

I am attempting to download Facebook albums of photos from a user in my app. Unfortunately although I do have an access token, I am getting zero albums from the requests. I am not getting an error, just getting zero. Why? If you would like to see any more code or ask more questions, just ask. Note that I have authorized the current user's Facebook permissions when they signed up, and I've since quit the app and opened it many times (don't think this would be an issue, since I have an access token..?)
- (void)getAlbums:(OLFacebookAlbumRequestHandler)handler {
if ([FBSDKAccessToken currentAccessToken]) {
// connection is open, perform the request
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSString *graphPath = #"me/albums?limit=100&fields=id,name,count,cover_photo";
if (self.after) {
graphPath = [graphPath stringByAppendingFormat:#"&after=%#", self.after];
}
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:nil];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if (self.cancelled) {
return;
}
if (error) {
[OLFacebookAlbumRequest handleFacebookError:error completionHandler:handler];
return;
}
NSString *parsingErrorMessage = #"Failed to parse Facebook Response. Please check your internet connectivity and try again.";
NSError *parsingError = [NSError errorWithDomain:kOLErrorDomainFacebookImagePicker code:kOLErrorCodeFacebookImagePickerBadResponse userInfo:#{NSLocalizedDescriptionKey: parsingErrorMessage}];
id data = [result objectForKey:#"data"];
if (![data isKindOfClass:[NSArray class]]) {
handler(nil, parsingError, nil);
return;
}
NSMutableArray *albums = [[NSMutableArray alloc] init];
for (id album in data) {
if (![album isKindOfClass:[NSDictionary class]]) {
continue;
}
id albumId = [album objectForKey:#"id"];
id photoCount = [album objectForKey:#"count"];
id name = [album objectForKey:#"name"];
if (!([albumId isKindOfClass:[NSString class]] && [photoCount isKindOfClass:[NSNumber class]]
&& [name isKindOfClass:[NSString class]])) {
continue;
}
OLFacebookAlbum *album = [[OLFacebookAlbum alloc] init];
album.albumId = albumId;
album.photoCount = [photoCount unsignedIntegerValue];
album.name = name;
album.coverPhotoURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=small&access_token=%#", album.albumId, [FBSDKAccessToken currentAccessToken].tokenString]];
[albums addObject:album];
}
// get next page cursor
OLFacebookAlbumRequest *nextPageRequest = nil;
id paging = [result objectForKey:#"paging"];
if ([paging isKindOfClass:[NSDictionary class]]) {
id cursors = [paging objectForKey:#"cursors"];
id next = [paging objectForKey:#"next"]; // next will be non nil if a next page exists
if (next && [cursors isKindOfClass:[NSDictionary class]]) {
id after = [cursors objectForKey:#"after"];
if ([after isKindOfClass:[NSString class]]) {
nextPageRequest = [[OLFacebookAlbumRequest alloc] init];
nextPageRequest.after = after;
}
}
}
handler(albums, nil, nextPageRequest);
}];
}
else {
NSString *message = #"No Facebook user authentication found.";
handler(nil, [NSError errorWithDomain:kOLErrorDomainFacebookImagePicker code:kOLErrorCodeFacebookImagePickerNoOpenSession userInfo:#{NSLocalizedDescriptionKey: message}], nil);
}
}
//Code for fetching albums...
- (void)loadNextAlbumPage {
self.inProgressRequest = self.albumRequestForNextPage;
self.albumRequestForNextPage = nil;
[self.inProgressRequest getAlbums:^(NSArray/*<OLFacebookAlbum>*/ *albums, NSError *error, OLFacebookAlbumRequest *nextPageRequest) {
self.inProgressRequest = nil;
self.loadingIndicator.hidden = YES;
self.albumRequestForNextPage = nextPageRequest;
if (error) {
if (self.parentViewController.isBeingPresented) {
self.loadingIndicator.hidden = NO;
self.getAlbumError = error; // delay notification so that delegate can dismiss view controller safely if desired.
} else {
[self.delegate albumViewController:self didFailWithError:error];
}
return;
}
NSMutableArray *paths = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < albums.count; ++i) {
[paths addObject:[NSIndexPath indexPathForRow:self.albums.count + i inSection:0]];
}
[self.albums addObjectsFromArray:albums];
if (self.albums.count == albums.count) {
// first insert request
[self.tableView reloadData];
} else {
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
}
if (nextPageRequest) {
self.tableView.tableFooterView = self.loadingFooter;
} else {
self.tableView.tableFooterView = nil;
}
}];
}
//And when they signed up:
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:#{ #"fields" : #"id,first_name,photos,picture.width(400).height(400)"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) { //etc etc the method continues.
FB authentication will give you a unique access_token for a particular set of permissions. To access user photos, you need to request the user_photos permission. Use the FBSDKLoginButton to request permissions.
loginButton.readPermissions = #[#"public_profile", #"email", #"user_photos"];
Once you have an access token with the required permissions, persist that locally (on the device) to reuse in future. If the access code is still valid, you won't need to request it again. If it becomes invalid (in case the user explicitly revoked permissions to your app), send them back to the login screen.

Fetch all the contact and all the keys using new Contact Framework

I want to fetch all the contacts without filter and all the information of their keys.
func unifiedContactsMatchingPredicate(_ predicate: NSPredicate,
keysToFetch keys: [CNKeyDescriptor]) throws -> [CNContact]
I am using above method to fetch contact.
is i have to specify all the keys?
is their is any shortcut to fetch all the keys information without specifying all of them?
No. You will have to specify all the required keys by yourself. Please have a look at apple documentation here
**EDIT:**Please try this method:
-(void)getAllContacts
{
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSString *containerId = store.defaultContainerIdentifier;
//to fetch all contacts
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
//to fetch contacts with matching name
// NSPredicate *predicate = [CNContact predicateForContactsMatchingName:#"vishal"];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(#"error fetching contacts %#", error);
} else {
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
Contact *newContact = [[Contact alloc] init];
newContact.firstName = contact.givenName;
newContact.lastName = contact.familyName;
UIImage *image = [UIImage imageWithData:contact.imageData];
newContact.image = image;
for (CNLabeledValue *label in contact.phoneNumbers) {
NSString *phone = [label.value stringValue];
if ([phone length] > 0) {
[newContact.phones addObject:phone];
}
}
[contacts addObject:newContact];
}
}
}

Getting \U00a , While fetching multiple phone numbers from the contact iOS

I am trying to fetch multiple phone numbers from the contacts of device.
It's working fine if the contact have only one number, but it's f***** when they have multiple numbers (which means that I'm getting "\U00a" in between the numbers).
I tried every solution I could think of, but it's still not working.
ABMultiValueRef phonesRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
for (int i = 0; i < ABMultiValueGetCount(phonesRef); i++) {
CFStringRef currentPhoneLabel = ABMultiValueCopyLabelAtIndex(phonesRef, i);
CFStringRef currentPhoneValue = ABMultiValueCopyValueAtIndex(phonesRef, i);
if (CFStringCompare(currentPhoneLabel, kABPersonPhoneMobileLabel, 0) == kCFCompareEqualTo) {
[contactInfoDict setObject:(__bridge NSString *) currentPhoneValue forKey:#"mobileNumber"];
}
else if (CFStringCompare(currentPhoneLabel, kABHomeLabel, 0) == kCFCompareEqualTo) {
[contactInfoDict setObject:(__bridge NSString *) currentPhoneValue forKey:#"homeNumber"];
}
CFRelease(currentPhoneLabel);
CFRelease(currentPhoneValue);
}
You can use Contacts Framework. Hope this will provide you direct solution for contacts.
#import <Contacts/Contacts.h>
-(void)getContact{
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
// make sure the user granted us access
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// user didn't grant access;
// so, again, tell user here why app needs permissions in order to do it's job;
// this is dispatched to the main queue because this request could be running on background thread
});
return;
}
// build array of contacts
NSMutableArray *contacts = [NSMutableArray array];
NSError *fetchError;
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:#[CNContactEmailAddressesKey, CNContactPhoneNumbersKey, CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPostalAddressesKey]];
BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
[contacts addObject:contact];
}];
if (!success) {
CTLog(#"error = %#", fetchError);
}
__weak typeof(self)weakSelf = self;
[weakSelf parseContactWithContact:contacts];
}];
- (void)parseContactWithContact :(NSMutableArray* )contacts{
for (CNContact *contact in contacts)
{
NSString * firstName = contact.givenName;
NSString * lastName = contact.familyName;
NSString *StrContactName = [NSString stringWithFormat:#"%# %#",firstName,lastName];
NSArray * arryPhone = [[contact.phoneNumbers valueForKey:#"value"] valueForKey:#"digits"];
for (int i=0; i<[arryPhone count]; i++)
{
NSMutableDictionary *mDictValue = [[NSMutableDictionary alloc]init];
[mDictValue setValue:firstName forKey:#"firstName"];
[mDictValue setValue:lastName forKey:#"lastName"];
[mDictValue setValue:StrContactName forKey:#"contactName"];
[mDictValue setValue:[arryPhone objectAtIndex:i] forKey:#"Phone"];
[arrayOfContacts addObject:mDictValue];
}
}

Resources