自从更新到iOS 6后,我注意到我在iPhone地址簿中添加联系人的代码不再有效。我认为这是一个与权限相关的问题,因为Apple在访问联系人之前现在需要用户权限(修复this问题)。
我希望该应用能够自动请求访问联系人的权限,如下面的屏幕截图所示,但事实并非如此。尝试添加联系人时失败ABAddressBookErrorDomain error 1
。
我是否需要以编程方式启动对联系人请求对话框的访问?怎么做的?
答案 0 :(得分:180)
根据Apple网站上的this documentation(向下滚动到页面中间的隐私),在以编程方式访问之前,必须先获得对地址簿的访问。这就是我最终要做的事情。
#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
}
更新适用于iOS 9及更高版本:
来自Apple网站:
重要
在iOS 9中不推荐使用地址簿UI框架。请改用ContactsUI框架中定义的API。要了解详情,请参阅ContactsUI
答案 1 :(得分:47)
这对我来说是完美的伎俩!
在iOS6上,Apple引入了新的隐私控制,用户可以通过每个应用程序控制联系人和日历的访问权限。因此,在代码方面,您需要添加一些方法来请求权限。在iOS5或之前,我们总是可以调用
ABAddressBookRef addressBook = ABAddressBookCreate();
获取地址簿没有任何问题,但在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.
}
在代码中,信号量用于阻塞直到响应,而ABAddressBookRequestAccessWithCompletion将在应用程序之前没有询问时请求权限。否则,它只会按照设置 - 隐私 - 联系方式中的设置进行操作。
消息来源:http://programmerjoe.blogspot.com/2012/10/ios6-permissions-contacts.html
答案 2 :(得分: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;
}
}
答案 3 :(得分:3)
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) {
if(self.isContactsChanged)
{
{
self.isContactsChanged=NO;
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
ABAddressBookRegisterExternalChangeCallback(addressBook, addressBookChanged, self);
int allPeopleCount = CFArrayGetCount(allPeople);
NSMutableArray *contactArrTemp = [[NSMutableArray alloc]init];
__block int noNumberCount=1;
managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
newMoc = [[NSManagedObjectContext alloc] init];
[newMoc setPersistentStoreCoordinator:[[AppDelegate getAppDelegate] persistentStoreCoordinator]];
[self DeleteAllPhoneContact];
NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
[notify addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:newMoc];
self.backgroundQueue = dispatch_queue_create("com.storephonecontacts.bgqueue", NULL);
__block NSMutableDictionary *dic;
__block NSString *strTime,*strName,*strMobile,*strEmail,*strNotes;
__block NSDate *nsDate;
dispatch_async(self.backgroundQueue, ^{
NSMutableDictionary *dict =nil;
for (int i = 0; i < allPeopleCount; i++)
{
dic = [[NSMutableDictionary alloc]init];
ABRecordRef record = CFArrayGetValueAtIndex(allPeople,i);
NSDate *date = (NSDate*)ABRecordCopyValue(record, kABPersonCreationDateProperty);
nsDate = [date retain];
NSDateFormatter *formatterTime = [[NSDateFormatter alloc] init];
[formatterTime setDateFormat:@"hh.mm"];
NSString *dateStrPhone = [formatterTime stringFromDate:date];
strTime = [dateStrPhone retain];
[formatterTime release];
NSString *name = (NSString*)ABRecordCopyValue(record, kABPersonFirstNameProperty);
if([name length]>0)
name = [name stringByAppendingString:@" "];
NSString *name1 = (NSString*)ABRecordCopyValue(record, kABPersonLastNameProperty);
if([name1 length]>0)
{
if([name length]>0)
name = [name stringByAppendingString:name1];
else
name = (NSString*)ABRecordCopyValue(record, kABPersonLastNameProperty);
}
if([name length]>0)
strName = [name retain];
else
strName = [@"noName" retain];
//to save notes
NSString *notes = (NSString*)ABRecordCopyValue(record, kABPersonNoteProperty);
if(notes == NULL){
strNotes = @"noNotes";
}
else{
strNotes = [notes retain];
}
//for image
if (!ABPersonHasImageData(record)){
}
else{
CFDataRef imageData = ABPersonCopyImageData(record);
UIImage *image = [UIImage imageWithData:(NSData *) imageData];
[dic setObject:image forKey:@"image"];
CFRelease(imageData);
}
//To set Mobile
NSMutableArray* mobileArray = [[NSMutableArray alloc] init];
ABMutableMultiValueRef multi = ABRecordCopyValue(record, kABPersonPhoneProperty);
if (ABMultiValueGetCount(multi) > 0) {
// collect all emails in array
for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) {
CFStringRef mobileRef = ABMultiValueCopyValueAtIndex(multi, i);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(multi, i);
NSString *phoneLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
if([phoneLabel isEqualToString:@"mobile"])
[mobileArray addObject:(NSString *)mobileRef];
else if([phoneLabel isEqualToString:@"iPhone"])
[mobileArray addObject:(NSString *)mobileRef];
else if([phoneLabel isEqualToString:@"home"])
[mobileArray addObject:(NSString *)mobileRef];
else if([phoneLabel isEqualToString:@"work"])
[mobileArray addObject:(NSString *)mobileRef];
else if([phoneLabel isEqualToString:@"main"])
[mobileArray addObject:(NSString *)mobileRef];
else if([phoneLabel isEqualToString:@"other"])
[mobileArray addObject:(NSString *)mobileRef];
CFRelease(mobileRef);
CFRelease(locLabel);
}
}
CFRelease(multi);
if([mobileArray count]>0)
strMobile = [[mobileArray objectAtIndex:0]retain];
else{
NSString *str=[NSString stringWithFormat:@"noNumber%i",noNumberCount];
strMobile = [str retain];
noNumberCount++;
}
[mobileArray release];
//To set E-mail
NSMutableArray* emailArray = [[NSMutableArray alloc] init];
multi = ABRecordCopyValue(record, kABPersonEmailProperty);
if (ABMultiValueGetCount(multi) > 0) {
// collect all emails in array
for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) {
CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i);
[emailArray addObject:(NSString *)emailRef];
CFRelease(emailRef);
}
}
CFRelease(multi);
if([emailArray count]>0)
strEmail = [[emailArray objectAtIndex:0]retain];
else
strEmail = [@"noemail" retain];
[emailArray release];
bool addBool = NO;
if([strName isEqualToString:@"noName"]){
if([strEmail isEqualToString:@"noemail"]){
}
else{
[dic setObject:strEmail forKey:@"name"];
addBool = YES;
}
if(addBool == NO){
if([strMobile isEqualToString:@"noNumber"]){
}
else{
[dic setObject:strMobile forKey:@"name"];
addBool = YES;
}
}
}
else{
[dic setObject:strName forKey:@"name"];
addBool = YES;
}
[dic setObject:strEmail forKey:@"email"];
[dic setObject:strMobile forKey:@"mobile"];
[dic setObject:nsDate forKey:@"date"];
[dic setObject:strTime forKey:@"time"];
[dic setObject:strNotes forKey:@"notes"];
if(addBool == YES)
[contactArrTemp addObject:dic];
if([strMobile hasPrefix:@"0"]){
NSString *contactNumber=[strMobile stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@""];
if(contactNumber.length>7)
[dic setObject:@"iPhone" forKey:@"ContactType"];
}
else {
if(strMobile.length>9)
[dic setObject:@"iPhone" forKey:@"ContactType"];
}
if(![[dic objectForKey:@"ContactType"] isKindOfClass:[NSNull class]] && [dic objectForKey:@"ContactType"])
{
[self InsertContactWithContactInfoDictionary:dic];
}
[strName release];
[nsDate release];
[strEmail release];
[strMobile release];
[strTime release];
[strNotes release];
[dic release];
}
dispatch_async(self.backgroundQueue, ^(void){ [self gcdDidFinishaddfebriteParsing:dict]; });
dispatch_release(self.backgroundQueue);
self.backgroundQueue=nil;
});
}
}
else
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"PhoneContactsSaved" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"Successful"]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"updateContacts" object:nil userInfo:[NSDictionary dictionaryWithObject:@"success" forKey:@"update"]];
}
}
答案 4 :(得分:3)
Xcode5中的iOS6.1上的yunas代码存在一些问题。有些small adaptions它对我有用。
问题是iOS 6中的ARC不允许dispatch_release(sema);
这是工作代码。注意:我使用m_addressbook
代替addressbook
作为ABAddressBookRef!
#import "ViewController.h"
#import <AddressBook/AddressBook.h>
#import <AddressBook/ABAddressBook.h>
#import <AddressBook/ABPerson.h>
@interface ViewController ()
@property (nonatomic, strong) NSMutableArray* contactList;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
ABAddressBookRef m_addressbook = ABAddressBookCreateWithOptions(NULL, NULL);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@autoreleasepool {
// Write your code here...
// Fetch data from SQLite DB
}
});
ABAddressBookRequestAccessWithCompletion(m_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;
}
if (accessGranted) {
// do your stuff
}
}
// ...
答案 5 :(得分:2)
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadPhoneContacts];
}
-(void)loadPhoneContacts{
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusDenied) {
// 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 (error) {
NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error));
if (addressBook) CFRelease(addressBook);
return;
}
if (status == kABAuthorizationStatusNotDetermined) {
// present the user the UI that requests permission to contacts ...
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];
});
}
if (addressBook) CFRelease(addressBook);
});
} else if (status == kABAuthorizationStatusAuthorized) {
[self listPeopleInAddressBook:addressBook];
if (addressBook) CFRelease(addressBook);
}
}
- (void)listPeopleInAddressBook:(ABAddressBookRef)addressBook
{
NSInteger numberOfPeople = ABAddressBookGetPersonCount(addressBook);
NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
for (NSInteger i = 0; i < numberOfPeople; i++) {
ABRecordRef person = (__bridge ABRecordRef)allPeople[i];
NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSString *lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
NSLog(@"Name:%@ %@", firstName, lastName);
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex numberOfPhoneNumbers = ABMultiValueGetCount(phoneNumbers);
for (CFIndex i = 0; i < numberOfPhoneNumbers; i++) {
NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumbers, i));
NSLog(@" phone:%@", phoneNumber);
}
CFRelease(phoneNumbers);
NSLog(@"=============================================");
}
}
答案 6 :(得分:1)
如果有任何人在iOS5中遇到地址簿问题,请使用
ABAddressBookRef addressBook = ABAddressBookCreate();
而不是
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL);
答案 7 :(得分:1)
ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool granted, CFErrorRef error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!granted){
[[[UIAlertView alloc] initWithTitle:@"Contacts Access Denied"
message:@"This app requires access to your device's Contacts.\n\nPlease enable Contacts access for this app in Settings / Privacy / Contacts"
delegate:nil
cancelButtonTitle:@"Dismiss"
otherButtonTitles:nil] show];
} else {
//access authorized
}
});
});
添加说明以警告在InfoPlist.strings中使用。
NSContactsUsageDescription = "TESTING!";
答案 8 :(得分:1)
Swift 3.别忘了导入联系人
func requestForContactAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void) {
let authorizationStatus = CNContactStore.authorizationStatus(for: CNEntityType.contacts)
switch authorizationStatus {
case .authorized:
completionHandler(true)
case .denied, .notDetermined:
self.contactStore.requestAccess(for: CNEntityType.contacts, completionHandler: { (access, accessError) -> Void in
if access {
completionHandler(access)
} else {
if authorizationStatus == CNAuthorizationStatus.denied {
DispatchQueue.main.async(execute: { () -> Void in
let message = "\(accessError!.localizedDescription)\n\nPlease allow the app to access your contacts through the Settings."
self.showMessage(message: message)
})
}
}
})
default:
completionHandler(false)
}
}
答案 9 :(得分:0)
使用iOS 6,你必须征得这样的许可
requestAccessToEntityType:EKEntityTypeEvent completion:
答案 10 :(得分:0)
在ios中获取地址簿
- (void)retreiveAllContacts
{
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
if (!people) {
return ;
}
CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault,
CFArrayGetCount(people),
people);
CFArraySortValues(peopleMutable,
CFRangeMake(0, CFArrayGetCount(peopleMutable)),
(CFComparatorFunction) ABPersonComparePeopleByName,
(void*) ABPersonGetSortOrdering());
NSMutableArray *contacts = [[NSMutableArray alloc] initWithCapacity:CFArrayGetCount(peopleMutable)];
for (CFIndex i = 0; i < CFArrayGetCount(peopleMutable); i++)
{
ABRecordRef person = CFArrayGetValueAtIndex(peopleMutable, i);
int32_t recId = ABRecordGetRecordID(person);
NSString * abId = [NSString stringWithFormat:@"%d", recId];
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
ABMultiValueRef emailIds = ABRecordCopyValue(person, kABPersonEmailProperty);
NSString* firstName = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString* lastName = (__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString* companyName = (__bridge NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);
NSString* displayName = [firstName ? firstName : @"" stringByAppendingFormat:@" %@", lastName ? lastName : @""];
displayName = [displayName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" "]];
NSMutableDictionary* contactInfo = [[NSMutableDictionary alloc] init];
if(ABPersonHasImageData(person))
{
CFDataRef imageDataRef = ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail);
NSData * imageData = (__bridge NSData *)imageDataRef;
UIImage * thumbImage = [UIImage imageWithData:imageData];
[contactInfo setObject:thumbImage forKey:@"picture"];
}
if(!firstName)
firstName = @"";
if (!lastName)
lastName = @"";
if(!displayName)
displayName = @"";
if(!companyName)
companyName = @"";
// [contactInfo setObject:[firstName capitalizedString] forKey:kFirstNameKey];
//[contactInfo setObject:[lastName capitalizedString] forKey:kLastNameKey];
[contactInfo setObject:[displayName capitalizedString] forKey:@"name"];
[contactInfo setObject:abId forKey:@"ABID"];
// [contactInfo setObject:companyName forKey:kCompanyNameKey];
NSMutableArray* phoneNumbersList = [[NSMutableArray alloc] init];
for (CFIndex j=0; j < ABMultiValueGetCount(phoneNumbers); j++)
{
NSString* phone = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, j);
CFStringRef localizedLabel = ABMultiValueCopyLabelAtIndex(phoneNumbers,j);
// NSString *phoneLabel =(__bridge NSString*) ABAddressBookCopyLocalizedLabel(localizedLabel);
if( phone)
{
// NSLog(@"validatedPhone: %@", validatedPhone);
[phoneNumbersList addObject:phone];
}
if (localizedLabel) {
// NSLog(@"localizedLabel: %@", localizedLabel);
CFRelease(localizedLabel);
}
}
if(phoneNumbers)
{
// NSLog(@"phoneNumbers: %@", phoneNumbers);
CFRelease(phoneNumbers);
// NSLog(@"phoneNumbers Release: %@", phoneNumbers);
}
[contactInfo setObject:phoneNumbersList forKey:@"phoneNumbers"];
NSMutableArray * emailList = [[NSMutableArray alloc] init];
for (CFIndex j=0; j < ABMultiValueGetCount(emailIds); j++)
{
NSString* email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emailIds, j);
CFStringRef localizedLabel = ABMultiValueCopyLabelAtIndex(emailIds, j);
if(email)
{
[emailList addObject:email];
}
}
if(emailIds)
{
CFRelease(emailIds);
}
if(emailList && [emailList count])
[contactInfo setObject:emailList forKey:@"emails"];
if ([phoneNumbersList count] > 0 || [emailList count] > 0) {
[contacts addObject:contactInfo];
}
}
//CFRelease();
CFRelease(people);
if([contacts count])
{
[self createiOSContactsDataSourceWithFeed:contacts];
}
}
答案 11 :(得分:0)
此代码显示如何设置权限以及如何从手机获取所有联系人,并使用标签标记显示列表中的联系人
var contactStore = CNContactStore()
var contactArray = [CNContact]()
func getContacts()
{
if CNContactStore.authorizationStatus(for: .contacts) == .notDetermined
{
contactStore.requestAccess(for: .contacts, completionHandler: { (authorized:Bool, error:Error?) in
if authorized {
let requestForContacts = CNContactFetchRequest(keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: CNContactFormatterStyle.fullName), CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactImageDataKey as CNKeyDescriptor, CNContactNicknameKey as CNKeyDescriptor])
do{
try self.contactStore.enumerateContacts(with: requestForContacts) { (contacts : CNContact, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
self.contactArray.append(contacts)
//print("hello")
}
}
catch {
print("EXCEPTION COUGHT")
}
}
})
}
else if CNContactStore.authorizationStatus(for: .contacts) == .authorized
{
let requestForContacts = CNContactFetchRequest(keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: CNContactFormatterStyle.fullName), CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactImageDataKey as CNKeyDescriptor, CNContactNicknameKey as CNKeyDescriptor])
do{
try self.contactStore.enumerateContacts(with: requestForContacts) { (contacts : CNContact, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
self.contactArray.append(contacts)
}
}
catch {
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
getContacts()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
//print(contactArray)
return contactArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "defaultCell")
if cell != nil{
//var dig = String()
var hmdig = [String]()
let names = contactArray[indexPath.row]
print(names)
let name1 = names.givenName+" "+names.middleName+" "+names.familyName
for number in names.phoneNumbers
{
let phoneNumber = number.value
let dig = (phoneNumber.value(forKey: "digits") as? String)!
hmdig.append(dig)
}
// Set the contact image.
if let imageData = names.imageData
{
let myImage = cell?.viewWithTag(30) as! UIImageView
myImage.image = UIImage(data: imageData)
}
// let niknm = names.nickname
let nameLable1 = cell?.viewWithTag(10) as! UILabel
nameLable1.text = name1
let nameLable2 = cell?.viewWithTag(20) as? UILabel
nameLable2?.text = hmdig.joined(separator: ",\n")
// let nameLable3 = cell?.viewWithTag(40) as? UILabel
// nameLable3?.text = niknm
return cell!
}
else{
return UITableViewCell()
}
}
答案 12 :(得分:0)
根据iOS最新的Apple开发文档,Apple坚持使用Contact之外的AddressBook。
CNAuthorizationStatus authorizationStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
switch (authorizationStatus) {
case CNAuthorizationStatusNotDetermined: {
break;
}
case CNAuthorizationStatusRestricted: {
break;
}
case CNAuthorizationStatusDenied:{
return;
}
break;
case CNAuthorizationStatusAuthorized: {
break;
}
}
以上目标C代码有助于查找是否授予天气联系人访问权限。