Saurabh Mishra
Saurabh Mishra

Reputation: 881

Contacts are not fetching first time

I am using below code for fetching contact in iOS 7.1

 CFErrorRef *error=nil;
    ABAddressBookRef addressbook=ABAddressBookCreateWithOptions(NULL, error);
    CFArrayRef allpeople=ABAddressBookCopyArrayOfAllPeople(addressbook);
    CFIndex npeople=ABAddressBookGetPersonCount( addressbook );


    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);

    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
            if (granted) {


                 NSLog(@"access granteddsddsdd");
                for ( int i = 0; i < npeople; i++ )
                {
                    NSLog(@"access granted");
                    ABRecordRef ref = CFArrayGetValueAtIndex( allpeople, i );
                    NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(ref, kABPersonFirstNameProperty));
                    NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(ref, kABPersonLastNameProperty));
                    NSLog(@"Name:%@ %@", firstName, lastName);    }


                // First time access has been granted, add the contact
            } else {
                // User denied access
                // Display an alert telling user the contact could not be added
            }
        });
    }
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        NSLog(@"access granted1");

        for ( int i = 0; i < npeople; i++ )
        {
            ABRecordRef ref = CFArrayGetValueAtIndex( allpeople, i );
            NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(ref, kABPersonFirstNameProperty));
            NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(ref, kABPersonLastNameProperty));
            NSLog(@"Name:%@ %@", firstName, lastName);    }


        // The user has previously given access, add the contact
    }
    else {

        NSLog(@"access granted2");
        for ( int i = 0; i < npeople; i++ )
        {
            ABRecordRef ref = CFArrayGetValueAtIndex( allpeople, i );
            NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(ref, kABPersonFirstNameProperty));
            NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(ref, kABPersonLastNameProperty));
            NSLog(@"Name:%@ %@", firstName, lastName);    }


        // The user has previously denied access
        // Send an alert telling user to change privacy setting in settings app
    }

While I run this code in my device , 1st time it ask for permission after click on "OK" on permission popup it doesn't print any name while if i close the app & again reopen it surprisingly it show all the name So can any one tell me what is the problem in 1st time & how it can be fixed

Upvotes: 1

Views: 314

Answers (1)

I got your problem. Actually it checks for the permission & at the same time it try to fetch the result.

Here is the brief solution:

Create class:

VSContacts.h

#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>

@interface VSContacts : NSObject
-(BOOL)canGetContacts;
-(NSArray *)getContacts;
-(ABAddressBookRef)addressBookRef;
@property (nonatomic) ABAddressBookRef addressBook;
@end

VSContacts.m

#import "VSContacts.h"

@implementation VSContacts
@synthesize addressBook = _addressBook;

-(BOOL)canGetContacts
{
    self.addressBook = [self addressBookRef];
    if (self.addressBook != NULL || self.addressBook != nil) {
        return YES;
    }

    return NO;
}

#pragma mark - Get AddressBook
-(ABAddressBookRef)addressBookRef
{
    ABAddressBookRef aBook = NULL;
    if(ABAddressBookCreateWithOptions)
    {
        CFErrorRef error;
        aBook = ABAddressBookCreateWithOptions(NULL, &error);

        __block BOOL accessGranted = NO;
        if (ABAddressBookRequestAccessWithCompletion != NULL) {
            // we're on iOS 6
            dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            ABAddressBookRequestAccessWithCompletion(aBook, ^(bool granted, CFErrorRef error) {
                accessGranted = granted;
                dispatch_semaphore_signal(sema);

                dispatch_async(dispatch_get_main_queue(), ^{
                    if(granted && !error)
                    {
                        ABAddressBookRevert(aBook);
                    }
                });
            });
            dispatch_semaphore_wait(sema, DISPATCH_TIME_NOW);
            dispatch_release(sema);
        }
        else
        {
            // we're on iOS 5 or older
            accessGranted = YES;
            aBook = ABAddressBookCreate();
        }
    }
    else
    {
        aBook = ABAddressBookCreate();
    }

    return aBook ;
}

-(NSArray *)getContacts
{
    __block NSArray *contacts = nil;
    ABAddressBookRef addressBook = self.addressBook;
    if(addressBook != NULL || addressBook != nil)
    {
        CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
        contacts = (__bridge NSArray *)people;
    }
    return contacts;
}
@end

Now:

  • In your Appdelagate.h file: #import "VSContacts.h"
  • Than declare VSContacts *contactsHandler;
  • Give property & synthesize it

Than:

In Appdelagate.m file:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   if ([contactsHandler canGetContacts])
    {
        NSLog(@"Access Granted");
    }
    else
    {
        NSLog(@"Access Not Granted");
    }
}

Once above is done than in the page where you fetching the contacts put the following line:

[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(doFetchContacts) userInfo:nil repeats:NO];

-(void)doFetchContacts
{
    CFErrorRef *error=nil;
    ABAddressBookRef addressbook=ABAddressBookCreateWithOptions(NULL, error);
    CFArrayRef allpeople=ABAddressBookCopyArrayOfAllPeople(addressbook);
    CFIndex npeople=ABAddressBookGetPersonCount( addressbook );

    for ( int i = 0; i < npeople; i++ )
    {
        ABRecordRef ref = CFArrayGetValueAtIndex( allpeople, i );
        NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(ref, kABPersonFirstNameProperty));
        NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(ref, kABPersonLastNameProperty));
        NSLog(@"Name:%@ %@", firstName, lastName);
    }
}

Hope this will help.

Enjoyyy :)

Upvotes: 1

Related Questions