storing addressbook contacts into a nsdictionary - iphone

I'm still trying to wrap my head around using NSDictionaries, and have come into a situation where I believe I need to use one. essentially, I would like to store all the phone numbers associated with each contact into a dictionary. so far I have this:
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
for (id person in thePeople)
{
ABMultiValueRef phones =(NSString*)ABRecordCopyValue(person, kABPersonPhoneProperty);
NSString* name = (NSString *)ABRecordCopyCompositeName(person);
for (CFIndex i = 0; i < ABMultiValueGetCount(phones); i++)
{
NSString *phone = [(NSString *)ABMultiValueCopyValueAtIndex(phones,i) autorelease];
}
}
I was wondering how to use a nsdictionary to store each person, and then an array of each phone value that's associated with that person.

What are you trying to do?
You can put all names and phonenumbers into a plist like this:
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSMutableArray* allPeoplesDicts = [NSMutableArray array];
for (id person in thePeople)
{
ABMultiValueRef phones =(NSString*)ABRecordCopyValue(person, kABPersonPhoneProperty);
NSString* name = (NSString *)ABRecordCopyCompositeName(person);
NSMutableArray* phones = [[NSMutableArray alloc] init];
for (CFIndex i = 0; i < ABMultiValueGetCount(phones); i++)
{
NSString *phone = [(NSString *)ABMultiValueCopyValueAtIndex(phones,i) autorelease];
[phones addObject:phone];
}
NSDictionary* personDict = [[NSDictionary alloc] initWithObjectsAndKeys:name,#"Name",phones,#"PhoneNumbers",nil];
[phones release];
[allPeoplesDicts addObject:personDict];
[personDict release];
}

Related

How to create NSMutableDictionary with multiple types for contacts in addressbook?

This is a function that I use to fetch the contact name and email from the addressbook.
-(void) fetchFriendsAllDetails {
NSMutableArray *allEmails = [[NSMutableArray alloc] initWithCapacity:_peopleList.count];
for (int i = 0; i < _peopleList.count; i++) {
ABRecordRef person = (__bridge ABRecordRef)([_peopleList objectAtIndex:i]);
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
NSString *name=[[NSString stringWithFormat:#"%#",(__bridge_transfer NSString *)ABRecordCopyCompositeName(person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSLog(#"id:%d,name:%#",i,name);
for (int j=0; j < ABMultiValueGetCount(emails); j++) {
NSString* email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emails, j);
[allEmails addObject:email];
NSLog(#"id:%d,email:%#",i,email);
}
}
}
The output of the above is as follows:
id:0,name:John Appleseed
id:0,email:John-Appleseed#mac.com
id:1,name:Kate Bell
id:1,email:kate-bell#mac.com
id:1,email:www.icloud.com
id:2,name:Anna Haro
id:2,email:anna-haro#mac.com
id:3,name:Daniel Higgins Jr.
id:3,email:d-higgins#mac.com
id:4,name:David Taylor
id:5,name:Hank M. Zakroff
id:5,email:hank-zakroff#mac.com
I want to make a dictionary in the above function that will contain the output in the following format
{
id:0
name:John Appleseed
email:John-Appleseed#mac.com
selectedFlag:NO
},
{
id:1
name:Kate Bell
email:kate-bell#mac.com, www.icloud.com
selectedFlag:NO
},
{
id:2
name:Anna Haro
email:John-Appleseed#mac.com
selectedFlag:NO
},
{
id:3
name:Daniel Higgins Jr.
email:d-higgins#mac.com
selectedFlag:NO
},
{
id:4
name:David Taylor
email:""
selectedFlag:NO
},
id:5
nameHank M. Zakroff
email:hank-zakroff#mac.com
selectedFlag:NO
}
I have basic understanding about NSMutableDictionary, but dont know in through detail to implement this. Can you help me create it?
Use NSMutableDictionary's setObject:forKey: method.
- (void)setObject:(id)anObject forKey:(id < NSCopying >)aKey
From official documentation, this method:
Adds a given key-value pair to the dictionary.
For example, we can modify your code to create the required array of dictionaries. We create an NSMutabeDictionary object for every index of for-loop and keep adding it in an
NSMutableArray object.
-(void) fetchFriendsAllDetails
{
// allocate array
NSMutableArray *array = [[NSMutableArray alloc]init];
NSMutableArray *allEmails = [[NSMutableArray alloc] initWithCapacity:_peopleList.count];
NSMutableDictionary *dictionary;
for (int i = 0; i < _peopleList.count; i++)
{
dictionary = [[NSMutableDictionary alloc]init];
ABRecordRef person = (__bridge ABRecordRef)([_peopleList objectAtIndex:i]);
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
NSString *name=[[NSString stringWithFormat:#"%#",(__bridge_transfer NSString *)ABRecordCopyCompositeName(person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// create key -vale pair for id and name
[dictionary setObject:[NSNumber numberWithInt:i] forKey:#"id"]; // here we used int wrapped inside and //object because NSMutable Dictionary expects an object instead of scalar type int.
[dictionary setObject:name forKey:#"name"];
NSLog(#"id:%d,name:%#",i,name);
// Create an NSMutableString to hold more than one email
NSMutableString *mutableEmail = [[NSMutableString alloc]init];
for (int j=0; j < ABMultiValueGetCount(emails); j++)
{
NSString* email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emails, j);
[mutableEmail appendString:email];
// append comma to separate more than one mail
if(j != ABMultiValueGetCount(emails) - 1)
{
[mutableEmail appendString:#","];
}
[allEmails addObject:email];
NSLog(#"id:%d,email:%#",i,email);
}
[dictionary setObject:mutableEmail forKey:#"email"];
// for boolean also. wrap inside an object
[dictionary setObject:[NSNumber numberWithBool:NO] forKey:#"id"];
// add dictionary to array
[array addObject:dictionary];
}
}
PS: I am writing this in Windows so please pardon me for any typos.
Did for your first part. Please try :-
NSDictionary *countriesListedByLetter = #{#"id" : #"0", #"name" : #"John Appleseed", #"email" : #"John-Appleseed#mac.com", #"selectedFlag": #"NO"};
NSLog(#"%#",countriesListedByLetter);
OUtPUt:--
{
email = "John-Appleseed#mac.com";
id = 0;
name = "John Appleseed";
selectedFlag = NO;
}
It looks like you want an array of dictionaries.
-(void) fetchFriendsAllDetails
{
NSMutableArray *allContacts = [[NSMutableArray alloc] initWithCapacity:_peopleList.count];
for (NSUInteger i = 0; i < _peopleList.count; i++)
{
ABRecordRef person = (__bridge ABRecordRef)([_peopleList objectAtIndex:i]);
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
NSString *name=[[NSString stringWithFormat:#"%#",(__bridge_transfer NSString *)ABRecordCopyCompositeName(person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSLog(#"id:%d,name:%#",i,name);
NSUInteger count = ABMultiValueGetCount(emails);
NSMutableArray *emailsM = [[NSMutableArray alloc] initWithCapacity:count];
for (NSUInteger j=0; j < ABMultiValueGetCount(emails); j++)
{
NSString* email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emails, j);
[emailsM addObject:email];
// NSLog(#"id:%d,email:%#",i,email);
}
[allContacts addObject:#{#"id": #(i),
#"name": name,
#"email": [NSArray arrayWithArray:emailsM],
#"selectedFlag": #(NO)}];
}
}
Try look in to the array of dictionaries.
NSMutableArray *allEmails = [[NSMutableArray alloc] initWithCapacity:_peopleList.count];
for (int i = 0; i < _peopleList.count; i++)
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init] ;
ABRecordRef person = (__bridge ABRecordRef)([_peopleList objectAtIndex:i]);
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
NSString *name=[[NSString stringWithFormat:#"%#",(__bridge_transfer NSString *)ABRecordCopyCompositeName(person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSLog(#"id:%d,name:%#",i,name);
[dict setObject:[NSNumber numberWithInt:i] forKey:#"id"];
[dict setObject:[NSNumber numberWithBool:false] forKey:#"seletedFlag"];
[dict setObject:name forKey:#"name"];
for (int j=0; j < ABMultiValueGetCount(emails); j++)
{
NSString* email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emails, j);
[dict setObject:email forKey:#"email"];
NSLog(#"id:%d,email:%#",i,email);
}
[allEmails addObject:dict];
[dict release];
}
}
NSLog(#"%#",allEmails);
Try this:
-(void) fetchFriendsAllDetails
{
NSMutableArray *allEmails = [[NSMutableArray alloc] initWithCapacity:_peopleList.count];
for (int i = 0; i < _peopleList.count; i++)
{
NSMutableDictionary *addressesDict = [[NSMutableDictionary alloc] initWithCapacity:4];
ABRecordRef person = (__bridge ABRecordRef)([_peopleList objectAtIndex:i]);
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
NSString *name=[[NSString stringWithFormat:#"%#",(__bridge_transfer NSString *)ABRecordCopyCompositeName(person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSLog(#"id:%d,name:%#",i,name);
[addressesDict setValue:[NSString stringWithFormat:#"%i",i] forKey:#"id"];
[addressesDict setValue:name forKey:#"name"];
for (int j=0; j < ABMultiValueGetCount(emails); j++)
{
NSMutableString *emailString = [[NSMutableString alloc]init];
NSString* email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emails, j);
[emailString appendString:email];
if(j != ABMultiValueGetCount(emails) - 1)
{
[emailString appendString:#","];
}
[allEmails addObject:emailString];
[emailString release];
}
[addressesDict setValue:#"NO" forKey:#"selectedFlag"];
[allEmails addObject:addressesDict];
}
NSLog(#"RESULT: %#",allEmails);
}

Xcode, only retrieving addressbook last names with the letter A(and so on)

i am having trouble retrieving the last names of my addressbook. I only want to retrieve last names by each letter of the alphabet.
this is the codes i have so far
ABAddressBookRef addressBook = ABAddressBookCreate();
totalPeople = (__bridge_transfer NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSString *aString = #"A";
for(int i =0;i<[totalPeople count];i++){
ABRecordRef thisPerson = (__bridge ABRecordRef)
[totalPeople objectAtIndex:i];
lastName = (__bridge_transfer NSString *) ABRecordCopyValue(thisPerson, kABPersonLastNameProperty);
}
I dont know what to do after, thank you for looking at this.
now it is like this
ABAddressBookRef addressBook = ABAddressBookCreate();
totalPeople = (__bridge_transfer NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSString *aString = #"A";
for(int i =0;i<[totalPeople count];i++){
ABRecordRef thisPerson = (__bridge ABRecordRef)
[totalPeople objectAtIndex:i];
lastName = (__bridge_transfer NSString *) ABRecordCopyValue(thisPerson, kABPersonLastNameProperty);
NSString *firstLetterOfCopiedName = [lastName substringWithRange: NSMakeRange(0,1)];
if ([firstLetterOfCopiedName compare: aString options: NSCaseInsensitiveSearch] == NSOrderedSame) {
//This person's last name matches the string aString
aArray = [[NSArray alloc]initWithObjects:lastName, nil];
}
}
it onlys adds one name to the array, what should i do in order to add it all.
sorry guys, i am fairly new to ios developing!
You could use something like this and store the result in an array or return the result. (Not tested)
NSString *firstLetterOfCopiedName = [lastName substringWithRange: NSMakeRange(0,1)];
if ([firstLetterOfCopiedName compare: aString options: NSCaseInsensitiveSearch] == NSOrderedSame) {
//This person's last name matches the string aString
}
You need to alloc the array outside the loop (otherwise it will only ever contain one object), the array also has to be an NSMutableArray (so it can be modified). Here is an example:
ABAddressBookRef addressBook = ABAddressBookCreate();
totalPeople = (__bridge_transfer NSMutableArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSString *aString = #"A";
//This is the resulting array
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
for(int i =0;i<[totalPeople count];i++){
ABRecordRef thisPerson = (__bridge ABRecordRef)
[totalPeople objectAtIndex:i];
lastName = (__bridge_transfer NSString *) ABRecordCopyValue(thisPerson, kABPersonLastNameProperty);
NSString *firstLetterOfCopiedName = [lastName substringWithRange: NSMakeRange(0,1)];
if ([firstLetterOfCopiedName compare: aString options: NSCaseInsensitiveSearch] == NSOrderedSame) {
//This person's last name matches the string aString
[resultArray addObject: lastName];
}
}
//print contents of array
for(NSString *lastName in resultArray) {
NSLog(#"Last Name: %#", lastName);
}

How to get email address and name from iPhone address

I have tried this but it crashes:
- (NSDictionary *)contacts {
NSMutableArray *result = [NSMutableArray array];
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFRelease(addressBook);
NSArray *peopleArray = (NSArray *)people;
// Return if there are no contacts in the address book
if (peopleArray && peopleArray.count > 0) {
for (int i = 0; i <= peopleArray.count - 1; i++) {
ABRecordRef person = [peopleArray objectAtIndex:i];
ABRecordID sourceID = ABRecordGetRecordID(person);
ABMutableMultiValueRef multiEmail = ABRecordCopyValue(person, kABPersonEmailProperty);
NSString *emailAddress = (NSString *) ABMultiValueCopyValueAtIndex(multiEmail, 0); //EXE BAD ACCESS
[emailAddress release];
CFRelease(multiEmail);
NSLog(#"email address %#", emailAddress);
NSString *sourceId = [NSString stringWithFormat:#"%i", sourceID];
NSLog(#"%#", sourceId);
}
}
if (peopleArray) CFRelease(people);
return [NSArray arrayWithArray:result];
}
Try not to release addressBook until you have done. I had a similar problem and that fixed the issue.

Can we access the emailids from the contactlist from iPhone?

Can we access all the email IDs for each contact from the iPhone contactlist through code?
You will get the individual email ids by given code...
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSString *contactName = lblTitle.text;
for(int i = 0;i<ABAddressBookGetPersonCount(addressBook);i++)
{
ABRecordRef person = CFArrayGetValueAtIndex(people, i);
NSString *strEmail = [arContactData valueForKey:#"Email"];
NSMutableArray *arEmailList = [[NSMutableArray alloc] init];
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
for(CFIndex idx = 0; idx < ABMultiValueGetCount(emails); idx++)
{
CFStringRef emailRef = ABMultiValueCopyValueAtIndex(emails, idx);
NSString *strLbl = (NSString*)ABAddressBookCopyLocalizedLabel (ABMultiValueCopyLabelAtIndex (emails, idx));
NSDictionary *dicTemp = [[NSDictionary alloc]initWithObjectsAndKeys:strEmail,#"value", strLbl,#"label", nil];
[arEmailList addObject:dicTemp];
}
}
Sure, use the ABAdressBook class:
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
Now you have all contacts in the allPeople array, then just get the email by key.

How to put my address book data into UITextField

ABAddressBookRef _addressBookRef = ABAddressBookCreate ();
NSArray* allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(_addressBookRef);
NSMutableArray* _allItems = [[NSMutableArray alloc] initWithCapacity:[allPeople count]]; // capacity is only a rough guess, but better than nothing
for (id record in allPeople) {
CFTypeRef phoneProperty = ABRecordCopyValue((ABRecordRef)record, kABPersonPhoneProperty);
NSArray *phones = (NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
CFRelease(phoneProperty);
for (NSString *phone in phones) {
NSString* compositeName = (NSString *)ABRecordCopyCompositeName((ABRecordRef)record);
NSString* field = [NSString stringWithFormat#"%#:%#",compositeName,phone];
[compositeName release];
[_allItems addObject:field];
}
[phoness release];
}
CFRelease(_addressBookRef);
[allPeople release];
allPeople = nil;
Thats my code now i need assistance with what to import && how would i set my UITextView as that
Thanks for any help
This code puts name and phone number in the _allItems array, which you can subsequently use to fill a textview with:
for ( NSString *txt in _allItems )
{
mytextview.text = [mytextview.text stringByAppendingFormat:#"%#\n",txt];
}
assuming you have a UITextView hooked up named mytextview.