teclado tamaño cambiar aumentar iphone objective-c ios cocoa-touch abaddressbook

iphone - tamaño - ¿Cómo uso correctamente el método ABAddressBookCreateWithOptions en iOS 6?



cambiar teclado iphone 6 (4)

Estoy intentando comprender los métodos ABAdressBookCreateWithOptions y ABAddressBookRequestAccessWithCompletion en iOS 6.

La mayor cantidad de información que he podido encontrar es la siguiente: "Para solicitar acceso a los datos de contacto, llame a la función ABAddressBookRequestAccessWithCompletion después de llamar a la función ABAddressBookCreateWithOptions ".

Creo que estos métodos juntos deberían alertar al usuario para decidir si permite que la aplicación acceda a los contactos, sin embargo, cuando los utilizo no veo ningún mensaje.

¿Podría alguien proporcionar un ejemplo de código de cómo estos métodos deberían reunirse en un ejemplo del mundo real? ¿Cómo creo opciones ( CFDictionary )? Tengo código de trabajo usando el método ABAddressBookCreate desuso, pero necesito actualizar a iOS 6 para dar cabida a las preocupaciones de privacidad.

Gracias de antemano a cualquiera que pueda arrojar algo de luz aquí!


Ahora que se ha eliminado la NDA, aquí está mi solución para esto donde necesitas reemplazar un método que devuelve una matriz. (Si prefiere no bloquear mientras el usuario está decidiendo y está listo para reescribir potencialmente parte de su código existente, consulte la solución de David a continuación):

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); dispatch_release(sema); } else { // we''re on iOS 5 or older accessGranted = YES; } if (accessGranted) { NSArray *thePeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook); // Do whatever you need with thePeople... }

Espero que esto ayude a alguien ...


Esto está relacionado periféricamente con la pregunta original, pero no la he visto mencionar en ningún otro lado, y me tomó alrededor de dos días encontrarla. Si registra una devolución de llamada para los cambios en la libreta de direcciones, DEBE estar en el hilo principal.

Por ejemplo, en este código, solo se llamará a sync_address_book_two ():

ABAddressBookRequestAccessWithCompletion(_addressBook, ^(bool granted, CFErrorRef error) { if (granted) { ABAddressBookRegisterExternalChangeCallback (_addressBook, sync_address_book_one, NULL); dispatch_async(dispatch_get_main_queue(), ^{ ABAddressBookRegisterExternalChangeCallback (_addressBook, sync_address_book_two, NULL); }); } });


La mayoría de las respuestas que he visto a esta pregunta hacen cosas locas complicadas con GCD y terminan bloqueando el hilo principal . ¡No es necesario!

Esta es la solución que he estado usando (funciona en iOS 5 e iOS 6):

- (void)fetchContacts:(void (^)(NSArray *contacts))success failure:(void (^)(NSError *error))failure { if (ABAddressBookRequestAccessWithCompletion) { // on iOS 6 CFErrorRef err; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &err); if (err) { // handle error CFRelease(err); return; } ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { // ABAddressBook doesn''t gaurantee execution of this block on main thread, but we want our callbacks to be dispatch_async(dispatch_get_main_queue(), ^{ if (!granted) { failure((__bridge NSError *)error); } else { readAddressBookContacts(addressBook, success); } CFRelease(addressBook); }); }); } else { // on iOS < 6 ABAddressBookRef addressBook = ABAddressBookCreate(); readAddressBookContacts(addressBook, success); CFRelease(addressBook); } } static void readAddressBookContacts(ABAddressBookRef addressBook, void (^completion)(NSArray *contacts)) { // do stuff with addressBook NSArray *contacts = @[]; completion(contacts); }


La otra respuesta de alto rango tiene problemas:

  • Incondicionalmente llama a API que no existe en iOS anterior a 6, por lo que su programa se bloqueará en dispositivos antiguos.
  • bloquea el hilo principal, por lo que su aplicación no responde y no progresa durante el tiempo en que se activa la alerta del sistema.

Aquí está mi MRC asumirlo:

ABAddressBookRef ab = NULL; // ABAddressBookCreateWithOptions is iOS 6 and up. if (&ABAddressBookCreateWithOptions) { NSError *error = nil; ab = ABAddressBookCreateWithOptions(NULL, (CFErrorRef *)&error); #if DEBUG if (error) { NSLog(@"%@", error); } #endif if (error) { CFRelease((CFErrorRef *) error); error = nil; } } if (ab == NULL) { ab = ABAddressBookCreate(); } if (ab) { // ABAddressBookRequestAccessWithCompletion is iOS 6 and up. if (&ABAddressBookRequestAccessWithCompletion) { ABAddressBookRequestAccessWithCompletion(ab, ^(bool granted, CFErrorRef error) { if (granted) { // constructInThread: will CFRelease ab. [NSThread detachNewThreadSelector:@selector(constructInThread:) toTarget:self withObject:ab]; } else { CFRelease(ab); // Ignore the error } // CFErrorRef should be owned by caller, so don''t Release it. }); } else { // constructInThread: will CFRelease ab. [NSThread detachNewThreadSelector:@selector(constructInThread:) toTarget:self withObject:ab]; } } }