0

I am trying to implement a contact app.

In the MyContactsViewController, I am trying to get access to Contacts and if the access is granted I will fetch the contacts from my address book. The ContactHandler is my model class(singleton) which has the method called getAllContacts to get the contacts in a NSMutableArray.

- (void)viewDidLoad {
    [super viewDidLoad];
    contactHandler = [ContactHandler sharedInstance];
    if(!self.accessGranted){
        NSOperationQueue *queue =[[ NSOperationQueue alloc]init];
        [queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:self waitUntilDone:YES];
        contactList = [contactHandler getAllContacts];
    }
    else{
        contactList = [contactHandler getAllContacts];
    }

}

-(BOOL)getAccessToAddressBook{

    CNContactStore * contactStore = [[CNContactStore alloc] init];

    if( [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusNotDetermined){

        [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if(granted){
                self.accessGranted = YES;
            }
            else{
                self.accessGranted = NO;
            }
        }];
    }
    else if( [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]== CNAuthorizationStatusAuthorized){
        self.accessGranted = YES;
    }
    else{
        self.accessGranted = NO;
    }
    return self.accessGranted;
}

But I am getting this error -

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSOperationQueue getAccessToAddressBook]: unrecognized selector sent to instance 0x137630700'

Can anyone please help.

Natasha
  • 6,651
  • 3
  • 36
  • 58
  • `[queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:self waitUntilDone:YES];` What do you want to do exactly? That's the line causing the issue. – Larme Feb 05 '16 at 10:58
  • By pressing cmd+click, does it go to the method ? Also try to waitUntilDone:NO – Hima Feb 05 '16 at 11:00
  • I am trying to get the permission before I go to fetch the contacts. Basically I want to call the getAllContacts method after I get response from the getAccessToAddressBook method. – Natasha Feb 05 '16 at 11:12

2 Answers2

1

Your problem is this line:

[queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:self waitUntilDone:YES];

You're asking queue to perform getAccessToAddressBook when is self who has this selector

If you want to run the method getAccessToAddressBook on the queue, you can use - addOperationWithBlock:

Leonardo
  • 1,740
  • 18
  • 27
0

As in this line: performSelectorOnMainThread you are passing withObject:self, where as in method definition i.e (BOOL)getAccessToAddressBookyou are not using it, which is causing the crash, so make withObject:nil , if you don't want to pass any object or value to the method.

Change this line:-

 [queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:self waitUntilDone:YES];

to this:-

 [queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:nil waitUntilDone:YES];

Or the better approach will be to write like this:-

   NSOperationQueue *opQueue=[NSOperationQueue new];
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(getAccessToAddressBook) object:nil];
 [opQueue addOperation:op ];
Vizllx
  • 9,135
  • 1
  • 41
  • 79