Question

In my iPad app (Xcode 5, iOS 7, ARC, Storyboards), I'm trying to read the Address book and get all of the entries. Unfortunately, I get the following error:

SalonBook[2225:a0b] -[__NSCFString count]: unrecognized selector sent to instance 0xb335e70

This is my code that I copied from SO (why re-invent the wheel?).

-(IBAction)importClientData:(UIButton *)sender {

NSMutableArray *allContacts = [[NSMutableArray alloc] init];
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
CFArrayRef people  = ABAddressBookCopyArrayOfAllPeople(addressBook);
for(int i = 0;i<ABAddressBookGetPersonCount(addressBook);i++)
{
    NSMutableDictionary *aPersonDict = [[NSMutableDictionary alloc] init];
    ABRecordRef ref = CFArrayGetValueAtIndex(people, i);
    NSString *fullName = (__bridge NSString *) ABRecordCopyCompositeName(ref);
    if (fullName) {
        [aPersonDict setObject:fullName forKey:@"fullName"];

        // collect phone numbers
        NSMutableArray *phoneNumbers = [[NSMutableArray alloc] init];
        ABMultiValueRef phones = ABRecordCopyValue(ref, kABPersonPhoneProperty);
        for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++) {
            NSString *phoneNumber = (__bridge NSString *) ABMultiValueCopyValueAtIndex(phones, j);
            [phoneNumbers addObject:phoneNumber];
        }
        [aPersonDict setObject:phoneNumbers forKey:@"phoneNumbers"];

        // collect emails - key "emails" will contain an array of email addresses
        ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);
        NSMutableArray *emailAddresses = [[NSMutableArray alloc] init];
        for(CFIndex idx = 0; idx < ABMultiValueGetCount(emails); idx++) {
            NSString *email = (__bridge NSString *)ABMultiValueCopyValueAtIndex(emails, idx);
            [emailAddresses addObject:email];
        }
        [aPersonDict setObject:emailAddresses forKey:@"emails"];
        // if you want to collect any other info that's stored in the address book, it follows the same pattern.
        // you just need the right kABPerson.... property.

        [allContacts addObject:aPersonDict];
    }
    else {
        // Note: I have a few entries in my phone that don't have a name set
        // Example one could have just an email address in their address book.
    }
}

}

UPDATE: Here is the complete stack trace:

0 CoreFoundation 0x2e335f53 + 130
1 libobjc.A.dylib 0x3899e6af objc_exception_throw + 38
2 CoreFoundation 0x2e3398e7 + 202
3 CoreFoundation 0x2e3381d3 + 706
4 CoreFoundation 0x2e287598 _CF_forwarding_prep_0 + 24
5 AddressBook 0x2d9274fd ABCCopyUserLanguage + 60
6 AddressBook 0x2d914e3d ABCIsSortDataValid + 28
7 AddressBook 0x2d914d6d ABCCreateAddressBookWithDatabaseDirectoryAndForceInProcessMigrationInProcessLinkingAndResetSortKeys + 1120
8 AddressBook 0x2d928d17 ABAddressBookCreateWithDatabaseDirectory + 74
9 AddressBook 0x2d928e67 ABAddressBookCreateWithOptionsAndPolicy + 146
10 AddressBook 0x2d9290c9 ABAddressBookCreateWithOptions + 88
11 SalonBook 0x000e35db -[CustomerSetupController importClientData:] + 118
12 UIKit 0x30adbf3f + 90
13 UIKit 0x30adbedf + 30
14 UIKit 0x30adbeb9 + 44
15 UIKit 0x30ac7b3f + 374
16 UIKit 0x30adb92f + 590
17 UIKit 0x30adb601 + 528
18 UIKit 0x30ad668d + 832
19 UIKit 0x30aaba25 + 196
20 UIKit 0x30aaa221 + 7096
21 CoreFoundation 0x2e30118b + 14
22 CoreFoundation 0x2e30065b + 206
23 CoreFoundation 0x2e2fee4f + 622
24 CoreFoundation 0x2e269ce7 CFRunLoopRunSpecific + 522
25 CoreFoundation 0x2e269acb CFRunLoopRunInMode + 106
26 GraphicsServices 0x32f37283 GSEventRunModal + 138
27 UIKit 0x30b0ba41 UIApplicationMain + 1136
28 SalonBook 0x000b6335 main + 116
29 libdyld.dylib 0x38ea6ab7 + 2

No matter what code I use (I have tried several variations of the above code) they all crash on the same call (-ABAddressBookCreateWithOptions). Since I copied the same code from multiple examples, I would expect at least this line to work. It's not! Why?

Was it helpful?

Solution

It is not clear whether or not you are calling ABAddressBookRequestWithCompletion to obtain the user's permission to access the address book. If you don't do this on an app targeting iOS 6 or newer, you will not be allowed to access the address book. That being said, AddressBook API should not crash in this way. You may need to report a bug to apple via bugreport.apple.com.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top