2

I've a device phone run ios 6.0.1, and i want get all contact in my device. I tried on iphone use to IOS 5.1, 6.1.3 and it's work ok. Unfortunately, when it's run ios 6.0.1, data is null

This is my code:

if ([[[UIDevice currentDevice] systemVersion] floatValue] > 5.2) {

    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
    {
        ABAddressBookRequestAccessWithCompletion(addressBookRef,
                                                 ^(bool granted, CFErrorRef error) {
                                                     if (granted)
                                                         [self loadContact];

                                                 });
    }
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
    {
        [self loadContact];
    }
}
else
{
    [self loadContact];
}

-(void) loadContact {

ABAddressBookRef addressBooks = ABAddressBookCreate();
allPeople = (__bridge NSArray *)(ABAddressBookCopyArrayOfAllPeople(addressBooks));
peopleCount = ABAddressBookGetPersonCount(addressBooks); }

I don't know, why it doesn't work on ios 6.0.1

I found this link, and do it, but my device have not data.

Can you help me this problem?

Community
  • 1
  • 1
BlueSky
  • 139
  • 3
  • 9

1 Answers1

0

The biggest problem in your code is that you need to pass reference "addressBookRef" to your "loadContact" method. "ABAddressBookCreate" won't work for iOS6 - you need to use the one created by ABAddressBookRequestAccessWithCompletion.

Btw. Instead of checking for iOS version better use that to determinate if you need to ask for permissions. Here is a code I'm using - feel free to use it:

-(BOOL)isABAddressBookCreateWithOptionsAvailable {
    return &ABAddressBookCreateWithOptions != NULL;
}

- (void) importContactsFromAddressBook
{
    ABAddressBookRef addressBook;
    if ([self isABAddressBookCreateWithOptionsAvailable]) {
        CFErrorRef error = nil;
        addressBook = ABAddressBookCreateWithOptions(NULL,&error);
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            // callback can occur in background, address book must be accessed on thread it was created on
                if (error) {
                    [self.delegate addressBookHelperError:self];
                } else if (!granted) {
                    [self.delegate addressBookHelperDeniedAcess:self];
                    AddressBookUpdated(addressBook, nil, self);
                } else {
                    // access granted
                    AddressBookUpdated(addressBook, nil, self);
                    CFRelease(addressBook);
                }
        });
    } else {
        // iOS 4/5
        addressBook = ABAddressBookCreate();
        AddressBookUpdated(addressBook, NULL, self);
        CFRelease(addressBook);
    }
}

void AddressBookUpdated(ABAddressBookRef addressBook, CFDictionaryRef info, void *context)
{
    NSMutableArray* addressBookContacts = [NSMutableArray array];

    //import from address book
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
    CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
    [helper.delegate performSelectorOnMainThread:@selector(didLoadList:)
                                    withObject:[NSNumber numberWithInt:nPeople]
                                 waitUntilDone:YES];
    if(allPeople) CFRelease(allPeople);
    [helper.delegate performSelectorOnMainThread:@selector(didComplete:)
                                    withObject:addressBookContacts
                                 waitUntilDone:YES];
}

I have those functions encapsulated into class and delegate is:

@protocol ContactImporterProgressViewDelegate <NSObject>
- (void) didLoadList:(NSNumber*) totalItems;
- (void) updateProgress:(NSNumber*) progress;
- (void) didComplete:(NSArray*) contactsImported;
@end

@property (nonatomic, assign) NSObject <ContactImporterProgressViewDelegate>* delegate;

To use it I would suggest to call it on another thread to don't block UI and show progress (it takes a while when you have 5000 entries):

ContactImporter* importer = [[ContactImporter alloc] init];
importer.delegate = self;
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
NSInvocationOperation *oper = [[[NSInvocationOperation alloc] initWithTarget:importer
                                                                   selector:@selector(importContactsFromAddressBook)
                                                                     object:nil] autorelease];
[queue addOperation:oper];
[importer release];
Grzegorz Krukowski
  • 18,081
  • 5
  • 50
  • 71