ABAddressBookRequestAccessWithCompletion iOS 7 et sémaphores

Ce code a été posté avant, et a été utilisé ainsi, de ce que j'ai pu rassembler. Je suis dans une situation où j'ai besoin du code pour ne PAS continuer jusqu'à ce que je sache si j'ai access aux contacts.

sur Xcode 5.0.2 et iOS 6, cela fonctionne très bien. sur iOS 7, il se bloque pour toujours, puis quand je tue l'application, la boîte de dialog apparaît demandant de permettre l'access aux contacts.

ABAddressBookRef addressBook = ABAddressBookCreate(); __block BOOL accessGranted = NO; if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 dispatch_semaphore_t sema = dispatch_semaphore_create(0); ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { accessGranted = granted; dispatch_semaphore_signal(sema); }); dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); } else { // we're on iOS 5 or older accessGranted = YES; } 

En essayant de jouer avec ça, je mets simplement un BOOL à NON, puis je le mets à OUI dans le bloc. après le bloc, j'ai mis une boucle while qui vérifiait que la variable était YES, puis j'ai dormi pendant 1 seconde. fonctionne parfaitement bien sur 6, sur 7 je n'atteins jamais la déclaration NSLog dans le bloc, et je suis coincé pour toujours dans la boucle d'printing de l'instruction de journal.

Est-ce que je fais quelque chose de vraiment boiteux ici? ou est-ce que cette méthode est devenue détraquée sur 7?

 ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { if (granted) { self.myAddressBook = addressBook; } done = YES; NSLog(@"in block, done is %@", done ? @"YES" : @"NO"); didGrant = granted; //dispatch_semaphore_signal(sema); }); while (!done) { NSLog(@"done is %@", done ? @"YES" : @"NO"); sleep(1); } 

J'ai eu le même problème, et j'ai réalisé que la boîte de dialog qui request l'access aux contacts bloque l'application de toute façon, alors peut-être qu'il y a une impasse. J'ai donc abandonné les sémaphores et fait quelque chose comme ça (testé et fonctionne sur iOS 7.1.1):

 ABAddressBookRef addressBook = ABAddressBookCreate(); MyController * __weak weakSelf = self; if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) { ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf accessGrantedForAddressBook]; }); }); } else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized); //Maybe add something here to handle kABAuthorizationStatusRessortingcted [self accessGrantedForAddressBook]; } } else // we're on iOS 5 or older [self accessGrantedForAddressBook]; 

ce qui est assez similaire à ce que fait Apple dans leur documentation (searchz ABAddressBookRequestAccessWithCompletion). En outre, quel est le sharepoint ABAddressBookRequestAccessWithCompletion étant asynchronous et l'attente (voir ici ) ..