accessing phone number and display country name or the country code - objective-c

I accessing contacts and sending it to server, my question is do I have any possibility of detecting which country contact belongs to?
Thank you.

Follow the steps below.
1 : Fetch the phone numbers from device.
2 : You need to find the country code from the phone number. Phone numbers can be saved in the device in different formats. International format, local format, with country code, without country code etc. So you need to consider all these cases to split the country code from the phone number. The following code may help you to get the country code from the phone number.
- (NSString *)getDiallingCodeFromPhoneNumber:(NSString *)phoneNumber
{
NSString *countryCode = #"not found";
NSString *code;
NSString *dialledNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:#"-() "]]
componentsJoinedByString:#""];
NSString *interNationalCode = [dialledNumber substringToIndex:2];
NSArray *allCodes = [self.diallingCodesDictionary allValues];
int idx;
if([dialledNumber hasPrefix:#"+"])
{
dialledNumber = [dialledNumber substringFromIndex:1];
}
else if([interNationalCode isEqualToString:#"00"])
{
dialledNumber = [dialledNumber substringFromIndex:2];
}
for (idx = 1 ; idx < dialledNumber.length; idx++) {
code = [dialledNumber substringToIndex:idx];
if([allCodes containsObject:code])
{
countryCode = code;
break;
}
}
return countryCode;
}
3 : You will get the list of country codes and country name from internet. Add it as a plist in your bundle. (I took this plist from a third part, HMDiallingCode)
4 : Now you will get the country name corresponding to your country code from that plist.
5 : If you got countryCode = not found, it means that the phone number is not saved with country code. This makes it clear that, that particular phone number is a local number. So in this case you can select the country name from NSLocale.

Try this code function you can get all of information would you like.
+(NSArray *)getAllContacts
{
CFErrorRef *error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
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) {
NSLog(#"Fetching contact info ----> ");
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
CFIndex nPeople = CFArrayGetCount(allPeople);
NSMutableArray* items = [NSMutableArray arrayWithCapacity:nPeople];
for (int i = 0; i < nPeople; i++)
{
ContactDetailModel *contacts = [[ContactDetailModel alloc] init]; // it is NsObject class. this is contained variables and array which required for get contact information. It is not necessary for you. you can maintain according your requirments.
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
if((__bridge NSString*)ABRecordCopyCompositeName(person)){
contacts.compse_name = (__bridge NSString*)ABRecordCopyCompositeName(person);
NSLog(#"compse_name = %#",contacts.compse_name);
}
if (!contacts.compse_name) {
contacts.compse_name = #"";
}
//get First Name and Last Name
if((__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty)){
contacts.first_name = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
}
if((__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty)){
contacts.last_name = (__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
}
if (!contacts.first_name) {
contacts.first_name = #"";
}
if (!contacts.last_name) {
contacts.last_name = #"";
}
NSLog(#"fname and lname = %# %#",contacts.first_name,contacts.last_name);
/// URL
ABMultiValueRef webpages = ABRecordCopyValue(person, kABPersonURLProperty);
NSString* homepage;
// Then iterate thru webpages to get the homepage
for (CFIndex k=0; k < ABMultiValueGetCount(webpages); k++)
{
homepage = (__bridge NSString*)ABMultiValueCopyValueAtIndex(webpages, k);
NSLog(#"homepage = %#",homepage);
}
NSLog(#"URL = %#",homepage);
//// get BirthDay
if((__bridge NSString*)ABRecordCopyValue(person, kABPersonBirthdayProperty)){
contacts.birthday = (__bridge NSString*)ABRecordCopyValue(person, kABPersonBirthdayProperty);
}
if (!contacts.birthday) {
contacts.birthday = #"";
}
//// get Company Name
if((__bridge NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty)){
contacts.company = (__bridge NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);
}
if (!contacts.company) {
contacts.company = #"";
}
// get contacts picture, if pic doesn't exists, show standart one
contacts.img_data = (__bridge NSData *)ABPersonCopyImageData(person);
if (!contacts.img_data) {
UIImage *image = [UIImage imageNamed:#"profile#2x.png"];
NSData *img_data = UIImagePNGRepresentation(image);
contacts.img_data = img_data;
}
//get Phone Numbers
NSMutableArray *phoneNumbers = [[NSMutableArray alloc] init];
ABMultiValueRef multiPhones = ABRecordCopyValue(person, kABPersonPhoneProperty);
for(CFIndex i=0;i<ABMultiValueGetCount(multiPhones);i++) {
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(multiPhones, i);
NSString *phoneNumber = (__bridge NSString *) phoneNumberRef;
NSString * strippedNumber = [phoneNumber stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [phoneNumber length])];
[phoneNumbers addObject:strippedNumber];
//NSLog(#"All numbers %#", phoneNumbers);
}
contacts.arrCallIDs = phoneNumbers;
/// get Addresss
NSMutableArray *arry_address = [[NSMutableArray alloc] init];
ABMutableMultiValueRef multiAddress = ABRecordCopyValue(person, kABPersonAddressProperty);
for(CFIndex i=0; i<ABMultiValueGetCount(multiAddress);i++){
CFDictionaryRef address = ABMultiValueCopyValueAtIndex(multiAddress, i);
NSString *street = (NSString*) CFDictionaryGetValue(address, kABPersonAddressStreetKey);
NSString *city = (NSString*) CFDictionaryGetValue(address, kABPersonAddressCityKey);
NSString *state = (NSString*) CFDictionaryGetValue(address, kABPersonAddressStateKey);
NSString *postal = (NSString*) CFDictionaryGetValue(address, kABPersonAddressZIPKey);
NSString *country = (NSString*) CFDictionaryGetValue(address, kABPersonAddressCountryKey);
NSString *country_id = (NSString*) CFDictionaryGetValue(address, kABPersonAddressCountryCodeKey);
NSMutableDictionary *add_field = [[NSMutableDictionary alloc] init];
[add_field setValue:street forKey:#"street"];
[add_field setValue:city forKey:#"city"];
[add_field setValue:state forKey:#"state"];
[add_field setValue:postal forKey:#"postal"];
[add_field setValue:country forKey:#"country"];
[add_field setValue:country_id forKey:#"country_id"];
// NSLog(#"Address = %#",add_field);
[arry_address addObject:add_field];
}
contacts.arrAddress = arry_address;
//get Contact email
NSMutableArray *contactEmails = [NSMutableArray new];
ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);
for (CFIndex i=0; i<ABMultiValueGetCount(multiEmails); i++) {
CFStringRef contactEmailRef = ABMultiValueCopyValueAtIndex(multiEmails, i);
NSString *contactEmail = (__bridge NSString *)contactEmailRef;
[contactEmails addObject:contactEmail];
// NSLog(#"All emails are:%#", contactEmails);
}
contacts.arrEmails = contactEmails;
[items addObject:contacts];
//NSLog(#"Person is: %#", contacts.firstNames);
//NSLog(#"Phones are: %#", contacts.numbers);
//NSLog(#"Email is:%#", contacts.emails);
}
return items;
} else {
NSLog(#"Cannot fetch Contacts :( ");
return NO;
}
}

Related

IOS::How to get the contact number from ABAddressBook

Phone number getting like this.
Phone ABMultiValueRef 0x17674380 with 1 value(s)
0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)
How to get this number"7124779070" from the above line.
I'm using this code for ios 7.Is it correct or wrong ,Please sugggest me.
int i;
ABAddressBookRef contactBook = ABAddressBookCreateWithOptions(NULL, NULL);
NSMutableArray *allData = ( NSMutableArray *)(ABAddressBookCopyArrayOfAllPeople(contactBook));
CFIndex contactNum = CFArrayGetCount((__bridge CFArrayRef)(allData));
for (i = 0; i < contactNum; i++)
{
ABRecordRef ref = CFArrayGetValueAtIndex((__bridge CFMutableArrayRef)(allData), i);
NSString* firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
NSString* lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
NSString* phonesNum = ABRecordCopyValue(ref, kABPersonPhoneProperty);
// Remove all formatting symbols that might be in both phone number being compared
NSCharacterSet *toExclude = [NSCharacterSet characterSetWithCharactersInString:#"/.()- "];
phonesNum = [[phonesNum componentsSeparatedByCharactersInSet:toExclude] componentsJoinedByString: #""];
NSString *phoneNumber = [[phonesNum componentsSeparatedByCharactersInSet:toExclude] componentsJoinedByString: #""];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
if (firstName!=nil)
{
[dic setObject:(__bridge id)(firstName) forKey:#"firstName"];
}
if (lastName !=nil) {
[dic setObject:(__bridge id)(lastName) forKey:#"lastName"];
}
if (phonesNum!=nil) {
[dic setObject:(__bridge id)(phonesNum) forKey:#"phonesNum"];
}
[arr_Contacts addObject:dic];
NSLog(#"First name %#", firstName);
NSLog(#"Last Name %#", lastName);
NSLog(#"Phone %#", phonesNum);
}
First, request permission:
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status != kABAuthorizationStatusAuthorized && status != kABAuthorizationStatusNotDetermined) {
// tell user to enable contacts in privacy settings
NSLog(#"You previously denied access: You must enable access to contacts in settings");
return;
}
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (!addressBook) {
NSLog(#"ABAddressBookCreateWithOptions error: %#", CFBridgingRelease(error));
return;
}
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (error) {
NSLog(#"ABAddressBookRequestAccessWithCompletion error: %#", CFBridgingRelease(error));
}
if (granted) {
[self getContacts:addressBook];
} else {
// tell user to enable contacts in privacy settings
NSLog(#"You just denied access: You must enable access to contacts in settings");
}
CFRelease(addressBook);
});
Second, to retrieve the phone numbers, use ABMultiValueCopyValueAtIndex:
- (void)getContacts:(ABAddressBookRef)addressBook
{
NSArray *allData = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
NSInteger contactCount = [allData count];
for (int i = 0; i < contactCount; i++) {
ABRecordRef person = CFArrayGetValueAtIndex((__bridge CFArrayRef)allData, i);
NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSString *lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
if (firstName) {
dictionary[#"firstName"] = firstName;
}
if (lastName) {
dictionary[#"lastName"] = lastName;
}
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex phoneNumberCount = ABMultiValueGetCount(phones);
if (phoneNumberCount > 0) {
NSString *phone = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, 0));
dictionary[#"phone"] = phone;
}
// or if you wanted to iterate through all of them, you could do something like:
//
// for (int j = 0; j < phoneNumberCount; j++) {
// NSString *phone = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, j));
//
// // do something with `phone`
// }
if (phones) {
CFRelease(phones);
}
[arr_Contacts addObject:dictionary];
}
}
A couple of additional issues addressed above:
The ABAddressBookCreateWithOptions does not return a mutable array. It's an immutable array. Replace all of those mutable references with immutable.
You must honor the Create Rule, namely that you're responsible for releasing any object returned from a Core Foundation method with either Create or Copy in its name. If the object supports toll-free bridging (e.g. the array of contacts, the first name string, the last name string, etc.), you can transfer ownership to ARC with CFBridgingRelease or __bridge_transfer. If the object doesn't support toll-free bridging (such as the phones or addressBook objects, above), then you must explicitly call CFRelease for the object in question.
Make sure to run your code through the static analyzer (shift+command+B, or choose "Analyze" from Xcode's "Product" menu), and it will identify these sorts of issues for you.
If a function, such as ABAddressBookCreateWithOptions offers an error parameter, you should avail yourself of it. I illustrate the proper use of the CFErrorRef object above.
What do you recive in console from Phone %# NSLog ? if Phone ABMultiValueRef 0x17674380 with 1 value(s) 0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)just substring after '-'
NSString *myString = #"Phone ABMultiValueRef 0x17674380 with 1 value(s) 0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)";
NSArray *myArray = [myString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"-"]];
and this is my method to get phone's
- (void) getContacts
{
NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
ABAddressBookRef contactBook = ABAddressBookCreateWithOptions(NULL, NULL);
arr_Contacts = [[NSMutableArray alloc] init];
ABAddressBookRef allPeople = contactBook;
CFArrayRef allContacts = ABAddressBookCopyArrayOfAllPeople(allPeople);
CFIndex numberOfContacts = ABAddressBookGetPersonCount(allPeople);
NSLog(#"contact == %#",allContacts);
NSLog(#"numberOfContacts------------------------------------%ld",numberOfContacts);
for(int i = 0; i < numberOfContacts; i++){
NSString* name = #"";
NSString* phone = #"";
NSString* email = #"";
ABRecordRef aPerson = CFArrayGetValueAtIndex(allContacts, i);
ABMultiValueRef fnameProperty = ABRecordCopyValue(aPerson, kABPersonFirstNameProperty);
ABMultiValueRef lnameProperty = ABRecordCopyValue(aPerson, kABPersonLastNameProperty);
ABMultiValueRef phoneProperty = ABRecordCopyValue(aPerson, kABPersonPhoneProperty);\
ABMultiValueRef emailProperty = ABRecordCopyValue(aPerson, kABPersonEmailProperty);
NSArray *emailArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
NSArray *phoneArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
if (fnameProperty != nil) {
name = [NSString stringWithFormat:#"%#", fnameProperty];
}
if (lnameProperty != nil) {
name = [name stringByAppendingString:[NSString stringWithFormat:#" %#", lnameProperty]];
}
if ([phoneArray count] > 0) {
if ([phoneArray count] > 1) {
for (int i = 0; i < [phoneArray count]; i++) {
phone = [phone stringByAppendingString:[NSString stringWithFormat:#"%#, ", [phoneArray objectAtIndex:i]]];
}
}else {
phone = [NSString stringWithFormat:#"%#", [phoneArray objectAtIndex:0]];
}
}
if ([emailArray count] > 0) {
if ([emailArray count] > 1) {
for (int i = 0; i < [emailArray count]; i++) {
email = [email stringByAppendingString:[NSString stringWithFormat:#"%#\n", [emailArray objectAtIndex:i]]];
}
}else {
email = [NSString stringWithFormat:#"%#", [emailArray objectAtIndex:0]];
}
}
NSLog(#"NAME : %#",name);
NSLog(#"PHONE: %#",phone);
NSLog(#"EMAIL: %#",email);
NSLog(#"\n");
[response setObject:name forKey:#"name"];
[response setObject:phone forKey:#"phone"];
[response setObject:email forKey:#"email"];
[arr_Contacts addObject:response];
}
}
Cheers

App crash when phone contact synced with facebook friends contact in ios

when i am syncing facebook contact in my iphone contact then my app crash in getting all phone contact. App crashed everytime on first name giving bad access. and app work fine if facebook friends is not synced .Here is my code:
+(NSMutableArray *)getAllContacts
{
CFErrorRef *error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
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)
{
#ifdef DEBUG
NSLog(#"Fetching contact info ----> ");
#endif
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
NSMutableArray* items = [NSMutableArray arrayWithCapacity:nPeople];
for (int i = 0; i < nPeople; i++)
{
NSMutableDictionary *contacts = [NSMutableDictionary new];
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
//get First Name and Last Name
NSString *firstName = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName = (__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *name=#"";
if ([firstName length]>0 && [lastName length]>0)
name= [NSString stringWithFormat:#"%# %#",firstName,lastName];
else if ([firstName length]>0 && [lastName length]==0)
name= [NSString stringWithFormat:#"%#",firstName];
else if ([firstName length]==0 && [lastName length]>0)
name= [NSString stringWithFormat:#"%#",lastName];
else
name= #"No Name";
contacts[#"name"]=name;
// get contacts picture, if pic doesn't exists, show standart one
NSData *imgData = (__bridge NSData *)ABPersonCopyImageData(person);
UIImage *image= [UIImage imageWithData:imgData];
if (!image)
image = [UIImage imageNamed:#"profilebase_small.png"];
contacts[#"image"]=image;
//get Phone Numbers
NSMutableArray *phoneNumbers = [[NSMutableArray alloc] init];
ABMultiValueRef multiPhones = ABRecordCopyValue(person, kABPersonPhoneProperty);
for(CFIndex i=0;i<ABMultiValueGetCount(multiPhones);i++) {
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(multiPhones, i);
NSString *phoneNumber = (__bridge NSString *) phoneNumberRef;
[phoneNumbers addObject:phoneNumber];
}
contacts[#"numbers"]=phoneNumbers;
//get Contact email
NSMutableArray *contactEmails = [NSMutableArray new];
ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);
for (CFIndex i=0; i<ABMultiValueGetCount(multiEmails); i++) {
CFStringRef contactEmailRef = ABMultiValueCopyValueAtIndex(multiEmails, i);
NSString *contactEmail = (__bridge NSString *)contactEmailRef;
[contactEmails addObject:contactEmail];
// NSLog(#"All emails are:%#", contactEmails);
}
contacts[#"emails"]=contactEmails;
[items addObject:contacts];
}
return items;
} else
{
#ifdef DEBUG
NSLog(#"Cannot fetch Contacts :( ");
#endif
return NO;
}
}
Replace this line CFIndex nPeople = ABAddressBookGetPersonCount(addressBook); with CFIndex nPeople = CFArrayGetCount(allPeople);

Accessing AddressBook in iOS6

I am currently accessing the user's contacts/address book. When i compile the program through xcode and launch the iPhone simulator, their is data.... because I went into the iPhone simulator contacts app and added them myself to see if the app can actually access the contacts database.
Now when I deploy the app through my iPhone, not the simulator, the app shows no contacts, no info. I understand their are some complications with iOS6 and apple changing some privacy settings around.
Here's my function I have within one of my view controller classes, I call the function
[self getPersonOutOfAddressBook]; to execute the function.
- (void)getPersonOutOfAddressBook
{
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil)
{
NSLog(#"Succesful.");
NSArray *allContacts = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSLog(#"Number of users: %d ", [allContacts count]);
NSUInteger i = 0;
for (i = 0; i < [allContacts count]; i++)
{
Person *person = [[Person alloc] init];
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSString *firstName = (__bridge NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
person.firstName = firstName;
person.lastName = lastName;
person.fullName = fullName;
//email
ABMultiValueRef emails = ABRecordCopyValue(contactPerson, kABPersonEmailProperty);
NSUInteger j = 0;
for (j = 0; j < ABMultiValueGetCount(emails); j++)
{
NSString *email = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(emails, j);
if (j == 0)
{
person.homeEmail = email;
NSLog(#"person.homeEmail = %# ", person.homeEmail);
}
else if (j==1)
person.workEmail = email;
}
[self.tableData addObject:person];
}
}
CFRelease(addressBook);
}
My output is
2013-03-04 22:29:00.094 ourApplication[5562:907] Succesful.
2013-03-04 22:29:00.099 ourApplication[5562:907] Number of users: 0
on my IPHONE
and on my Mac
2013-03-04 22:31:41.799 ourApplication[12591:12b03] Succesful.
2013-03-04 22:31:41.801 ourApplication[12591:12b03] Number of users: 6
And so on...
Weird!!! HELP :(

ios dev ABMultiValueRemoveValueAndLabelAtIndex returns true but doesn't work

I want to delete a specific phone number from an address book contact.
It "seems" to work, because it is returning true, but it doesn't.
Please, could anyone help me out here? This would be awesome!
ABAddressBookRef ab = ABAddressBookCreate();
ABRecordRef record = ABAddressBookGetPersonWithRecordID(ab,[myID intValue]);
NSError *error = NULL;
ABMultiValueRef phoneNumbers = ABRecordCopyValue(record,kABPersonPhoneProperty);
for(CFIndex i=0; i < ABMultiValueGetCount(phoneNumbers); i++){
NSString *phoneNumber = (NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers,i);
//ckDebug(#"phoneNumber = %#", phoneNumber);
if ([[oDict objectForKey:#"value"] isEqualToString:phoneNumber]) {
BOOL didRemove = ABMultiValueRemoveValueAndLabelAtIndex(ABMultiValueCreateMutableCopy(phoneNumbers),i);
ckDebug(#"didRemove = %#\n", (didRemove ? #"TRUE" : #"FALSE"));
//and save it!
BOOL didSave = ABAddressBookSave(ab, (CFErrorRef *) error);
ckDebug(#"didSave = %#\n", (didSave ? #"TRUE" : #"FALSE"));
if (error) {
ckDebug(#"ABAddressBookSaveError = %#", error);
}
}
[phoneNumber release];
}
CFRelease(ab);
So the Solution is:
Creating the MutableCopy of the MultiValueRef, then delete the value from there and set the copy back to the record and save...
like this:
ABAddressBookRef ab = ABAddressBookCreate();
ABRecordRef record = ABAddressBookGetPersonWithRecordID(ab,[myID intValue]);
NSError *error = NULL;
ABMultiValueRef phoneNumbers = ABRecordCopyValue(record,kABPersonPhoneProperty);
ABMutableMultiValueRef phoneNumberMV = ABMultiValueCreateMutableCopy(phoneNumbers);
for(CFIndex i=0; i < ABMultiValueGetCount(phoneNumberMV); i++){
NSString *phoneNumber = (NSString *)ABMultiValueCopyValueAtIndex(phoneNumberMV,i);
//ckDebug(#"phoneNumber = %#", phoneNumber);
if ([[oDict objectForKey:#"value"] isEqualToString:phoneNumber]) {
//now delete it!!! ;-)
/*
ckDebug(#"phoneNumbers = %#",phoneNumbers);
ckDebug(#"index = %d", i);
*/
BOOL didRemove = ABMultiValueRemoveValueAndLabelAtIndex(phoneNumberMV,i);
ckDebug(#"didRemove = %#\n", (didRemove ? #"TRUE" : #"FALSE"));
BOOL didSet = ABRecordSetValue(record, kABPersonPhoneProperty, phoneNumberMV, nil);
ckDebug(#"didSet = %#\n", (didSet ? #"TRUE" : #"FALSE"));
//and save it!
BOOL didSave = ABAddressBookSave(ab, (CFErrorRef *) error);
ckDebug(#"didSave = %#\n", (didSave ? #"TRUE" : #"FALSE"));
if (error) {
ckDebug(#"ABAddressBookSaveError = %#", error);
}
}
[phoneNumber release];
}
CFRelease(ab);
You remove the phone number from a copy of the phone numbers field, but never update the record with the modified list. You need to call ABRecordSetValue before you call ABAddressBookSave.

Get all E-Mail addresses from contacts (iOS)

I know it is possible to pull up a contact and see information based on one contact. But is there any way to get all the emails from the contacts you have entered email addresses for and then store that in a NSArray?
This is my first time working with contacts so I don't know much about it.
Yes, you can do this. It seems suspicious that you would want to do this (why do you need this information?), but it isn't difficult to do.
You can use ABAddressBookCopyArrayOfAllPeople to get an CFArrayRef with all of the people, and then you can query kABPersonEmailProperty of each using ABRecordCopyValue. The code would look something like this (untested):
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSMutableArray *allEmails = [[NSMutableArray alloc] initWithCapacity:CFArrayGetCount(people)];
for (CFIndex i = 0; i < CFArrayGetCount(people); i++) {
ABRecordRef person = CFArrayGetValueAtIndex(people, i);
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
for (CFIndex j=0; j < ABMultiValueGetCount(emails); j++) {
NSString* email = (NSString*)ABMultiValueCopyValueAtIndex(emails, j);
[allEmails addObject:email];
[email release];
}
CFRelease(emails);
}
CFRelease(addressBook);
CFRelease(people);
(Memory allocation may be a little off; it's been a while since I've developed Cocoa/Core Foundation code.)
But seriously, question why you are doing this. There's a good chance that there's a better solution by just using the Apple-provided APIs to present a contact picker at appropriate times.
ABAddressBookRef allPeople = ABAddressBookCreate();
CFArrayRef allContacts = ABAddressBookCopyArrayOfAllPeople(allPeople);
CFIndex numberOfContacts = ABAddressBookGetPersonCount(allPeople);
NSLog(#"numberOfContacts------------------------------------%ld",numberOfContacts);
for(int i = 0; i < numberOfContacts; i++){
NSString* name = #"";
NSString* phone = #"";
NSString* email = #"";
ABRecordRef aPerson = CFArrayGetValueAtIndex(allContacts, i);
ABMultiValueRef fnameProperty = ABRecordCopyValue(aPerson, kABPersonFirstNameProperty);
ABMultiValueRef lnameProperty = ABRecordCopyValue(aPerson, kABPersonLastNameProperty);
ABMultiValueRef phoneProperty = ABRecordCopyValue(aPerson, kABPersonPhoneProperty);\
ABMultiValueRef emailProperty = ABRecordCopyValue(aPerson, kABPersonEmailProperty);
NSArray *emailArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
NSArray *phoneArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
if (fnameProperty != nil) {
name = [NSString stringWithFormat:#"%#", fnameProperty];
}
if (lnameProperty != nil) {
name = [name stringByAppendingString:[NSString stringWithFormat:#" %#", lnameProperty]];
}
if ([phoneArray count] > 0) {
if ([phoneArray count] > 1) {
for (int i = 0; i < [phoneArray count]; i++) {
phone = [phone stringByAppendingString:[NSString stringWithFormat:#"%#\n", [phoneArray objectAtIndex:i]]];
}
}else {
phone = [NSString stringWithFormat:#"%#", [phoneArray objectAtIndex:0]];
}
}
if ([emailArray count] > 0) {
if ([emailArray count] > 1) {
for (int i = 0; i < [emailArray count]; i++) {
email = [email stringByAppendingString:[NSString stringWithFormat:#"%#\n", [emailArray objectAtIndex:i]]];
}
}else {
email = [NSString stringWithFormat:#"%#", [emailArray objectAtIndex:0]];
}
}
NSLog(#"NAME : %#",name);
NSLog(#"PHONE: %#",phone);
NSLog(#"EMAIL: %#",email);
NSLog(#"\n");
}
#import AddressBook;
- (void)addressBookInit {
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusDenied || ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusRestricted){
// NSLog(#"Denied");
UIAlertView *cantAddContactAlert = [[UIAlertView alloc] initWithTitle: #"Cannot get contacts" message: #"You must give the app permission to read the contacts first." delegate:nil cancelButtonTitle: #"OK" otherButtonTitles: nil];
[cantAddContactAlert show];
} else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized){
// NSLog(#"Authorized");
[self getEmails];
} else {
// NSLog(#"Not determined");
ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool granted, CFErrorRef error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!granted){
//4
UIAlertView *cantAddContactAlert = [[UIAlertView alloc] initWithTitle: #"Cannot get contacts" message: #"You must give the app permission to read the contacts first." delegate:nil cancelButtonTitle: #"OK" otherButtonTitles: nil];
[cantAddContactAlert show];
return;
}
// NSLog(#"Authorized 2");
[self getEmails];
});
});
}
}
-(NSArray *)getEmails
{
NSMutableArray *emails = [NSMutableArray array];
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil);
NSArray *allContacts = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBookRef);
for (id record in allContacts)
{
ABRecordRef person = (__bridge ABRecordRef)record;
ABMultiValueRef emailProperty = ABRecordCopyValue(person, kABPersonEmailProperty) ;
NSArray *personEmails = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
[emails addObjectsFromArray:personEmails];
CFRelease(person);
CFRelease(emailProperty);
}
CFRelease(addressBookRef) ;
for (NSString *email in emails)
{
NSLog(#"%#", email) ;
}
return emails;
}
for iOS 9+, use Contacts framework, Objective C
-(NSArray*)getAllContacts{
__block NSMutableArray *allContacts = nil;
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, CNContactEmailAddressesKey, CNContactImageDataKey];
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 {
allContacts = [NSMutableArray array];
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
// create custom class Contacts with firstName,lastName,image and emailAddress
for (CNLabeledValue<NSString*> *email in contact.emailAddresses) {
Contact *newContact = [[Contact alloc] init];
newContact.firstName = contact.givenName;
newContact.lastName = contact.familyName;
UIImage *image = [UIImage imageWithData:contact.imageData];
newContact.image = image;
newContact.emailAddress = email.value;
[allContacts addObject:newContact];
}
}
}
}
}];
return allContacts;}