ABAddressBookRequestAccessWithCompletion iOS 7 y semáforos

este código se ha publicado antes, y también se ha utilizado, de lo que podría recostackr. Estoy en una situación en la que necesito el código para NO continuar hasta que sepa si tengo acceso a los contactos.

en Xcode 5.0.2 y iOS 6, esto funciona bien. en iOS 7, cuelga para siempre, y luego, cuando mato la aplicación, aparece el cuadro de dialog pidiéndome que permita el acceso a los contactos.

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; } 

Al intentar jugar con esto, entonces simplemente establezco un BOOL para que sea NO, y luego lo establezco en YES dentro del bloque. Después del locking, puse un ciclo while que verificó que la variable sea SÍ y luego dormí durante 1 segundo. funciona perfectamente bien en 6, en 7 nunca alcanzo la instrucción NSLog en el bloque, y estoy atrapado para siempre en el bucle while imprimiendo la instrucción log.

¿Estoy haciendo algo realmente cojo aquí? ¿O es que este método se descontrola en 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); } 

Tuve el mismo problema, y ​​me di count de que el cuadro de dialog que solicita acceso a los contactos bloquea la aplicación de todos modos, así que tal vez hay un punto muerto. Entonces, simplemente abandoné los semáforos e hice algo como esto (probado y funciona en 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 kABAuthorizationStatusRestricted [self accessGrantedForAddressBook]; } } else // we're on iOS 5 or older [self accessGrantedForAddressBook]; 

que es bastante similar a lo que Apple hace en su documentation (busque ABAddressBookRequestAccessWithCompletion). Además, ¿cuál es el punto de ABAddressBookRequestAccessWithCompletion que es asynchronous y lo espera (ver aquí ) …