初识Contacts framework
Contacts.framework是iOS9之后新出来的用于处理通讯录联系人的一系列方法。
1. Contact联系人对象
1.1 CNContact联系人对象这个对象是用来配置联系人信息的,有可变的CNMutaleContact和CNContact。CNContact对象中有许多属性,对应联系人的一些信息。
Contact联系人属性:
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSArray<CNLabeledValue<CNPhoneNumber*>*> *phoneNumbers;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSArray<CNLabeledValue<NSString*>*> *emailAddresses;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSArray<CNLabeledValue<CNPostalAddress*>*> *postalAddresses;
@property (readonly, copy, nullable, NS_NONATOMIC_IOSONLY) NSData *imageData;
@property (readonly, copy, nullable, NS_NONATOMIC_IOSONLY) NSData *thumbnailImageData;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *namePrefix;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *givenName;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *middleName;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *familyName;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *previousFamilyName;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *nameSuffix;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *nickname;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *organizationName;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *departmentName;
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *jobTitle;
1.2 CNLabeledValue对象主要用于创建一些联系人属性的键值对应,通过这些对应,系统会帮我们进行数据的格式化。
CNLabeledValue键值对 = key - value
// Generic labels
CONTACTS_EXTERN NSString * const CNLabelHome NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelWork NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelOther NS_AVAILABLE(10_11, 9_0);
// Additional email labels
CONTACTS_EXTERN NSString * const CNLabelEmailiCloud NS_AVAILABLE(10_11, 9_0);
// URL address labels
CONTACTS_EXTERN NSString * const CNLabelURLAddressHomePage NS_AVAILABLE(10_11, 9_0);
// Date labels
CONTACTS_EXTERN NSString * const CNLabelDateAnniversary NS_AVAILABLE(10_11, 9_0);
2. 创建添加联系人请求
2.1 CNSaveRequest是用于存储联系人的请求类,通过这个类,我们可以创建批量添加、修改或者删除联系人的请求。
这个类中还有许多方便我们操作的方法:
@interface CNSaveRequest : NSObject
// 添加一个联系人
- (void)addContact:(CNMutableContact *)contact toContainerWithIdentifier:(nullable NSString *)identifier;
// 更新一个联系人
- (void)updateContact:(CNMutableContact *)contact;
// 删除一个联系人
- (void)deleteContact:(CNMutableContact *)contact;
@end
// 添加通讯录联系人信息
- (void)addContactInfo {
// 初始化方法
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
CNMutableContact *contact = [[CNMutableContact alloc] init];
contact.namePrefix = @"Zhang";
contact.nameSuffix = @"Jay";
CNPhoneNumber *homePhoneNumber = [CNPhoneNumber phoneNumberWithStringValue:@"+8612345678901"];
CNLabeledValue *labeledValue = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:homePhoneNumber];
contact.phoneNumbers = @[labeledValue];
contact.emailAddresses = @[[CNLabeledValue labeledValueWithLabel:CNLabelEmailiCloud value:@"123456@163.com"]];
// CNContactStore是一个用于存取联系人的上下文桥梁
CNContactStore *store = [[CNContactStore alloc] init];
// 添加联系人
[saveRequest addContact:contact toContainerWithIdentifier:[store defaultContainerIdentifier]];
NSError *error = nil;
// 只有执行此操作才会在通讯录生成记录
BOOL flag = [store executeSaveRequest:saveRequest error:&error];
if (flag && error == nil) {
NSLog(@"save successful.");
[[[UIAlertView alloc] initWithTitle:@"contact info save successful." message:@"contact info save successful." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
} else {
[[[UIAlertView alloc] initWithTitle:@"contact info save failure." message:[NSString stringWithFormat:@"contact info save failure, because : %@", error.localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
}
}
3. 在开发中,提取联系人的使用率要远远高于创建联系人。
3.1 iOS9中,ContactsFramework为开发者提供了非常方便的格式化信息的方法。
格式化联系人姓名:[CNContactFormatter stringFromContact:c style:CNContactFormatterStyleFullName]
格式化地址:[CNPostalAddressFormatter stringFromPostalAddress:[c.postalAddresses firstObject].value style:CNPostalAddressFormatterStyleMailingAddress]
3.2 iOS9支持检索联系人的功能,类似于数据库的检索方式,通过配置条件,提取出我们需要的数据。
#import <Contacts/Contacts.h>
- (void)accessContacts {
// 请求权限
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
// 检索联系人
if (status == CNAuthorizationStatusAuthorized || status == CNAuthorizationStatusRestricted) {
[self requestContactsInfo];
} else if (status == CNAuthorizationStatusDenied) {
[[[UIAlertView alloc] initWithTitle:@"请获取访问相册权限!" message:@"请获取访问相册权限!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
} else if (status == CNAuthorizationStatusNotDetermined) {
[[[CNContactStore alloc] init] requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted && error == nil) {
[self requestContactsInfo];
} else {
// 访问通讯录权限被拒绝
}
}];
}
}
- (void)requestContactsInfo {
CNContactStore *store = [[CNContactStore alloc] init];
// 检索条件,检索所有名字中有zhang的联系人
NSPredicate *predicate = [CNContact predicateForContactsMatchingName:@"张"];
// 检索条件,检索通讯录中所有的联系人信息
predicate = [CNContact predicateForContactsInContainerWithIdentifier:[store defaultContainerIdentifier]];
// 提取数据
NSError *error = nil;
// keysToFetch是设置提取联系人的哪些数据。
NSArray<CNContact *> *contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactFamilyNameKey,CNContactGivenNameKey,CNContactOrganizationNameKey,CNContactPhoneNumbersKey,CNContactEmailAddressesKey,CNContactPostalAddressesKey] error:&error];
for (CNContact *c in contacts) {
NSLog(@"%@", c);
}
// 我们也可以通过keysToFetch获取联系人,并对联系人进行遍历。
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactGivenNameKey,CNContactPhoneNumbersKey]];
[store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
NSLog(@"%@", contact);
}];
}
console输出:po contact
<CNContact: 0x149e1d290: identifier=7AC1ECC1-D481-42C3-BDD9-8B171C3E70D1:ABPerson, givenName=小玲, familyName=张, organizationName=(null), phoneNumbers=(
"<CNLabeledValue: 0x282856e80: identifier=25E689F7-9D25-4F4E-91EE-0E3D8437A32D, label=_$!<Other>!$_, value=<CNPhoneNumber: 0x283df4240: stringValue=12345678901, initialCountryCode=(null)>>"
), emailAddresses=(
), postalAddresses=(
)>
3.3 iOS9系统为我们封装好了一套联系人的UI界面,用起来也十分方便,主要新增的controller有两个:
CNContactPickerViewController:展示联系人列表的controller
CNContactViewController:展示联系人详细信息的controller
#import <ContactsUI/ContactsUI.h>
// 只有使用present方式,CNContactPickerViewController才能正常显示,不能使用push方式打开
CNContactPickerViewController *cpVc = [[CNContactPickerViewController alloc] init];
cpVc.delegate = self; // <CNContactPickerDelegate>
[self presentViewController:cpVc animated:YES completion:nil];
// 只有使用push方式,CNContactViewController才能正常显示,不能使用present方式打开
CNContactViewController *contactVc = [CNContactViewController viewControllerForContact:self.contact];
[self.navigationController pushViewController:contactVc animated:YES];
// 取消
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker {
NSLog(@"%@", picker);
}
// 选择一个联系人
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact {
NSLog(@"%@", contact);
}
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty {
NSLog(@"%@", contactProperty);
}
// 选择多个联系人
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray<CNContact*> *)contacts {
for (CNContact *contact in contacts) {
NSLog(@"%@", contact);
}
self.contact = [contacts firstObject];
}
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperties:(NSArray<CNContactProperty*> *)contactProperties {
for (CNContactProperty *contactProperty in contactProperties) {
NSLog(@"%@", contactProperty);
}
}
Demo地址:https://github.com/jayZhangh/PhotosFrameworkBasicUsage.git
网友评论