美文网首页
Contacts.framework的使用详解

Contacts.framework的使用详解

作者: 智狸 | 来源:发表于2019-05-30 16:33 被阅读0次

初识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

相关文章

网友评论

      本文标题:Contacts.framework的使用详解

      本文链接:https://www.haomeiwen.com/subject/mypvtctx.html