Guys am working on a calling app for Ios,so naturally i have a dial-pad integrated.
The problem am facing in to get the contact details from number dialed from my dial-pad which i am showing in other screen.
Here is my code
+(PhoneContactModel*) getContactFrom:(NSString *)calledPhoneNumber{
PhoneContactModel *contact=[[PhoneContactModel alloc]init];
ABAddressBookRef addressBook = [AppUtils getCompatibleAdressBook];
CFArrayRef all = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex n = ABAddressBookGetPersonCount(addressBook);
for( int i = 0 ; i < n ; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex(all, i);
ABMultiValueRef phones = (ABMultiValueRef)ABRecordCopyValue(ref, kABPersonPhoneProperty);
for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++)
{
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j);
//CFRelease(phones);
NSString *phoneNumber = (__bridge NSString *)phoneNumberRef;
NSLog(#"apputil number %#",[AppUtils getNumberSanatized:phoneNumber]);
if ([phoneNumber isEqualToString:calledPhoneNumber]){
NSLog(#"apputil number matched %#",[AppUtils getNumberSanatized:phoneNumber]);
contact.strFullName = (__bridge_transfer NSString *) ABRecordCopyValue(ref, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *) ABRecordCopyValue(ref, kABPersonLastNameProperty);
contact.strFullName=[contact.strFullName stringByAppendingString:#" "];
if (lastName!=nil){
contact.strFullName=[contact.strFullName stringByAppendingString:lastName];
}
contact.imgContactImge=[AppUtils imageForContact:ref];
contact.strNumber=phoneNumber;
return contact;
}
}
}
contact.strFullName = calledPhoneNumber;
return contact;
}
The problem appears like if i have a Contact A with number 64xxxx... and i dial +164xxxx.. from my dial-pad i don't get the contact details, Also you can see that in the method above i have to run a loop to find the matching contact even if there is a match, so is there a better method out there to do the same
Thanks
I created a better solution
it can be seen here http://codesnight.blogspot.in/2013/11/ios-acces-contacts-from-number.html
Related
I am using the following code to get mobile number (i.e. 1st phone number) of all contacts in my address book. I want to store all those number into NSArray
self.dataSource = [[NSMutableArray alloc]init]; // dataSouce is delared in .h file
ABAddressBookRef addressBook = ABAddressBookCreate();
NSMutableArray *allPeople = (__bridge NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
int nPeople = ABAddressBookGetPersonCount(addressBook);
for(int i=0; i < nPeople; i++ ){
ABRecordRef person = (__bridge ABRecordRef)([allPeople objectAtIndex:i]);
NSString *name = #"";
if(ABRecordCopyValue(person, kABPersonFirstNameProperty) != NULL)
name = [[NSString stringWithFormat:#"%#", ABRecordCopyValue(person, kABPersonFirstNameProperty)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[_dataSource addObject: name];
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);
_phoneNumbers = (__bridge NSArray*)ABMultiValueCopyValueAtIndex(phoneNumberProperty, 0);
CFRelease(phoneNumberProperty);
NSLog(#"Phone numbers = %#", _phoneNumbers);
}
but when I use NSLog(#"Phone numbers = %#", _phoneNumbers); the output comes out as
2012-11-07 15:31:06.116 contacts[4938:12b03] Phone numbers = 1 (800) 111-1111
2012-11-07 15:31:06.117 contacts[4938:12b03] Phone numbers = (222) 355-5668
2012-11-07 15:31:06.118 contacts[4938:12b03] Phone numbers = (910) 192-0192
I want the output in NSArray like
Phone numbers = (
"1 (800) 111-1111",
"(222) 355-5668",
"(910) 192-0192"
)
how can I do this ?
you Can Do it Simply like this
self.dataSource = [[NSMutableArray alloc]init]; // dataSouce is delared in .h file
ABAddressBookRef addressBook = ABAddressBookCreate();
NSMutableArray *allPeople = (__bridge NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
int nPeople = ABAddressBookGetPersonCount(addressBook);
NSMutableArray *arrContacts = [[NSMutableArray alloc] init];
for(int i=0; i < nPeople; i++ ){
ABRecordRef person = (__bridge ABRecordRef)([allPeople objectAtIndex:i]);
NSString *name = #"";
if(ABRecordCopyValue(person, kABPersonFirstNameProperty) != NULL)
name = [[NSString stringWithFormat:#"%#", ABRecordCopyValue(person, kABPersonFirstNameProperty)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[_dataSource addObject: name];
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);
_phoneNumbers = (__bridge NSArray*)ABMultiValueCopyValueAtIndex(phoneNumberProperty, 0);
CFRelease(phoneNumberProperty);
NSLog(#"Phone numbers = %#", _phoneNumbers);
[arrContacts addObject:_phoneNumbers];
}
NSLog(#"Phone numbers : %#",arrContacts);
I found this via Google and was using this address book code as an example, but found a mistake that I'd correct for others coming here.
When using ABMultiValueCopyValueAtIndex it returns a type CFTypeRef. That function gets just the phone number at that index (in this case at index 0) which in the case of the phone number is a CFStringRef that shouldn't be cast to an NSArray*.
ABMultiValueCopyArrayOfAllValues would be the proper call to get the array of all phone numbers stored in a contact. That can be stored into an array and logged like Sarafaraz is doing in his answer.
NSArray *_phoneNumbers = (__bridge NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty);
If you just want to get the first phone number you would do this:
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phoneNumberProperty, 0);
NSString *phoneString = (__bridge NSString*)phoneNumberRef;
I am using an ABPeoplePickerNavigationController to collect an array of email addresses and phone numbers from a contact book entry. 90% of the time it works fine but a few testers are reporting crashes. The crash report says it is crashing at CFRelease ... Not sure why considering I believe my code is correct. Take a look:
ABProfile *selectedUser = [[ABProfile alloc]init];
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
NSArray *emailArray;
if (ABMultiValueGetCount(emails) > 0) {
emailArray = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(emails);
}
CFRelease(emails);
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSMutableArray *phonesArray = [[NSMutableArray alloc]initWithCapacity:1];
for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++)
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc]initWithCapacity:1];
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(phones, j);
NSString *phoneLabel =(__bridge_transfer NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
CFRelease(locLabel);
[dict setValue:phoneLabel forKey:#"label"];
NSString *phoneNumber = (__bridge_transfer NSString *)phoneNumberRef;
[dict setValue:phoneNumber forKey:#"number"];
[phonesArray addObject:dict];
}
selectedUser.phones = phonesArray;
CFRelease(phones);
ABMultiValueCopyLabelAtIndex can return NULL if not found, and CFRelease(NULL) will crash. I would cheek to ensure locLabel exists before doing anything with it.
I'm able to pull the first name and the last name of the contact list from iphone sdk, however I'm unable to fetch the phone number from it. I'm getting the error if I try other way, and the usual way I'm getting other stuff with phone number here is the details with the code:
- (IBAction)buttonmessage {
ABAddressBookRef addressBook = ABAddressBookCreate(); // create address book reference object
NSArray *abContactArray = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); // get address book contact array
NSInteger totalContacts = [abContactArray count];
for(NSUInteger loop= 0 ; loop < totalContacts; loop++)
{
ABRecordRef record = (__bridge ABRecordRef)[abContactArray objectAtIndex:loop]; // get address book record
if(ABRecordGetRecordType(record) == kABPersonType) // this check execute if it is person group
{
ABRecordID recordId = ABRecordGetRecordID(record); // get record id from address book record
recordIdString = [NSString stringWithFormat:#"%d",recordId]; // get record id string from record id
firstNameString = (__bridge NSString*)ABRecordCopyValue(record,kABPersonFirstNameProperty); // fetch contact first name from address book
lastNameString = (__bridge NSString*)ABRecordCopyValue(record,kABPersonLastNameProperty); // fetch contact last name from address book
NSString *phnumber = (__bridge NSString *)ABRecordCopyValue(record, kABPersonPhoneProperty);
myArray2 = [NSArray arrayWithObjects:firstNameString,lastNameString,phnumber,nil];
NSString *m12=[NSString stringWithFormat:#"%#,%#,%#",[myArray2 objectAtIndex:0],[myArray2 objectAtIndex:1],[myArray2 objectAtIndex:2]];
}
Output:
Abdullah,Rashed,ABMultiValueRef 0x80426a0 with 1 value(s)
0: _$!<Mobile>!$_ (0x8042da0) - 0550979691 (0x8042dc0)
2012-05-07 14:43:06.670 Firstphase[2914:207] Hussain,Mahmood,ABMultiValueRef 0x80442d0 with 1 value(s)
0: _$!<Mobile>!$_ (0x8044290) - 055979896 (0x80442b0)
2012-05-07 14:43:06.671 Firstphase[2914:207] Nasir,Jilaani,ABMultiValueRef 0x8046070 with 1 value(s)
0: _$!<Mobile>!$_ (0x8046000) - 055982391 (0x8046020)
2012-05-07 14:43:06.673 Firstphase[2914:207] Ghulam,Basith,ABMultiValueRef 0x8046850 with 1 value(s)
0: _$!<Mobile>!$_ (0x8046810) - 055871943 (0x8046830)
However if you take a close look i'm able to get the firstname and last name without any extra stuff. But I'm not able to get the phone numbers in the same way.
ABMutableMultiValueRef multi;
int multiCount = 0;
multi = ABRecordCopyValue(record, kABPersonPhoneProperty);
multiCount = ABMultiValueGetCount(multi);
for (int i = 0; i < multiCount; i++) {
phoneNumber = (NSString * ) ABMultiValueCopyValueAtIndex(multi, i);
[someArray addObject: phoneNumber];
}
check this:
Your problem may solve with this answer or this.
As of I understand ABRecordCopyValue(ref, kABPersonPhoneProperty) returns some array value. And you are trying to get a String thats why you may face the issue. I didn't tried this solution but think it will work.
Hope this helps.
Try the following:
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(record, kABPersonPhoneProperty);
NSArray *phoneNumbers = (NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty);
for (id number in phoneNumbers) {
// do whatever you want
}
The following code will retrieve all the phone numbers from the contact list:-
ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
for ( int i = 0; i < nPeople; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, i );
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(ref, kABPersonPhoneProperty);
NSArray* phoneNumbers = (NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty);
CFRelease(phoneNumberProperty);
[phoneNumbers release];
}
It will work..
-(void)displayPerson
{
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil)
{
NSLog(#"Succesful.");
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger i = 0;
for (i = 0; i < [allContacts count]; i++)
{
Person *person = [[Person alloc] init];
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
NSString *phone=nil;
ABMultiValueRef phoneNumbers = ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);
if (ABMultiValueGetCount(phoneNumbers) > 0) {
phone = (__bridge_transfer NSString*)
ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
} else {
phone = #"[None]";
}
person.fullname = fullName;
person.phoneNum=phone;
[self.tableData addObject:person];
person=nil;
}
CFRelease(addressBook);
}
}
Now i ve got this code:
-(void)getContacts{
ABAddressBookRef currentAddressBook = ABAddressBookCreate();
if (currentAddressBook) {
CFArrayRef allBook = ABAddressBookCopyArrayOfAllPeople(currentAddressBook);
if (allBook) {
for (int index=0; index < CFArrayGetCount(allBook); index++){
ABRecordRef currentPerson = CFArrayGetValueAtIndex(allBook, index);
NSString *firstName = (__bridge NSString *)ABRecordCopyValue(currentPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge NSString *)ABRecordCopyValue(currentPerson, kABPersonLastNameProperty);
NSData *imageData = (__bridge NSData*)ABPersonCopyImageDataWithFormat(currentPerson, kABPersonImageFormatThumbnail);
NSMutableArray *tempArrayForPhones = [[NSMutableArray alloc] init];
ABMultiValueRef phoneNumbersMultiValue = ABRecordCopyValue(currentPerson, kABPersonPhoneProperty);
for(CFIndex counter = 0; counter < ABMultiValueGetCount(phoneNumbersMultiValue); counter++){
CFStringRef currentLabel = ABMultiValueCopyLabelAtIndex(phoneNumbersMultiValue, counter);
NSString *phoneLabel =(__bridge NSString*) ABAddressBookCopyLocalizedLabel(currentLabel);
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phoneNumbersMultiValue, counter);
currentLabel = ABMultiValueCopyLabelAtIndex(phoneNumbersMultiValue, counter);
phoneLabel =(__bridge NSString*) ABAddressBookCopyLocalizedLabel(currentLabel);
NSString *phoneNumber = (__bridge NSString *)phoneNumberRef;
CFRelease(phoneNumberRef);
CFRelease(currentLabel);
NSDictionary *tempDictForPhonew = [NSDictionary dictionaryWithObjectsAndKeys:phoneNumber,#"number",
phoneLabel,#"label",
nil];
[tempArrayForPhones addObject:tempDictForPhonew];
}
NSDictionary *dictionaryWithAddressBook = [NSDictionary dictionaryWithObjectsAndKeys:firstName,#"firstName",
lastName,#"lastName",
imageData,#"image",
tempArrayForPhones,#"phones",
nil];
tempArrayForPhones = nil;
[dataArray addObject:dictionaryWithAddressBook];
CFRelease(phoneNumbersMultiValue);
}
CFRelease(allBook);
}
CFRelease(currentAddressBook);
}
}
all works fine on simulator, i get array with dictionary, which contains all fields i need. But when i run code on real device(iOS 5.1) dictionary got only first name and last name.
I tried to do some nslog around initializing dictionary, and temp dictionary with phones and image data existed, but not in final dataArray. Whats wrong?
Problem solved; It was a mistake in parsing address book; I forgot to handle contacts without first name.
I know how to get the phone number from an ABRecordRef, but what I want now is to also get the type of the number, i.e. its label as a string:
const CFStringRef kABPersonPhoneIPhoneLabel;
const CFStringRef kABPersonPhoneMainLabel;
const CFStringRef kABPersonPhoneHomeFAXLabel;
const CFStringRef kABPersonPhoneWorkFAXLabel;
const CFStringRef kABPersonPhonePagerLabel;
Here is how I get the numbers:
//get all phone numbers
NSArray *phoneNumbersArray = (NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty);
NSInteger numbersCounter = 0;
for(numbersCounter = 0; numbersCounter < [phoneNumbersArray count]; numbersCounter++)
{
NSString currentPhoneNumber = [phoneNumbersArray objectAtIndex:indexPhoneNumber];
// here i would like to read the type of phone number
// NSLog(#"NumberType:%#",numberType);
}
I tried all sorts of things and I've read the ABPerson Reference and I don't know how to get the phone number type?
I have figure out how to read the localized label of the phone number
//get all phone numbers
ABMultiValueRef phoneNumberMultiValue = ABRecordCopyValue(currentPerson, kABPersonPhoneProperty);
NSUInteger phoneNumberIndex;
for (phoneNumberIndex = 0; phoneNumberIndex < ABMultiValueGetCount(phoneNumberMultiValue); phoneNumberIndex++) {
CFStringRef labelStingRef = ABMultiValueCopyLabelAtIndex (phoneNumberMultiValue, phoneNumberIndex);
NSString *phoneLabelLocalized = (NSString*)ABAddressBookCopyLocalizedLabel(labelStingRef);
NSString *phoneNumber = (NSString *)ABMultiValueCopyValueAtIndex(phoneNumberMultiValue, phoneNumberIndex);
//memory management
[phoneLabelLocalized release];
[phoneNumber release];
CFRelease(labelStingRef);
}
Here's a code snippet that creates a person, adds 2 phone contacts and then shows how to get at the label and value for the phone property:
ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueIdentifier multivalueIdentifier;
ABMultiValueAddValueAndLabel(multi, #"(555) 555-1234",
kABPersonPhoneMobileLabel, &multivalueIdentifier);
ABMultiValueAddValueAndLabel(multi, #"(555) 555-2345",
kABPersonPhoneMainLabel, &multivalueIdentifier);
ABRecordRef aRecord = ABPersonCreate();
CFErrorRef anError = NULL;
ABRecordSetValue(aRecord, kABPersonPhoneProperty, multi, &anError);
CFRelease(multi);
multi = ABRecordCopyValue(aRecord, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++)
{
CFStringRef phoneNumber, phoneNumberLabel;
phoneNumberLabel = ABMultiValueCopyLabelAtIndex(multi, i);
phoneNumber = ABMultiValueCopyValueAtIndex(multi, i);
NSLog(#"%# %#", (NSString *) phoneNumberLabel, (NSString *) phoneNumber);
CFRelease(phoneNumberLabel);
CFRelease(phoneNumber);
}
CFRelease(aRecord);
CFRelease(multi);
In the code it iterates over all the multi-values and extracts the label and number as it goes, using ABMultiValueCopyLabelAtIndex and ABMultiValueCopyValueAtIndex respectively.