Filter Companies from Address Book References - iphone

Using the 'AddressBook.framework' is it possible to filter out all companies (i.e. just people). For example, how would one modify the following code to remove companies:
ABAddressBookRef addressbook = ABAddressBookCreate();
CFArrayRef contacts = ABAddressBookCopyArrayOfAllPeople(addressbook);
I found that companies do not appear to be stored as groups (they are still returned with the above call). Thanks!

You are correct, companies are records/people in the Address Book.
Look up the value for the kABPersonFlags -- one of the flags is "show as company". Then just do a bitmask and compare.
if (([aPerson valueForProperty:kABPersonFlags] & kABShowAsMask) == kABShowAsCompany) {
// it's a company
} else {
// it's a person, resource, or room
}
I used the following references from Apple, which you should probably read as well:
Address Book Programming Guide for Mac OS X
Address Book Constants Reference
ABPerson Class Reference
EDIT: Sorry, the above is for Address Book on Mac OS X. Try this for iOS:
ABRecordRef aRecord = ... // Assume this exists
CFNumberRef recordType = ABRecordCopyValue(aRecord, kABPersonKindProperty);
if (recordType == kABPersonKindOrganization) {
// it's a company
} else {
// it's a person, resource, or room
}
The idea is the same: get the value of the person type property, and see what it tells you.
Used these Apple docs:
Address Book Programming Guide for iOS
ABPerson Reference

Related

How can i get all contacts from particular Group in Addressbook?

Hi I have several Groups in my iPhone addressbook which contains several contacts. For Example:
iPhone addressbook, Group1, Group2 etc.
Each group contains contacts information like First Name,Last name,Email ,Phone number. Now by selecting any group I should get all details of added contacts in it. Can anybody please guide me how can I get all contacts details from particular group?
Please need some guidelines.
CFErrorRef error = NULL;
ABAddressBookRef addrBook = ABAddressBookCreate();
CFArrayRef groups = ABAddressBookCopyArrayOfAllGroups(addrBook);
CFIndex numGroups = CFArrayGetCount(groups);
for(CFIndex idx=0; idx<numGroups; ++idx) {
ABRecordRef groupItem = CFArrayGetValueAtIndex(groups, idx);
CFArrayRef members = ABGroupCopyArrayOfAllMembers(groupRef);
if(members) {
NSUInteger count = CFArrayGetCount(members);
for(NSUInteger idx=0; idx<count; ++idx) {
ABRecordRef person = CFArrayGetValueAtIndex(members, idx);
// your code
}
CFRelease(members);
}
}
CFRelease(groups);
CFRelease(addrBook);
This code is not guaranteed leak-proof so double check it. Its more or less correct.
Everything is explained in the documentation, so please tell use what you don't understand in it. What did you try? What did you get, which errors did you have?
If you want to work with contacts, in addition to the very complete Address Book Programming Guide, you have of course the Address Book Framework Reference and especially the ABGroup Reference Documentation to work with groups. And the latter contains an explicitly a method to get all members of a group. So you should have everything you need here.
CFArrayRef cfmembers = ABGroupCopyArrayOfAllMembers(group);
NSArray* members = (NSArray*)cfmembers; // working with NSArray is usually easier that CFArrays so I like using toll-free bridging
for(ABRecordRef person in members)
{
// ... your code ...
}
CFBridgingRelease(cfmembers); // release memory when done, following the usual memory mgmt rules

How to modify a contact number in address book programmatically?

I am currently writing an app which should enable the user to modify the contact details (mainly numbers) in the app, and then these modifications should be reflected directly to the Address Book.
I searched thoroughly on the internet, but all the examples I found were either to load the contacts or add new contact, but nothing on modifying an existing contact.
also how can I get a list of all phone numbers of a single contact, in case he has several numbers stored.
To allow a user to edit their details directly, see Apple's documentation on displaying and editing a person record. The initial section of that says, "Set the delegate, which must adopt the ABPersonViewControllerDelegate protocol. To allow the user to edit the record, set allowsEditing to YES."
For example:
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.personViewDelegate = self;
personViewController.allowsEditing = YES;
Other than setting allowsEditing, the code would be exactly the same as that required to display a person's details without editing. (This code was drawn from this answer which displays a fuller example regarding deleting a contact from the address book.)
However, I see your title refers to doing so programatically. Apple's Address Book Programing Guide for iOS says, "Remember that the Address Book database is ultimately owned by the user, so applications must be careful not to make unexpected changes to it. Generally, changes should be initiated or confirmed by the user."
However, it is possible. The following example appears on p.17 of that document:
ABRecordRef aRecord = ABPersonCreate();
CFErrorRef anError = NULL;
bool didSet;
didSet = ABRecordSetValue(aRecord, kABPersonFirstNameProperty, CFSTR("Katie"), &anError);
if (!didSet) {/* Handle error here. */}
didSet = ABRecordSetValue(aRecord, kABPersonLastNameProperty, CFSTR("Bell"), &anError);
if (!didSet) {/* Handle error here. */}
CFStringRef firstName, lastName;
firstName = ABRecordCopyValue(aRecord, kABPersonFirstNameProperty);
lastName = ABRecordCopyValue(aRecord, kABPersonLastNameProperty);
/* ... Do something with firstName and lastName. ... */
CFRelease(aRecord);
CFRelease(firstName);
CFRelease(lastName);

iPhone: How do you get the names of all the address books on the iPhone?

Some users have multiple address books in their iPhone Contacts, as a result of different synchronization connections they have made with e.g. Exchange Servers.
How is it possible to get all of these different address books? I would be interested in getting the names under which these different address books are saved and accessing their contact information.
Thank you!
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef sourcesArray = ABAddressBookCopyArrayOfAllSources(addressBook);
for (CFIndex i = 0; i < CFArrayGetCount(sourcesArray); i++) {
ABRecordRef source = (ABRecordRef)CFArrayGetValueAtIndex(sourcesArray, i);
ABRecordID sourceID = ABRecordGetRecordID(source);
CFNumberRef sourceType = (CFNumberRef)ABRecordCopyValue(source, kABSourceTypeProperty);
CFStringRef sourceName = (CFStringRef)ABRecordCopyValue(source, kABSourceNameProperty);
NSLog(#"source id=%d type=%d name=%#", sourceID, [(NSNumber *)sourceType intValue], sourceName);
CFRelease(sourceType);
if (sourceName != NULL) CFRelease(sourceName); // some source names are NULL
}
CFRelease(sourcesArray);
CFRelease(addressBook);
Note that, as of iOS 4, not all sources return a name. You may provide your own names based on type.
Use ABAddressBookCopyArrayOfAllPeopleInSource(addressBook, source) to get entries in a source.
There is only a single, centralized address book database on iOS accessible by a set of C functions, see ABAddressBook and the iOS address book programming guide.
You may be referring to groups within that address book. In that case, you can get the list of groups using the ABAddressBookCopyArrayOfAllGroups function as described in the reference on ABGroup.

Obtaining Specific ABSource from ABAddressBook in iOS 4+

Does anyone have an example of how to obtain a specific ABSource from the ABAddressBook in iOS 4+?
iOS 4+ provides new API that allows one to select a specific ABSource from the ABAddressBook. This may be useful as some operations, e.g. creating an ABGroup, are not supported in some sources (i.e. Exchange).
"Not all source types support groups, more conspicuously, Exchange does not know anything about groups." - http://flavors.me/volonbolon#1a5/tumblr
Attached are functions that leverage the new API to obtain sources of specific types which may be used in calls to ABGroupCreateInSource().
#define CFRELEASE_AND_NIL(x) CFRelease(x); x=nil;
ABRecordRef sourceWithType (ABSourceType mySourceType)
{
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef sources = ABAddressBookCopyArrayOfAllSources(addressBook);
CFIndex sourceCount = CFArrayGetCount(sources);
ABRecordRef resultSource = NULL;
for (CFIndex i = 0 ; i < sourceCount; i++) {
ABRecordRef currentSource = CFArrayGetValueAtIndex(sources, i);
CFTypeRef sourceType = ABRecordCopyValue(currentSource, kABSourceTypeProperty);
BOOL isMatch = mySourceType == [(NSNumber *)sourceType intValue];
CFRELEASE_AND_NIL(sourceType);
if (isMatch) {
resultSource = currentSource;
break;
}
}
CFRELEASE_AND_NIL(addressBook);
CFRELEASE_AND_NIL(sources);
return resultSource;
}
ABRecordRef localSource()
{
return sourceWithType(kABSourceTypeLocal);
}
ABRecordRef exchangeSource()
{
return sourceWithType(kABSourceTypeExchange);
}
ABRecordRef mobileMeSource()
{
return sourceWithType(kABSourceTypeMobileMe);
}
Really wanna know how to create my own source.Just like the group Exchange create with which you dont need to edit the default source record but create own one,and what's most fantastic is,the addressbook will linked them together automatically.
Xyzzycoder-
Your solution works well if there is already a localSource, but just returns NULL if there isn't one.
Is there a way to, say, create an ABRecordRef for a localSource? I need to be able to store my contact to a non-synchronising source.
Cheers
The code has errors, thats why it always returns two, since the method: ABRecordGetRecordType is not a part of the ABSource. It only includes:
kABPersonType for person records
kABGroupType for group records.
kABSourceType for source records.
To figure out the right type you have to use: ABRecordCopyValue(source, kABSourceTypeProperty) instead! :) Works excellent on my iPhone with or without localSource.
Good luck!

How to create string property for each address book record?

I want to store network carrier as a string (e.g. AT&T) for each contact in address book.
I found a method
addPropertiesAndTypes for creating a custom property. But I am not able to find any proper example to do this.
I am using following code to iterate through contact book records:
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef addressArr = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
for(int i=0; i<nPeople; i++) {
ABRecordRef recref = CFArrayGetValueAtIndex(addressArr, i);
}
And my query is, the property will stay with value after app is closed. Are these property is getting saved in address book database?
Help needed.
Thanks.
Make sure you call ABAddressBookSave().