首页 > 代码库 > 【iOS开发-114】ABAddressBook通讯录:增删改查的简单介绍,CF框架于F框架间的转换

【iOS开发-114】ABAddressBook通讯录:增删改查的简单介绍,CF框架于F框架间的转换

(1)导入ABAddressBook库,然后添加头文件后,就可以使用。

——因为这个库的方法基本是C语言的风格,所以类基本是以CF开头的,比如CFStringRef以及CFArrayRef,它和OC的NSString和NSArray类似,可以相互转换,利用__bridge来强制转换,如(__bridge NSString *)XXX,就可以把原本是CFStringRef的XXX转换成NSString类型,这样做的好处就是不需要在很多地方进行释放操作CFRelease()。

——使用通讯录,首先需要发送访问请求,得到请求后,才可以进行一系列操作,访问请求的方法是ABAddressBookRequestAccessWithCompletion,而建议在后续执行一些通讯录操作前可以判断此时我们访问的授权是否还存在,如果用户更改了授权,我们就不必进一步操作,而判断的方法是:

//点击之前,先判断是否被允许
if (ABAddressBookGetAuthorizationStatus()!=kABAuthorizationStatusAuthorized) return;

——除了查询,增加、修改、删除,都需要最终保存通讯录,相当于做一次更新操作。

//保存
ABAddressBookSave(bookRef, NULL);

——删除操作是:

ABAddressBookRemoveRecord(bookRef, people, NULL);


主要代码如下:

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

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //创建3个按钮
    UIButton *btnAccess=[[UIButton alloc]init];
    btnAccess.frame=CGRectMake(20, 40, 280, 30);
    [btnAccess setTitle:@"访问联系人" forState:UIControlStateNormal];
    [btnAccess setBackgroundColor:[UIColor blueColor]];
    [btnAccess addTarget:self action:@selector(btnAccessClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnAccess];
    
    UIButton *btnUpdate=[[UIButton alloc]init];
    btnUpdate.frame=CGRectMake(20, 80, 280, 30);
    [btnUpdate setTitle:@"更改联系人" forState:UIControlStateNormal];
    [btnUpdate setBackgroundColor:[UIColor blueColor]];
    [btnUpdate addTarget:self action:@selector(btnUpdateClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnUpdate];
    
    UIButton *btnAdd=[[UIButton alloc]init];
    btnAdd.frame=CGRectMake(20, 120, 280, 30);
    [btnAdd setTitle:@"增加联系人" forState:UIControlStateNormal];
    [btnAdd setBackgroundColor:[UIColor blueColor]];
    [btnAdd addTarget:self action:@selector(btnAddClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnAdd];
    
    //发送访问通讯录请求
    ABAddressBookRef bookRef=ABAddressBookCreateWithOptions(NULL, NULL);
    ABAddressBookRequestAccessWithCompletion(bookRef, ^(bool granted, CFErrorRef error) {
        if (granted) {
            NSLog(@"可访问");
        }else{
            NSLog(@"不可访问");
        }
    });
    //C语言里create、copy、retain都可以用下面这个来释放
    CFRelease(bookRef);
}

-(void)btnAccessClick{
    //因为是CF框架Core Foundation,所以是C语言的,需要用很多CF类,而且需要释放
//    [self btnAccessClickWithC];
    //部分CF类可以直接用__bridge强制转换成NS类,如数组、字符等,好处是不需要释放
    //在两个框架之间转换用__bridge
    [self btnAccessClickWithOC];
}

-(void)btnAccessClickWithC{
    //点击之前,先判断是否被允许
    if (ABAddressBookGetAuthorizationStatus()!=kABAuthorizationStatusAuthorized) return;
    //获得允许后,获取通讯录里的数据
    ABAddressBookRef bookRef=ABAddressBookCreateWithOptions(NULL, NULL);
    CFArrayRef allPeople=ABAddressBookCopyArrayOfAllPeople(bookRef);
    CFIndex count=CFArrayGetCount(allPeople);
    for (CFIndex i=0; i<count; i++) {
        ABRecordRef people=CFArrayGetValueAtIndex(allPeople, i);
        CFStringRef firstName=ABRecordCopyValue(people, kABPersonFirstNameProperty);
        CFStringRef lastName=ABRecordCopyValue(people, kABPersonLastNameProperty);
        NSLog(@"%@,%@",lastName,firstName);
        
        ABMultiValueRef phone=ABRecordCopyValue(people, kABPersonPhoneProperty);
        CFArrayRef phones=ABMultiValueCopyArrayOfAllValues(phone);
        CFIndex countPhone=CFArrayGetCount(phones);
        for (int j=0; j<countPhone; j++) {
            CFStringRef phoneType=ABMultiValueCopyLabelAtIndex(phone, j);
            CFStringRef phoneNum=ABMultiValueCopyValueAtIndex(phone, j);
            NSLog(@"%@-%@",phoneType,phoneNum);
            //释放
            CFRelease(phoneType);
            CFRelease(phoneNum);
        }
        //释放
        CFRelease(firstName);
        CFRelease(lastName);
        CFRelease(phones);
        CFRelease(phone);
    }
    //释放
    CFRelease(allPeople);
    //释放
    CFRelease(bookRef);
}

-(void)btnAccessClickWithOC{
    //点击之前,先判断是否被允许
    if (ABAddressBookGetAuthorizationStatus()!=kABAuthorizationStatusAuthorized) return;
    //获得允许后,获取通讯录里的数据
    ABAddressBookRef bookRef=ABAddressBookCreateWithOptions(NULL, NULL);
    NSArray *allPeople=(__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(bookRef);
    for (int i=0; i<allPeople.count; i++) {
        ABRecordRef people=(__bridge ABRecordRef)allPeople[i];
        NSString *firstName=(__bridge NSString *)ABRecordCopyValue(people, kABPersonFirstNameProperty);
        NSString *lastName=(__bridge NSString *)ABRecordCopyValue(people, kABPersonLastNameProperty);
        NSLog(@"%@,%@",lastName,firstName);
        
        ABMultiValueRef phone=ABRecordCopyValue(people, kABPersonPhoneProperty);
        NSArray *phones=(__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phone);
        for (int j=0; j<phones.count; j++) {
            NSString *phoneType=(__bridge NSString *)ABMultiValueCopyLabelAtIndex(phone, j);
            NSString *phoneNum=(__bridge NSString *)ABMultiValueCopyValueAtIndex(phone, j);
            NSLog(@"%@-%@",phoneType,phoneNum);
        }
        //释放
        CFRelease(phone);
    }
    //释放
    CFRelease(bookRef);
}

-(void)btnUpdateClick{
    //点击之前,先判断是否被允许
    if (ABAddressBookGetAuthorizationStatus()!=kABAuthorizationStatusAuthorized) return;
    //获得允许后,获取通讯录里的数据
    ABAddressBookRef bookRef=ABAddressBookCreateWithOptions(NULL, NULL);
    NSArray *allPeople=(__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(bookRef);
    //拿到第1条数据
    ABRecordRef people=(__bridge ABRecordRef)allPeople[0];
    //修改
    ABRecordSetValue(people, kABPersonLastNameProperty, ((__bridge CFStringRef)@"司马"), NULL);
    //所有的增删改最终都需要调用save保存方法
    ABAddressBookSave(bookRef, NULL);
    //释放
    CFRelease(bookRef);
}

-(void)btnAddClick{
    //点击之前,先判断是否被允许
    if (ABAddressBookGetAuthorizationStatus()!=kABAuthorizationStatusAuthorized) return;
    //获得允许后,获取通讯录,需要把联系人加到这个通讯录里,所以需要创建这个
    ABAddressBookRef bookRef=ABAddressBookCreateWithOptions(NULL, NULL);
    //创建一个联系人
    ABRecordRef people=ABPersonCreate();
    //设置联系人的数据
    ABRecordSetValue(people, kABPersonLastNameProperty, ((__bridge CFStringRef)@"诸葛"), NULL);
    ABRecordSetValue(people, kABPersonFirstNameProperty, ((__bridge CFStringRef)@"亮"), NULL);
    
    ABMultiValueRef phone=ABMultiValueCreateMutable(kABMultiStringPropertyType);
    ABMultiValueAddValueAndLabel(phone, ((__bridge CFStringRef)@"10086"), kABPersonPhoneMainLabel, NULL);
    ABMultiValueAddValueAndLabel(phone, ((__bridge CFStringRef)@"13514678920"), kABPersonPhoneMobileLabel, NULL);
    ABRecordSetValue(people, kABPersonPhoneProperty, phone, NULL);
    
    //添加联系人
    ABAddressBookAddRecord(bookRef, people, NULL);
    
    //保存
    ABAddressBookSave(bookRef, NULL);
    
    //释放
    CFRelease(phone);
    CFRelease(people);
    CFRelease(bookRef);
}

@end


【iOS开发-114】ABAddressBook通讯录:增删改查的简单介绍,CF框架于F框架间的转换