Obtaining Specific ABSource from ABAddressBook in iOS 4+
Asked Answered
S

4

3

Does anyone have an example of how to obtain a specific ABSource from the ABAddressBook in iOS 4+?

Stannite answered 13/1, 2011 at 11:41 Comment(0)
S
9

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);
}
Stannite answered 13/1, 2011 at 11:45 Comment(3)
Readers, be aware that not all devices will have a local source (see comments below), so you will need to be able to handle cases where the requested source does not exist. It also does not appear to be possible to programmatically create a local source.Stannite
what about releasing the copied values? Is this unnecessary for some reason I don't see?Fireback
Martin - Good catch. The leaks should be fixed now.Stannite
C
2

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.

Chubb answered 26/1, 2011 at 16:46 Comment(2)
Jackie, are you saying that you know how to create a local source?Stannite
I wish.Actually I found a private API that can create my own source which is ABSourceCreate();.It doesnt crash and return ABRecordRef which is printed as "ABStore" type in Log.I believe that is the ABSource type that i want.So I set the kABSourceNameProperty,kABSourceTypeProperty and use ABAddressAddRecord() to add it to addressBook.But it is still failed finally like i had missed something in process.Maybe Apple will release some more detail in next update,who knows : )Chubb
B
1

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

Barb answered 13/1, 2011 at 14:3 Comment(3)
Peter, under what circumstances would there not be a local source?Stannite
Hi. For example there is no local address book (typically "all on my iphone", "all on my PC" or "all on my Mac" listed on the Groups page on the Contacts app) if you synchronize all your contacts with Google over Exchange, neither can you get a handle to it using the method you suggested. From my testing you can only get a handle on a local addressbook if the user also has some contacts stored on his device that dont sync to Exchange (if he entered them before he had Exchange set up, for instance, and opted not to merge). CheersBarb
Peter, that's interesting. I guess that I had (apparently wrongly) assumed that a local address book would always exist on the device. It also does not seem like there is a facility for programmatically creating the local source if it does not already exist?Stannite
C
1

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!

Chery answered 6/2, 2011 at 16:47 Comment(5)
@Chery - can you patch the code to incorporate what you're suggesting? Or are you saying that the approach just will not work if the local source does not already exist?Stannite
I'm saying that this approach will not work if the local source does not already exist. Currently waiting on a answer from Apple on this issue!Chery
@Stannite got an answer from Apple today and it was as I thought. "It is not possible to create a source, or perform any operations on a source the user is not using." I have filed a bug on -> developer.apple.com/bugreporterChery
@Chery - Thank you. I would still like to patch the code example so that it works, to the degree that it can.Stannite
@Chery - I believe that I have incorporated the patch that you suggested. Thank you.Stannite

© 2022 - 2024 — McMap. All rights reserved.