以编程方式请求访问联系人

Kyl*_*egg 109 iphone objective-c contacts ios ios6

自从更新到iOS 6后,我注意到我在iPhone地址簿中添加联系人的代码不再有效.我相信这是一个与权限相关的问题,因为Apple在访问联系人之前现在需要用户权限(修复问题).

我希望应用程序能够自动请求访问联系人的权限,如下面的屏幕截图所示,但事实并非如此.尝试添加联系人失败了ABAddressBookErrorDomain error 1.

我是否需要以编程方式启动对联系人请求对话框的访问?怎么做的?

访问联系人

Kyl*_*egg 180

根据Apple网站上的此文档(在页面中间向下滚动到"隐私"),必须先授予对地址簿的访问权限,然后才能以编程方式进行访问.这就是我最终做的事情.

  #import <AddressBookUI/AddressBookUI.h>

  // Request authorization to Address Book
  ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);

  if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
    ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
      if (granted) {
          // First time access has been granted, add the contact
          [self _addContactToAddressBook];
      } else {
          // User denied access
          // Display an alert telling user the contact could not be added
      }
    });
  }
  else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
    // The user has previously given access, add the contact
    [self _addContactToAddressBook];
  }
  else {
    // The user has previously denied access
    // Send an alert telling user to change privacy setting in settings app
  }
Run Code Online (Sandbox Code Playgroud)

适用于iOS 9及更高版本的更新:

来自Apple网站:

重要

iOS 9中不推荐使用Address Book UI框架.请改用ContactsUI框架中定义的API.有关详细信息,请参阅ContactsUI

  • 编辑:这不是一个错误,它实际上是操作系统的故意... http://stackoverflow.com/questions/12810638/app-crashed-in-ios-6-when-user-changes-contacts-access -permissions (3认同)

yun*_*nas 47

这对我来说是完美的伎俩!

在iOS6上,Apple引入了新的隐私控制,用户可以通过每个应用程序控制联系人和日历的访问.因此,在代码方面,您需要添加一些方法来请求权限.在iOS5或之前,我们总是可以打电话

ABAddressBookRef addressBook = ABAddressBookCreate();
Run Code Online (Sandbox Code Playgroud)

获取地址簿没有任何问题,但在iOS6中,如果你没有权限,这个调用只会返回空指针.这就是我们需要更改方法以获取ABAddressBookRef的原因.

__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) {
    // Do whatever you want here.
}
Run Code Online (Sandbox Code Playgroud)

在代码中,信号量用于阻塞直到响应,而ABAddressBookRequestAccessWithCompletion将请求权限,如果应用程序之前没有询问.否则,它将遵循Settings-Privacy-Contact中的设置.

消息来源:http://programmerjoe.blogspot.com/2012/10/ios6-permissions-contacts.html

  • @Yunas但它停止了所有线程,我的意思是当警报弹出请求用户访问其联系人时,按钮没有响应,我的应用程序挂起,我相信这是因为GCD dispatch_semaphore_wait (2认同)

Zar*_*aki 6

对于联系人框架:

- (void)checkPermissionForCNContacts
{
    switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts])
    {
        case CNAuthorizationStatusNotDetermined:
        {
            [[[CNContactStore alloc] init] requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
                if (granted == YES)
                    [self showCNContactPicker];
            }];
        }
            break;
        case CNAuthorizationStatusRestricted:
        case CNAuthorizationStatusDenied:
                // Show custom alert
            break;
        case CNAuthorizationStatusAuthorized:
            [self showCNContactPicker];
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)