通信录

1、
在iOS9之前,有2个框架可以访问用户的通讯录
目前需要适配iOS8,所有也必须进行学习
AddressBookUI.framework
提供了联系人列表界面、联系人详情界面、添加联系人界面等
一般用于选择联系人

 

AddressBook.framework
纯C语言的API,仅仅是获得联系人数据
没有提供UI界面展示,需要自己搭建联系人展示界面
里面的数据类型大部分基于Core Foundation框架,使用起来极其蛋疼
 
从iOS6开始,需要得到用户的授权才能访问通讯录,因此在使用之前,需要检查用户是否已经授权
获得通讯录的授权状态:ABAddressBookGetAuthorizationStatus()
 
2、
在iOS9开始,也有2个框架可以访问用户的通讯录
ContactsUI.framework
提供了联系人列表界面、联系人详情界面、添加联系人界面等
一般用于选择联系人

 

Contacts.framework
没有提供UI界面展示,需要自己搭建联系人展示界面
 
3、授权状态
kABAuthorizationStatusNotDetermined
用户还没有决定是否授权你的程序进行访问

 

kABAuthorizationStatusRestricted
iOS设备上一些许可配置阻止程序与通讯录数据库进行交互
 
kABAuthorizationStatusDenied
用户明确的拒绝了你的程序对通讯录的访问
 
kABAuthorizationStatusAuthorized
用户已经授权给你的程序对通讯录进行访问
 
4、代码
***iOS9之前有界面***
#import <AddressBookUI/AddressBookUI.h>

@interface ViewController () <ABPeoplePickerNavigationControllerDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 1.创建一个选择联系人的控制器
    ABPeoplePickerNavigationController *ppnc = [[ABPeoplePickerNavigationController alloc] init];
    
    // 2.设置代理
    ppnc.peoplePickerDelegate = self;
    
    // 3.弹出控制器
    [self presentViewController:ppnc animated:YES completion:nil];
}

#pragma mark - 实现ABPeoplePickerNavigationController的代理方法
/**
 *  当用户选择某一个联系人的时候会执行该方法(如果实现了该方法,那么一定不会执行下面的代理方法)
 *
 *  @param person       选中的联系人
 */
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
    // 1.获取用户的姓名
    NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
    NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSLog(@"%@ %@", lastName, firstName);
    
    // 2.获取电话号码
    // 2.1.获取所有的电话
    ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
    
    // 2.2.将电话进行遍历
    CFIndex phoneCount = ABMultiValueGetCount(phones);
    for (int i = 0; i < phoneCount; i++) {
        // 3.获取电话
        NSString *phoneLabel = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(phones, i);
        NSString *phoneValue = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phones, i);
        NSLog(@"%@ %@", phoneLabel, phoneValue);
    }
}

/**
 *  当用户选择某一个联系人的某一个属性的时候会执行该方法
 *
 *  @param person       选中的联系人
 *  @param property     选中的联系人的属性
 *  @param identifier   每一个属性都有一个对应的表示
 */
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    NSLog(@"%s", __func__);
}

/**
 *  当点击取消按钮时,会执行该方法
 *
 */
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
    NSLog(@"%s", __func__);
}

 

***iOS9之前无界面***

 

#import "AppDelegate.h"


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 1.获取授权状态 ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); // 2.判断授权状态 if (status == kABAuthorizationStatusNotDetermined) { // 3.请求授权 // 3.1.创建通信录对象 ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); // 3.2.请求授权 ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { // 当用户决定是否授权的时候会执行该block if (granted) { // 授权成功 NSLog(@"可以访问通信录"); } else { // 授权失败 NSLog(@"不可以访问通信录"); } }); // 3.3.释放不再使用的对象 CFRelease(addressBook); } return YES; }

 

#import <AddressBook/AddressBook.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 1.判断授权状态
    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
    if (status != kABAuthorizationStatusAuthorized) return;
    
    // 2.获取联系人
    // 2.1.创建通信录对象
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    
    // 2.2.获取所有的联系人
    CFArrayRef peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);
    
    // 2.3.遍历所有的联系人
    CFIndex peopleCount = CFArrayGetCount(peopleArray);
    for (int i = 0; i < peopleCount; i++) {
        
        // 3.获取一条记录
        ABRecordRef person = CFArrayGetValueAtIndex(peopleArray, i);
        
        // 3.1.获取联系人的姓名
        NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
        NSLog(@"%@ %@", firstName, lastName);
        
        // 3.2.获取电话号码
        // 3.2.1.获取所有的电话
        ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
        // 3.3.2.遍历所有的电话号码
        CFIndex phoneCount = ABMultiValueGetCount(phones);
        for (int i = 0; i < phoneCount; i++) {
            NSString *phoneLabel = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(phones, i);
            NSString *phoneValue = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phones, i);
            NSLog(@"%@ %@", phoneLabel, phoneValue);
        }
    }
}

 

***iOS9之后有界面***

#import <ContactsUI/ContactsUI.h>

@interface ViewController () <CNContactPickerDelegate>

@property (nonatomic, strong) NSArray *array;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 1.创建选择联系人的界面
    CNContactPickerViewController *cpvc = [[CNContactPickerViewController alloc] init];
    
    // 2.设置代理
    cpvc.delegate = self;
    
    // 3.弹出控制器
    [self presentViewController:cpvc animated:YES completion:nil];
}

#pragma mark - 实现CNContactPickerViewController的代理方法
/**
 *  当用户选中某一个联系人的时候会执行该方法
 *
 *  @param contact 选中的联系人
 */
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact
{
    // 1.获取联系人的姓名
    NSString *lastname = contact.familyName;
    NSString *firstname = contact.givenName;
    NSLog(@"%@ %@", lastname, firstname);
    
    // 2.获取电话号码
    for (CNLabeledValue *labelValue in contact.phoneNumbers) {
        // 3.获取电话的label/value
        NSString *phoneLabel = labelValue.label;
        CNPhoneNumber *phoneNumber = labelValue.value;
        NSString *phoneValue = phoneNumber.stringValue;
        NSLog(@"%@ %@", phoneLabel, phoneValue);
    }
}

/**
 *  当用户选中某一个联系人的某一个属性时候会执行该方法
 *
 *  @param contactProperty 选中的属性
 */
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty
{
    NSLog(@"%s", __func__);
}

 

***iOS9之后无界面***

#import "AppDelegate.h"
#import <Contacts/Contacts.h>

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    // 1.获取授权状态
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    
    // 2.判断授权状态,如果是未决定请求授权
    if (status == CNAuthorizationStatusNotDetermined) {
        // 3.请求授权
        // 3.1.创建CNContactStore对象
        CNContactStore *store = [[CNContactStore alloc] init];
        
        // 3.2.请求授权
        [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (error) {
                NSLog(@"%@", error);
                return;
            }
            
            if (granted) {
                NSLog(@"授权成功");
            } else {
                NSLog(@"授权失败");
            }
        }];
    }
    
    return YES;
}

 

#import "ViewController.h"
#import <Contacts/Contacts.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 1.判断授权状态
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    if (status != CNAuthorizationStatusAuthorized) return;
    
    // 2.创建通信录对象
    CNContactStore *store = [[CNContactStore alloc] init];
    
    // 3.请求所有的联系人
    // 3.1.创建联系人请求对象,并且传入keys:你准备获取的信息(姓familyName名givenName 电话号码:phones)
    NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
    CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
    
    // 3.2.请求所有的联系人
    NSError *error = nil;
    [store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) { // 当遍历到一条记录就会执行该block
        // 4.获取联系人
        // 4.1.获取姓名
        NSString *firstName = contact.givenName;
        NSString *lastName = contact.familyName;
        NSLog(@"%@ %@", firstName, lastName);
        
        // 4.2.获取电话号码
        NSArray *phones = contact.phoneNumbers;
        for (CNLabeledValue *labelValue in phones) {
            NSString *phoneLabel = labelValue.label;
            CNPhoneNumber *phoneNumber = labelValue.value;
            NSString *phoneValue = phoneNumber.stringValue;
            NSLog(@"%@ %@", phoneLabel, phoneValue);
        }
    }];
}

 

 

 

posted @ 2015-10-10 17:28  淡墨寒  阅读(253)  评论(0)    收藏  举报