iOS 通讯录开发之保有姿势。获取通讯录–AddressBookUI的利用。

通讯录简介

通讯录使用状况:

  1. 电商类的 App,设置收货人电话号码。
  2. 即时通讯类 App,添加手机联系人相知。

通讯录获取方案:

同样、iOS 9 以前的通讯录框架

  1. AddressBookUI.framework 框架

    1. 供了关系人列表界面、联系人详情界面、添加联系人界面等。
    2. 一般用于选择联系人。
  2. AddressBook.framework 框架

    1. 纯 C 语言的 API,仅仅是抱联系人数以。
    2. 没提供 UI 界面展示,需要团结搭建沟通人出示界面。
    3. 其间的数据类型大部分根据 Core Foundation
      框架,使用起来炒鸡复杂。

其次、 iOS 9 以后最新通讯录框架

  1. ContactsUI.framework 框架。

    • 拥有 AddressBookUI.framework
      框架的备功能,使用起来更加的面向对象。
  2. Contacts.framework 框架。

    • 拥有 AddressBook.framework 框架的有所机能,不再是 C 语言的
      API,使用起来非常简单。

一. 通讯录的简介

  1. 通讯录获取重要用于一些即时通讯App, 如微信, 可以得到你的无绳电话机通讯录,
    查看哪样好友注册了微信号

  2. 此时此刻通讯录获取之方案

    1. AddressBookUI.framework框架
      • 是框架提供了沟通人列表界面/详情界面/添加关系人界面等
      • 以此框架一般用于查看联系人/添加联系人等作用
    2. AddressBook.framework框架
      • 欠框架和方相比, 没有UI其次字,
        因此他并不曾提供UI界面的显示, 需要手动搭建界面
      • 该框架是一个纯C语言的API, 主要用户获得联系人之数
      • 中的始末大部分是冲CoreFoundation框架的数据类型,
        因此使用比较麻烦
      • 由iOS6始, 需要获得用户之授权才会访问通讯录,
        因此还要检查用户是否授权了
    3. RHAddressBook三正值框架
      • 拖欠框架是针对AddressBook.framework框架的包装
      • 动较为简单, 不过较为古老
    4. iOS9.0新推出的简单只框架:
      • ContactsUI.framework -> AddressBookUI.framework的替代品
      • Contacts.framework -> AddressBook.framework的替代品
      • 马上简单只框架都浮动以当对象的包装, 使用大粗略, 也比强,
        但是烦恼为iOS9.0+专用, 对于没有版本适配很是无奈

iOS 9 以前的通讯录框架

二. AddressBookUI的使用

  1. 落实步骤

    1. 始建选择联系人的控制器:

    2. 安装选择联系人控制器的代理属性

    3. 弹有控制器

       // 1. 创建联系人选择控制器
       ABPeoplePickerNavigationController *pickVC = [[ABPeoplePickerNavigationController alloc] init];
      
       // 2. 设置代理
       pickVC.peoplePickerDelegate = self;
      
       // 3. 弹出控制器
       [self presentViewController:pickVC animated:YES completion:nil];
      
    4. 遵照协议, 并且实现代理方:
      ABPeoplePickerNavigationControllerDelegate

    5. 当点击某个联系人经常调用的计:

      • 牵连人的特性:
        • 简简单单属性: firstName/lastName等
        • 复杂属性: 电话号码/电子邮件
          • 对复杂属性,
            要使用ABRecordCopyValue函数返回的ABMutiValueRef色来收取
          • ABRecordCopyValue待少单参数, 一个是联络员对象,
            一个凡是亟需得到的多寡要字
          • 复杂属性要指定取出哪个属性, 比如电话,
            划分为座机/手机等等不同的对讲机,
            因此该品种涵盖了差不多个数据
          • ABMutiValueRef是一个含了多只数据的结,
            要通过遍历其中的数据, 才会取出每一个

                    // 选择某个联系人的时候调用
                    - (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person {

                        NSLog(@"选中了某个联系人");

                        // 取出联系人的姓名数据
                        CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
                        CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);

                        // 将CoreFoundation的字符串, 转化为OC的字符串, 并且转移内存管理权
                        NSString *first = CFBridgingRelease(firstName);
                        NSString *last = CFBridgingRelease(lastName);

                        NSLog(@"%@--%@", first, last);

                        // 取出电话的数据
                        ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonPhoneProperty);
                        CFIndex count = ABMultiValueGetCount(multi);

                        for (int i = 0; i < count; i++) {
                            NSString *label = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(multi, i);
                            NSString *phone = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(multi, i);
                            NSLog(@"%@---%@", label, phone);
                        }
                    }

AddressBookUI

心想事成步骤

一致、创建选择联系人之控制器

// 创建联系人选择控制器    
ABPeoplePickerNavigationController *pvc = [[ABPeoplePickerNavigationController alloc] init];

其次、设置代理(用来收纳用户选择的关系人消息)

// 设置代理
pvc.peoplePickerDelegate = self;

老三、弹出联系人控制器

if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
{
   ABAddressBookRef bookRef = ABAddressBookCreate();
   ABAddressBookRequestAccessWithCompletion(bookRef, ^(bool granted, CFErrorRef error) {
       if (granted)
       {
           NSLog(@"授权成功!");
           [self presentViewController:pvc animated:YES completion:nil];
       }
       else
       {
           NSLog(@"授权失败!");
       }
   });
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
{
   [self presentViewController:pvc animated:YES completion:nil];
}

季、实现代理方

// 选择某个联系人时调用
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person
{
    NSLog(@"选中联系人");
    CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
    CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);

    NSString *fir = CFBridgingRelease(firstName);
    NSString *las = CFBridgingRelease(lastName);

    NSLog(@"%@---%@", fir, las);

    ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonPhoneProperty);
    CFIndex count = ABMultiValueGetCount(multi);
    for (int i = 0; i  < count; i++) 
    {
        NSString *label = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(multi, i);
        NSString *phone =(__bridge_transfer NSString *)  ABMultiValueCopyValueAtIndex(multi, i);
        NSLog(@"%@---%@", label, phone);
    }
}

Core Foundation 对象手动管理内存,如果是 Create、Copy、Retain
等字样创建的靶子,需要手动 CFRelease。类似 Objective-C 的 MRC。

拓展:__bridge__bridge_retained__bridge_transfer
三个转移关键字的分别。

  1. __bridge 只做类型转换,但是不修改对象(内存)管理权;
  2. __bridge_retained(也堪采取CFBridgingRetain)将 Objective-C
    的对象转换为 Core Foundation
    的目标,同时用目标(内存)的管理权交给我们,后续要运用 CFRelease
    或者有关方法来释放对象;
  3. __bridge_transfer(也可行使 CFBridgingRelease )将 Core
    Foundation 的目标转换为 Objective-C
    的目标,同时将对象(内存)的管理权交给 ARC。

五、在相应的代办方中取联系人信

// 1.选择联系人时使用(不展开详情)
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person;

// 2.选择联系人某个属性时调用(展开详情)
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier;

// 3.取消选中联系人时调用
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;

留意:选择联系人的非进行详情(代理方1)和进行详情(代理方2)的代办方都勾了底下,展开详情的代办方就未履行。

AddressBook

同样、请求授权

自 iOS 6
开始,需要获得用户之授权才会顾通讯录,因此在运之前,需要检查用户是否曾经授权。

// 获得通讯录的授权状态
ABAddressBookGetAuthorizationStatus()

授权状态

  1. 用户还尚未决定是否授权你的次序开展访问:kABAuthorizationStatusNotDetermined

  2. iOS
    设备及一些许可配置阻止程序和通讯录数据库进行互:kABAuthorizationStatusRestricted

  3. 用户明确的不肯了而的先后对通讯录的拜访:kABAuthorizationStatusDenied

  4. 用户都授权为你的次第对通讯录进行走访:kABAuthorizationStatusAuthorized

// 判断当前的授权状态是否是用户还未选择的状态
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) 
{
   ABAddressBookRef bookRef = ABAddressBookCreate();
   ABAddressBookRequestAccessWithCompletion(bookRef, ^(bool granted, CFErrorRef error) {
       if (granted) 
       {
           NSLog(@"授权成功!");
       }
       else
       {
           NSLog(@"授权失败!");
       }
   });
}

第二、判断授权状态

假定就授权,则持续;未授权,则提醒用户,并回到。

// 判断当前的授权状态
if (ABAddressBookGetAuthorizationStatus() != kABAuthorizationStatusAuthorized) 
{
    NSLog(@"您的通讯录暂未允许访问,请去设置->隐私里面授权!");
    return;
}

其三、创建通讯录对象

// 创建通讯录对象
ABAddressBookRef bookRef = ABAddressBookCreate();

季、从通信录对象中, 获取有的关联人

// 获取通讯录中所有的联系人
CFArrayRef arrayRef = ABAddressBookCopyArrayOfAllPeople(bookRef);

五、遍历所有的牵连人

// 遍历所有联系人
CFIndex count = CFArrayGetCount(arrayRef);
for (int i = 0; i < count; i++) 
{
   ABRecordRef record = CFArrayGetValueAtIndex(arrayRef, i);

   // 获取姓名
   NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty);
   NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty);
   NSLog(@"firstName = %@, lastName = %@", firstName, lastName);

   // 获取电话号码
   ABMultiValueRef multiValue = ABRecordCopyValue(record, kABPersonPhoneProperty);
   CFIndex count = ABMultiValueGetCount(multiValue);
   for (int i = 0; i < count; i ++) 
   {
       NSString *label = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(multiValue, i);
       NSString *phone = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(multiValue, i);
       NSLog(@"label = %@, phone = %@", label, phone);
   }

   CFRelease(multiValue);
}

六、释放不再动用的对象

CFRelease(bookRef);
CFRelease(arrayRef);

关系人属性定义

负有的性能常量值都定义在了 ABPerson.h 头文件中。

联系人属性包括以下种类:

  1. 简短属性:姓、名当
  2. 大多重属性:电话号码、电子邮件等
  3. 组合属性:地址等

注意:使用 ABRecordCopyValue 可以于同长达 Person
记录面临得到对应之笔录,但是后续处理则需要基于记录的切实可行品种加以区别。

简而言之属性

一个关系人便是一个
ABRecordRef,每个联系人还生好之习性,比如名、电话、邮件等。
使用 ABRecordCopyValue 函数可以从 ABRecordRef
中获得联系人之简易属性(例如:一个字符串)。
ABRecordCopyValue 函数接收 2 只参数。
第 1 独参数是 ABRecordRef 实例。
第 2 个参数是性关键字,定义在 ABPerson.h 中。
ABPersonCopyLocalizedPropertyName
函数可以根据指定的主要字取相应的价签文本。

落有的牵连人数量

// 获取所有联系人记录
CFArrayRef array = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSInteger count = CFArrayGetCount(array);

for (NSInteger i = 0; i < count; ++i) {
    // 取出一条记录
    ABRecordRef person = CFArrayGetValueAtIndex(array, i);

    // 取出个人记录中的详细信息
    // 名
    CFStringRef firstNameLabel = ABPersonCopyLocalizedPropertyName(kABPersonFirstNameProperty);
    CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
    CFStringRef lastNameLabel = ABPersonCopyLocalizedPropertyName(kABPersonLastNameProperty);
    // 姓
    CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);

    NSLog(@"%@ %@ - %@ %@", lastNameLabel, lastName, firstNameLabel, firstName);
}

CoreFoundation 与 Foundation之间的桥接

// 1. 获取通讯录引用
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, nil);
// 2. 获取所有联系人记录
NSArray *array = (__bridge NSArray *)(ABAddressBookCopyArrayOfAllPeople(addressBook));
for (NSInteger i = 0; i < array.count; i++) {
    // 取出一条记录
    ABRecordRef person = (__bridge ABRecordRef)(array[i]);
    // 取出个人记录中的详细信息
    NSString *firstNameLabel = (__bridge NSString *)(ABPersonCopyLocalizedPropertyName(kABPersonFirstNameProperty));
    NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
    NSString *lastNameLabel = (__bridge NSString *)(ABPersonCopyLocalizedPropertyName(kABPersonLastNameProperty));
    NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty));
    NSLog(@"%@ %@ - %@ %@", lastNameLabel, lastName, firstNameLabel, firstName);
}
CFRelease(addressBook);

基本上重属性

牵连人的小属性值就不曾这么简单,一个特性可能会见含有多单价
以邮箱,分为工作邮箱、住宅信箱、其他邮箱等
准电话,分为工作电话、住宅电话、其他电话等
如果是扑朔迷离属性,那么 ABRecordCopyValue 函数回的哪怕是
ABMultiValueRef 类型的多少,例如邮箱或者电话

// 取电话号码
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
// 取记录数量
NSInteger phoneCount = ABMultiValueGetCount(phones);
// 遍历所有的电话号码
for (NSInteger i = 0; i < phoneCount; i++) 
{

}

获得复杂属性的措施

// 电话标签
CFStringRef phoneLabel = ABMultiValueCopyLabelAtIndex(phones, i);
// 本地化电话标签
CFStringRef phoneLocalLabel = ABAddressBookCopyLocalizedLabel(phoneLabel);
// 电话号码
CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phones, i);

加上挂钩人之手续

累加沟通人的步骤:

  1. 通过 ABPersonCreate 函数创建一个初的联络员(返回 ABRecordRef)。
  2. 通过 ABRecordSetValue 函数设置联系人之习性。
  3. 通过 ABAddressBookAddRecord 函数将关系人填补加至通讯录数据库中。
  4. 通过 ABAddressBookSave 函数保存刚才所作的改动。

可以通过 ABAddressBookHasUnsavedChanges 函数判断是否发生非保存的改动
当控制是否改变通讯录数据库后,你可以分别以 AbAddressBookSave
ABAddressBookRevert 方式来保存还是放弃双重改 。

添加群组的步调

增长群组的步子大体与长联络官一致:

  1. 通过 ABPersonCreate 函数创建一个新的组。(返回 ABRecordRef
  2. 通过 ABRecordSetValue 函数设置组名。
  3. 通过 ABAddressBookAddRecord 函数将组添加到通讯录数据库被。
  4. 通过 ABAddressBookSave 函数保存刚才所发的改。

操作联系人的头像

思操作联系人的头像,有以下函数
BPersonHasImageData
看清通讯录中的联系人是否出图片

ABPersonCopyImageData
获取图片数(假如有言语)

ABPersonSetImageData
安联系人的图纸数

通讯录的改动回调

// 创建通讯录
self.addressBook = ABAddressBookCreate();  
// 注册通知  
ABAddressBookRegisterExternalChangeCallback(self.addressBook, _addressBookChange, nil);            

// 处理收到通知的 Action
void _addressBookChange(ABAddressBookRef addressBook, CFDictionaryRef info, void *context)
{
}

- (void)dealloc
{
    // 注销通知
    ABAddressBookUnregisterExternalChangeCallback(self.addressBook, _addressBookChange, nil);
    // 释放对象
    CFRelease(self.addressBook);
}

iOS 9 以后的报道录新框架

iOS 9 之前操作通讯录还是比较辛苦的,iOS 9
以后苹果推出了新的通讯录框架,使用起来更的面向对象。

CNContactUI

兑现步骤

同、创建选择联系人之控制器

// 创建联系人选择控制器    
CNMutableContact *contact = [[CNMutableContact alloc] init];
CNLabeledValue *labelValue = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMobile
ontact.phoneNumbers = @[labelValue];                                                                     value:[CNPhoneNumber phoneNumberWithStringValue:phoneNum]];
CNContactViewController *contactController = [CNContactViewController viewControllerForNewContact:contact];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:contactController];

其次、设置代理(用来接受用户选择的联系人信)

// 设置代理
contactController.delegate = self;

老三、弹出联系人控制器

[controller presentViewController:nav animated:YES completion:nil];

季、实现代理方

// 选择某个联系人时调用
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty
{
    CNContact *contact = contactProperty.contact;
    NSString *name = [CNContactFormatter stringFromContact:contact style:CNContactFormatterStyleFullName];
    CNPhoneNumber *phoneValue= contactProperty.value;
    NSString *phoneNumber = phoneValue.stringValue;
    NSLog(@"%@--%@",name, phoneNumber);
}

五、在相应之代理方吃获取联系人信息

// 1.选择联系人时使用(不展开详情)
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact;

// 2.选择联系人某个属性时调用(展开详情)
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;

// 3.取消选中联系人时调用
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker;

小心:与 AddressBookUI
一样,选择联系人之非开展详情(代理方1)和拓展详情(代理方2)的代理方都勾了之时,展开详情的代办方就非执。

CNContact

贯彻步骤

一样、请求授权

// 获得通讯录的授权状态
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]

授权状态

  1. 用户还没决定是否授权你的程序开展走访:CNAuthorizationStatusNotDetermined

  2. iOS
    设备上一些特许配置阻止程序及通讯录数据库进行相互:CNAuthorizationStatusRestricted

  3. 用户明确的不容了您的次序对通讯录的拜会:CNAuthorizationStatusDenied

  4. 用户就授权为你的程序对通讯录进行走访:CNAuthorizationStatusAuthorized

// 判断当前的授权状态是否是用户还未选择的状态
if (status == CNAuthorizationStatusNotDetermined)
{
    CNContactStore *store = [CNContactStore new];
    [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) 
        {
            NSLog(@"授权成功!");
        }
        else
        {
            NSLog(@"授权失败!");
        }
    }];
}

老二、判断授权状态

设已授权,则连续;未授权,则提醒用户,并回。

// 判断当前的授权状态
if (status != CNAuthorizationStatusAuthorized) 
{
    NSLog(@"您的通讯录暂未允许访问,请去设置->隐私里面授权!");
    return;
}

其三、创建通讯录对象

// 创建通讯录对象
CNContactStore *contactStore = [CNContactStore new];

季、设置访问的性 Key,每个 Key 对应一个特性,iOS 9
新增,如果没有设置,访问该属性就会崩溃。

// 姓名前缀
CNContactNamePrefixKey     
// 名                 
CNContactGivenNameKey                       
// 中间名
CNContactMiddleNameKey  
// 姓                   
CNContactFamilyNameKey            
// 婚前姓         
CNContactPreviousFamilyNameKey
// 姓名后缀
CNContactNameSuffixKey   
// 昵称                   
CNContactNicknameKey                        
// 公司
CNContactOrganizationNameKey                
// 部门
CNContactDepartmentNameKey                  
// 职位
CNContactJobTitleKey                        
// 名字拼音或音标
CNContactPhoneticGivenNameKey
// 中间名拼音或音标              
CNContactPhoneticMiddleNameKey
// 姓拼音或音标
CNContactPhoneticFamilyNameKey  
// 公司拼音或音标            
CNContactPhoneticOrganizationNameKey      
// 生日  
CNContactBirthdayKey   
// 农历                    
CNContactNonGregorianBirthdayKey    
// 备注        
CNContactNoteKey                            
// 图片
CNContactImageDataKey                       
// 缩略图
CNContactThumbnailImageDataKey              
// 图片是否允许访问
CNContactImageDataAvailableKey              
// 类型
CNContactTypeKey                            
// 号码
CNContactPhoneNumbersKey                    
// 电子邮件
CNContactEmailAddressesKey                  
// 地址
CNContactPostalAddressesKey                 
// 日期
CNContactDatesKey   
// URL                        
CNContactUrlAddressesKey                    
// 关联人
CNContactRelationsKey                       
// 社交
CNContactSocialProfilesKey                  
// 即时通讯
CNContactInstantMessageAddressesKey         

NSArray *keys = @[CNContactPhoneNumbersKey,CNContactGivenNameKey];

五、从通信录对象吃, 获取有的联系人,并遍历

// 获取通讯录中所有的联系人
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];

[contactStore enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
    // 获取姓名
    NSString *firstName = contact.familyName;
    NSString *lastName = contact.givenName;

    NSLog(@"%@--%@",firstName,lastName);

    // 获取电话号码

    for (CNLabeledValue *labeledValue in contact.phoneNumbers)
    {
         CNPhoneNumber *phoneValue = labeledValue.value;
         NSString *phoneNumber = phoneValue.stringValue;
         NSString *label = [CNLabeledValue localizedStringForLabel:labeledValue.label];
         NSLog(@"%@--%@",label,phoneNumber);
    }

}];

通讯录的改回调

// 注册通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_contactStoreDidChange) name:CNContactStoreDidChangeNotification object:nil]            

// 处理收到通知的 Action
- (void)_contactStoreDidChange
{
}

- (void)dealloc
{   
    // 注销通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:CNContactStoreDidChangeNotification object:nil];
}

当 App
活跃(前台+后台活动之间)的当儿,当通讯录修改的当儿,会吸纳通知
当 App 不欢的上(挂于的下),App 收不顶通报;而是,当 App
到前台的时候接到延迟的通告。

LJContactManager

介绍

LJContanctManager 是我勾勒的均等放缓操作通讯录的类库,iOS 9 之前用的凡
AddressBook 和 AddressBookUI 系统库,iOS 9 之后采取苹果新推出的 Contacts
和 ContactsUI 框架。

安装

CocoaPods

  1. 在 Podfile 中添加 pod 'LJContactManager'
  2. 执行 pod installpod update
  3. 导入 <LJContactManager.h>。

手动安装

  1. 下载 LJContactManager 文件夹内的具有内容。
  2. 将 LJContactManager 内的源文件添加(拖放)到你的工。
  3. 导入 LJContactManager.h

使用

着重提供以下的办法:

  • 挑联系人

/**
 选择联系人

 @param controller 控制器
 @param completcion 回调
 */
- (void)selectContactAtController:(UIViewController *)controller
                      complection:(void (^)(NSString *name, NSString *phone))completcion;
  • 始建新关系人

/**
 创建新联系人

 @param phoneNum 手机号
 @param controller 当前 Controller
 */
- (void)createNewContactWithPhoneNum:(NSString *)phoneNum controller:(UIViewController *)controller;
  • 累加到存活联系人

/**
 添加到现有联系人

 @param phoneNum 手机号
 @param controller 当前 Controller
 */
- (void)addToExistingContactsWithPhoneNum:(NSString *)phoneNum controller:(UIViewController *)controller;
  • 收获联系人列表(未分组的通讯录)

/**
 获取联系人列表(未分组的通讯录)

 @param completcion 回调
 */
- (void)accessContactsComplection:(void (^)(BOOL succeed, NSArray <LJPerson *> *contacts))completcion;
  • 取联系人列表(已分组的通讯录)

/**
 获取联系人列表(已分组的通讯录)

 @param completcion 回调
 */
- (void)accessSectionContactsComplection:(void (^)(BOOL succeed, NSArray <LJSectionPerson *> *contacts, NSArray <NSString *> *keys))completcion;
  • 报道录变更回调(未分组的通讯录)

/**
 通讯录变更回调(未分组的通讯录)
 */
@property (nonatomic, copy) void (^contactsChangeHanlder) (BOOL succeed, NSArray <LJPerson *> *newContacts);
  • 简报录变更回调(已分组的通讯录)

/**
 通讯录变更回调(已分组的通讯录)
 */
@property (nonatomic, copy) void (^sectionContactsHanlder) (BOOL succeed, NSArray <LJSectionPerson *> *newSectionContacts, NSArray <NSString *> *keys);

最后

由作者水平有限,文中如果产生错的地方,或者发更好的方式,还于大神指出。
屈居本文的备 demo
下充斥链接,【GitHub】。
比方你看了晚当对你抱有帮助,还向在 GitHub 上沾个
star。赠人玫瑰,手有余香。

相关文章