自从更新到 iOS 6 后,我注意到我将联系人添加到 iPhone 通讯录的代码不再有效。我相信这是一个与权限相关的问题,因为 Apple 现在需要用户权限才能访问联系人(修复此问题)。
我希望该应用程序会自动请求访问联系人的权限,如下面的屏幕截图所示,但事实并非如此。尝试添加联系人只是失败了ABAddressBookErrorDomain error 1
。
我是否需要以编程方式启动访问联系人请求对话框?这是怎么做的?
根据苹果网站上的这个文档(向下滚动到页面中间的隐私),必须先授予对地址簿的访问权限,然后才能以编程方式访问它。这就是我最终要做的。
#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 及更高版本的更新:
从苹果网站:
重要的
地址簿 UI 框架在 iOS 9 中已弃用。请改用 ContactsUI 框架中定义的 API。要了解更多信息,请参阅ContactsUI
这对我来说是完美的把戏!
在 iOS6 上,苹果引入了新的隐私控制,用户可以控制每个应用程序对联系人和日历的访问。因此,在代码方面,您需要添加一些方法来请求权限。在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
对于联系人框架:
- (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;
}
}
Xcode5 中 iOS6.1 上的yunas代码有一些问题。通过一些小的调整,它对我有用。
问题是 iOS 6 中的 ARC 不允许dispatch_release(sema);
Here's the working code。注意:我使用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
}
}
// ...
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"]];
}
}
- (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(@"=============================================");
}
}
根据 iOS 最近的苹果开发文档,除了AddressBook之外,苹果坚持使用Contact。
CNAuthorizationStatus authorizationStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
switch (authorizationStatus) {
case CNAuthorizationStatusNotDetermined: {
break;
}
case CNAuthorizationStatusRestricted: {
break;
}
case CNAuthorizationStatusDenied:{
return;
}
break;
case CNAuthorizationStatusAuthorized: {
break;
}
}
以上目标c代码有助于查找天气联系人访问权限是否被授予。
如果有人对 iOS5 中的地址簿有疑问,请使用
ABAddressBookRef addressBook = ABAddressBookCreate();
安装在
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL);
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)
}
}
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!";
使用 iOS 6,您必须像这样请求许可
requestAccessToEntityType:EKEntityTypeEvent completion:
在 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];
}
}
此代码显示如何设置权限以及如何从手机中获取所有联系人并在列表中显示带有标签标签的联系人
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()
}
}