CNContact 显示名称 objective c / swift
CNContact display name objective c / swift
我正在开发需要将联系人导入 NSMutableDictionary
的应用程序,但有时人们不会填写所有联系人详细信息。所以只留下号码或公司名称。我是否需要查看所有联系人详细信息以检查哪个字段将是我的 "display name"。在 Android 我知道有 displayName
变量。但是在 Swift 或 Objective C 中如何?
我的代码:
BOOL success = [addressBook
enumerateContactsWithFetchRequest:request
error:&contactError
usingBlock:^(CNContact *contact, BOOL *stop){
NSString * contactId = contact.identifier;
NSString * firstName = contact.givenName;
NSString * lastName = contact.familyName;
}];
#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>
- (IBAction)displayContact:(id)sender {
id keysToFetch = @[[CNContactViewController descriptorForRequiredKeys]];
CNContact *contact = [self.store unifiedContactWithIdentifier:self.contactIdentifier keysToFetch:keysToFetch error:nil];
self.controller = [[CNContactViewController alloc] init];
[self.controller.view setFrameSize:NSMakeSize(500, 500)];
[self presentViewController:self.controller asPopoverRelativeToRect:self.view.bounds ofView: self.view preferredEdge: NSMaxXEdge behavior:NSPopoverBehaviorTransient];
self.controller.contact = contact;
}
您可以使用此代码从 phone 簿中获取联系人姓名:-
- (void) fetchContacts
{
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusDenied) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"This app previously was refused permissions to contacts; Please go to settings and grant permission to this app so it can use contacts" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:TRUE completion:nil];
return;
}
CNContactStore *store = [[CNContactStore alloc] init]; [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
// make sure the user granted us access
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// user didn't grant access;
// so, again, tell user here why app needs permissions in order to do it's job;
// this is dispatched to the main queue because this request could be running on background thread
});
return;
}
// build array of contacts
NSMutableArray *contacts = [NSMutableArray array];
NSError *fetchError;
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactIdentifierKey, [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]]];
BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
[contacts addObject:contact];
}];
if (!success) {
NSLog(@"error = %@", fetchError);
}
// you can now do something with the list of contacts, for example, to show the names
CNContactFormatter *formatter = [[CNContactFormatter alloc] init];
for (CNContact *contact in contacts) {
if (!_contacts) {
_contacts = [[NSMutableArray alloc] init];
}
NSString *string = [formatter stringFromContact:contact];
NSLog(@"contact = %@", string);
[_contacts addObject:string];
}
[_contactatableview reloadData];
}];
}
从设备中获取联系人
if (isIOS9) { //checking iOS version of Device
CNContactStore *store = [[CNContactStore alloc] init];
//keys with fetching properties
NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactEmailAddressesKey,CNContactPostalAddressesKey, CNLabelWork, CNLabelDateAnniversary];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
DLOG(@"cnContacts %lu",(unsigned long)cnContacts.count);
if (error) {
//error
} else {
for (CNContact *contact in cnContacts) {
//iterate over cnContacts to get details
}
}
} else {
//for below iOS 9
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef arrPersons = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex count = ABAddressBookGetPersonCount(addressBook);
NSLog(@"cnContacts %lu",(unsigned long)count);
for (int i = 0; i < count; i++) {
ABRecordRef record = CFArrayGetValueAtIndex(arrPersons,i);
//use kABPersonBirthdayProperty to get b’day
NSString *birthDay = (__bridge NSString *)(ABRecordCopyValue(record, kABPersonBirthdayProperty));
NSLog(@“B’day %@”, birthDay);
}
}
使用CNContactFormatter
建立显示名称。在为请求指定键时,使用 descriptorForRequiredKeysForStyle
确保您请求了适当的字段。
在 Swift 中,它将是:
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
guard granted else {
print(error?.localizedDescription ?? "Unknown error")
return
}
let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
let formatter = CNContactFormatter()
formatter.style = .fullName
do {
try store.enumerateContacts(with: request) { contact, stop in
if let name = formatter.string(from: contact) {
print(name)
}
}
} catch let fetchError {
print(fetchError)
}
}
您建议您遇到既没有姓名也没有公司,只有 phone 号码的情况。好吧,那么,你必须自己手动处理:
let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as CNKeyDescriptor, CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
do {
try store.enumerateContacts(with: request) { contact, stop in
if let name = formatter.string(from: contact) {
print(name)
} else if let firstPhone = contact.phoneNumbers.first?.value {
print(firstPhone.stringValue)
} else {
print("no name; no number")
}
}
} catch let fetchError {
print(fetchError)
}
对于 Swift 2,请参阅 previous revision of this answer。
我正在开发需要将联系人导入 NSMutableDictionary
的应用程序,但有时人们不会填写所有联系人详细信息。所以只留下号码或公司名称。我是否需要查看所有联系人详细信息以检查哪个字段将是我的 "display name"。在 Android 我知道有 displayName
变量。但是在 Swift 或 Objective C 中如何?
我的代码:
BOOL success = [addressBook
enumerateContactsWithFetchRequest:request
error:&contactError
usingBlock:^(CNContact *contact, BOOL *stop){
NSString * contactId = contact.identifier;
NSString * firstName = contact.givenName;
NSString * lastName = contact.familyName;
}];
#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>
- (IBAction)displayContact:(id)sender {
id keysToFetch = @[[CNContactViewController descriptorForRequiredKeys]];
CNContact *contact = [self.store unifiedContactWithIdentifier:self.contactIdentifier keysToFetch:keysToFetch error:nil];
self.controller = [[CNContactViewController alloc] init];
[self.controller.view setFrameSize:NSMakeSize(500, 500)];
[self presentViewController:self.controller asPopoverRelativeToRect:self.view.bounds ofView: self.view preferredEdge: NSMaxXEdge behavior:NSPopoverBehaviorTransient];
self.controller.contact = contact;
}
您可以使用此代码从 phone 簿中获取联系人姓名:-
- (void) fetchContacts
{
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusDenied) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"This app previously was refused permissions to contacts; Please go to settings and grant permission to this app so it can use contacts" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:TRUE completion:nil];
return;
}
CNContactStore *store = [[CNContactStore alloc] init]; [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
// make sure the user granted us access
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// user didn't grant access;
// so, again, tell user here why app needs permissions in order to do it's job;
// this is dispatched to the main queue because this request could be running on background thread
});
return;
}
// build array of contacts
NSMutableArray *contacts = [NSMutableArray array];
NSError *fetchError;
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactIdentifierKey, [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]]];
BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
[contacts addObject:contact];
}];
if (!success) {
NSLog(@"error = %@", fetchError);
}
// you can now do something with the list of contacts, for example, to show the names
CNContactFormatter *formatter = [[CNContactFormatter alloc] init];
for (CNContact *contact in contacts) {
if (!_contacts) {
_contacts = [[NSMutableArray alloc] init];
}
NSString *string = [formatter stringFromContact:contact];
NSLog(@"contact = %@", string);
[_contacts addObject:string];
}
[_contactatableview reloadData];
}];
}
从设备中获取联系人
if (isIOS9) { //checking iOS version of Device
CNContactStore *store = [[CNContactStore alloc] init];
//keys with fetching properties
NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactEmailAddressesKey,CNContactPostalAddressesKey, CNLabelWork, CNLabelDateAnniversary];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
DLOG(@"cnContacts %lu",(unsigned long)cnContacts.count);
if (error) {
//error
} else {
for (CNContact *contact in cnContacts) {
//iterate over cnContacts to get details
}
}
} else {
//for below iOS 9
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef arrPersons = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex count = ABAddressBookGetPersonCount(addressBook);
NSLog(@"cnContacts %lu",(unsigned long)count);
for (int i = 0; i < count; i++) {
ABRecordRef record = CFArrayGetValueAtIndex(arrPersons,i);
//use kABPersonBirthdayProperty to get b’day
NSString *birthDay = (__bridge NSString *)(ABRecordCopyValue(record, kABPersonBirthdayProperty));
NSLog(@“B’day %@”, birthDay);
}
}
使用CNContactFormatter
建立显示名称。在为请求指定键时,使用 descriptorForRequiredKeysForStyle
确保您请求了适当的字段。
在 Swift 中,它将是:
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
guard granted else {
print(error?.localizedDescription ?? "Unknown error")
return
}
let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
let formatter = CNContactFormatter()
formatter.style = .fullName
do {
try store.enumerateContacts(with: request) { contact, stop in
if let name = formatter.string(from: contact) {
print(name)
}
}
} catch let fetchError {
print(fetchError)
}
}
您建议您遇到既没有姓名也没有公司,只有 phone 号码的情况。好吧,那么,你必须自己手动处理:
let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as CNKeyDescriptor, CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
do {
try store.enumerateContacts(with: request) { contact, stop in
if let name = formatter.string(from: contact) {
print(name)
} else if let firstPhone = contact.phoneNumbers.first?.value {
print(firstPhone.stringValue)
} else {
print("no name; no number")
}
}
} catch let fetchError {
print(fetchError)
}
对于 Swift 2,请参阅 previous revision of this answer。