美文网首页
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