【问题标题】:The application can not access the phone book应用程序无法访问电话簿
【发布时间】:2016-08-21 19:30:39
【问题描述】:

我苦苦挣扎了好几天,试图访问电话簿的姓名和号码,但都失败了。我使用以下代码,它在测试应用程序中成功运行,但是当我将它添加到您的项目工作中时,它不起作用。变量“granted”不断有一个值 - “false”,我收到错误“访问失败”。尽管如此,在隐私设置中不显示滑块以允许访问... 我早就找不到一个相当奇怪的行为的答案......

如果有任何帮助,我将不胜感激!`

CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
    if (granted == YES) {

        NSMutableArray *contacts = [NSMutableArray array];

        NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
        NSString *containerId = store.defaultContainerIdentifier;
        NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
        NSError *error;
        NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
        if (error) {
            NSLog(@"error fetching contacts %@", error);
        } else {
            for (CNContact *contact in cnContacts) {

                TSContact *newContact = [[TSContact alloc] init];
                newContact.firstName = contact.givenName;
                newContact.lastName = contact.familyName;
                UIImage *image = [UIImage imageWithData:contact.imageData];
                newContact.image = image;
                for (CNLabeledValue *label in contact.phoneNumbers) {
                    NSString *phone = [label.value stringValue];
                    if ([phone length] > 0) {
                        [contacts addObject:phone];
                    }
                }
            }
        }
    } else {
        NSLog(@"Error = %@", error.localizedDescription);
    }
}];

【问题讨论】:

  • 你的应用的部署目标是什么(目标iOS 6.0版本)?
  • 您是否在 info.plist 中添加了 Privacy - Contacts Usage Description 密钥?它在 iOS 6.0 及更高版本中受支持。
  • 我试过 iOS ios 8 和 9 还是不行
  • 我在 info.plist 中只添加了“隐私 - 联系人使用说明”,但您的隐私设置中没有出现访问开关

标签: ios objective-c cncontactstore


【解决方案1】:

如果您想访问地址簿中现有联系人的信息,以下代码可能会对您有所帮助:)

第一步:添加

#import <AddressBook/AddressBook.h>

第 2 步: 从 viewDidLoad 调用以下方法

-(void)phonenumber
{
    self.navigationController.navigationBarHidden = true;
    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();

    if (status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted) {
        // if you got here, user had previously denied/revoked permission for your
        // app to access the contacts, and all you can do is handle this gracefully,
        // perhaps telling the user that they have to go to settings to grant access
        // to contacts

        [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
        return;
    }

    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

    if (!addressBook) {
        NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error));
        return;
    }

    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
        if (error) {
            NSLog(@"ABAddressBookRequestAccessWithCompletion error: %@", CFBridgingRelease(error));
        }

        if (granted) {
            // if they gave you permission, then just carry on
            [self listPeopleInAddressBook:addressBook];
        } else {
            // however, if they didn't give you permission, handle it gracefully, for example...
            dispatch_async(dispatch_get_main_queue(), ^{
                // BTW, this is not on the main thread, so dispatch UI updates back to the main queue
                [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
            });
        }
        CFRelease(addressBook);
    });
    // Do any additional setup after loading the view.
}

第 3 步:将此方法也添加到您的代码中 此方法为您提供特定联系人所需的所有信息。

- (void)listPeopleInAddressBook:(ABAddressBookRef)addressBook
{
            //Run UI Updates
            NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
            NSInteger numberOfPeople = [allPeople count];

            for (NSInteger i = 0; i < numberOfPeople; i++) {
                ABRecordRef person = (__bridge ABRecordRef)allPeople[i];
                //From Below code you can get what you want.
                NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
                NSString *lastName  = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
                NSLog(@"Name:%@ %@", firstName, lastName);

                ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
                NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumbers, 0));
                NSLog(@"phone:%@", phoneNumber);
                NSLog(@"=============================================");
            }

}

【讨论】:

  • 我在我的应用程序中添加了您的代码,不幸的是,每次应用程序启动时都会显示访问警报。在访问联系人的设置中转换时,滑块不显示:(
  • 你从我的代码中得到了你想要的吗?我没有得到你所面临的确切问题? @СашаЦвигун
  • 不,我没有收到您的代码的联系。我的应用程序无权访问它们。隐私设置,没有允许访问的开关...
  • 不,没有错误不给xcode。我通过断点,停在几个地方,但没有错误。我去了导致警报的块dispatch_async(dispatch_get_main_queue()和所有。在隐私设置中允许访问联系人的开关没有出现......很奇怪
  • 您确定要使用此功能从“设置”访问联系人吗?设置>常规>限制>隐私并允许更改。
猜你喜欢
  • 1970-01-01
  • 2014-02-09
  • 2011-05-23
  • 1970-01-01
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多