iOS系统通讯录授权,获取,修改,创建联系人

来源:互联网 发布:mac jenkins android 编辑:程序博客网 时间:2024/06/07 14:02

1、现在的很多应用程序中都会设计到手机系统通讯录的问题,下面就简单介绍一下iOS系统通讯录的
2、iOS9之前的系统通讯录有2个框架,分别是AddressBookUI/AddressBookUI.h // 系统带UI通讯录, AddressBook/AddressBook.h // 系统通讯录,需要自己手动搭建页面,
3、 AddressBookUI/AddressBookUI.h // 系统带UI通讯录,不用自己搭建页面,直接调用系统的就可以了,

ABPeoplePickerNavigationController *vc = [[ABPeoplePickerNavigationController alloc] init];    vc.peoplePickerDelegate = self;    [self presentViewController:vc animated:YES completion:nil];

遵守代理ABPeoplePickerNavigationControllerDelegate,并实现代理方法:

// ios7- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{    NSLog(@"111111");    [peoplePicker dismissViewControllerAnimated:YES completion:nil];}// 在iOS7中选中一个联系人就会调用// 返回一个BOOL值,NO代表不会进入到下一层(详情),YES代表会进入到下一层- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{    return NO;}// ios8选中一个联系人就会调用 实现这个方法之后,控制器不会进入到下一层(详情),直接dismiss//- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person{//    NSLog(@"2222");//}// ios8选中某一个联系人的某一个属性时就会调用- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{    NSLog(@"%@,%d,@%d",person,property,identifier);}

这样的话,就能够直接利用系统的通讯录界面进行操作了,但是有一点就是,不能在界面上操作需求。

4、获取联系人。
AddressBook/AddressBook.h // 系统通讯录,需要自己手动搭建页面,这个框架只能够通过手动拿到联系人数据,然后自己搭建界面展示数据,并可以进行其他的需求操作。

(1)为了更方便的展示数据,首先创建person模型类:PeopleModel

#import <UIKit/UIKit.h>@interface PeopleModel : NSObject@property (nonatomic, copy) NSString *name; // 姓名@property (nonatomic, copy) NSString *email; // 邮箱@property (nonatomic, copy) NSString *tellPhone; // 电话@property (nonatomic, strong) UIImage *iconImage; // 联系人头像@property (nonatomic, assign) NSInteger sectionNumber; // section标题(用于按某一个属性排序,比如按照name排序)@end

从通讯录中获取所有的联系人,并转换成person模型类,
(2)首先创建数据源,数据源一定要初始化,很多时候忘记初始化数据源会导致看不到数据,

@property (nonatomic ,retain) NSMutableArray *peoplePhoneData; // 用来存储联系人(分组)// self.peoplePhoneData = [NSMutableArray array]; // 记得初始化数据源(这里就不用懒加载了)

(3)取得通讯录授权:程序在第一次使用的时候,会请求用户的授权,如果用户同意了,就加载数据,拒绝了,就给提示。如果不是第一次使用通讯录,就不再提示授权的提示框,但程序同样要走到下面的请求函数,这时系统会自动识别授权状态,granted=1,就是已经授权的,granted=0就是拒绝授权或者其他的,总之只有同意授权才可以拿数据的。

CFErrorRef *error = nil;    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(nil, error);    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {        NSLog(@"granted==%d",granted);        if (granted) {            NSLog(@"授权成功!");            [self getUpAddBookViewPersonDataWithAddBook:addressBook];        } else {            NSLog(@"授权失败!");            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"授权失败" message:@"请在设置中打开访问权限" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];            [alert show];        }    });

获取授权状态也可以用ABAddressBookGetAuthorizationStatus()获取授权状态,

kABAuthorizationStatusNotDetermined = 0, // 还没有决定是否授权(就是在第一次提示授权的时候)
kABAuthorizationStatusRestricted, // 有其他限制通讯录授权的状态
kABAuthorizationStatusDenied, // 拒绝授权
kABAuthorizationStatusAuthorized // 同意授权
(4)获取所有联系人并按照拼音排序(效果就是系统通讯录的排序效果),都是c语言的语法,与oc转化的时候是通过__bridge(桥接)来互相转换的

// 获取所有联系人并存储- (void)getUpAddBookViewPersonDataWithAddBook:(ABAddressBookRef)addressBook{    // 获取所有联系人并存储    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);    CFIndex peolpeCount = ABAddressBookGetPersonCount(addressBook); // 获取联系人个数    NSMutableArray *peopleArray = [NSMutableArray array]; // 用来存储联系人模型    // 获取联系人信息(将联系人转模型)    for (NSInteger i = 0; i < peolpeCount; i++)    {        PeopleModel *model = [[PeopleModel alloc] init];        ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i); // 获取某一个联系人        CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);        CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);        CFStringRef fullName = ABRecordCopyCompositeName(person);//         取出个人记录中的详细信息//        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);        // 读取name        NSString *firstNameStr = (__bridge NSString *)firstName;        NSString *lastNameStr = (__bridge NSString *)lastName;        NSString *fullNameStr = (__bridge NSString *)fullName;        if ( fullNameStr.length != 0) {            firstNameStr = fullNameStr;        } else if (lastNameStr.length!=0) {            firstNameStr = [NSString stringWithFormat:@"%@ %@",firstNameStr,lastNameStr];        }        model.name = firstNameStr;        // 读取邮箱        ABMultiValueRef email = ABRecordCopyValue(person, kABPersonEmailProperty);        NSInteger emailCount = ABMultiValueGetCount(email);        for (NSInteger i = 0; i < emailCount; i++) {            model.email = (__bridge NSString *)ABMultiValueCopyValueAtIndex(email, i);        }        // 读取电话        ABMultiValueRef tellPhone = ABRecordCopyValue(person, kABPersonPhoneProperty);        for (NSInteger i = 0; i < ABMultiValueGetCount(tellPhone); i++) {            model.tellPhone = (__bridge NSString *)ABMultiValueCopyValueAtIndex(tellPhone, i);        }//        for (NSInteger i = 0; i < ABMultiValueGetCount(tellPhone); i++) {////            获取复杂属性的方法//            // 电话标签//            CFStringRef phoneLabel = ABMultiValueCopyLabelAtIndex(tellPhone, i);//            // 本地化电话标签//            CFStringRef phoneLocalLabel = ABAddressBookCopyLocalizedLabel(phoneLabel);//            // 电话号码 //            CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(tellPhone, i);//        }        // 读取联系人头像        NSData *iconData = (__bridge NSData *)ABPersonCopyImageData(person);        model.iconImage = [UIImage imageWithData:iconData];        [peopleArray addObject:model];        if (firstName) {            CFRelease(firstName);        }        if (lastName) {            CFRelease(lastName);        }        if (fullName) {            CFRelease(fullName);        }        CFRelease(email);        CFRelease(tellPhone);    }    // 排序    UILocalizedIndexedCollation *theCollation = [UILocalizedIndexedCollation currentCollation];    for (PeopleModel *model in peopleArray) {        NSInteger sect = [theCollation sectionForObject:model                                collationStringSelector:@selector(name)]; // 根据模型的name字断排序        model.sectionNumber = sect;    }    NSInteger highSection = [[theCollation sectionTitles] count];    NSMutableArray *sectionArrays = [NSMutableArray arrayWithCapacity:highSection];    for (int i=0; i<=highSection; i++) {        NSMutableArray *sectionArray = [NSMutableArray arrayWithCapacity:1];        [sectionArrays addObject:sectionArray];    }    for (PeopleModel *model in peopleArray) {        [(NSMutableArray *)[sectionArrays objectAtIndex:model.sectionNumber] addObject:model];    }    // 排好序的联系人加入数组中    for (NSMutableArray *sectionArray in sectionArrays) {        int count = 0; // 统计name为nil的个数        for (PeopleModel *model in sectionArray) {            if (model.name.length==0) {                count++;            }        }        NSArray *sortedSection = [NSArray array];        //        NSArray *sortedSection = [theCollation sortedArrayFromArray:sectionArray collationStringSelector:@selector(name)];        if (count >= 2) { // 有2个以上name为nil,            sortedSection = [NSArray arrayWithArray:sectionArray];        } else {            sortedSection = [theCollation sortedArrayFromArray:sectionArray collationStringSelector:@selector(name)];        }        [self.peoplePhoneData addObject:sortedSection];    }    [self.tableView reloadData];}

在iOS的通讯录中的联系人的名字是有好几个的(firstName,lastName,fullName),所有按照需求来操作,并且手机号,邮箱都是有多个的,所有这些需求就需要按照设计需求来做了。

(5)索引实现。

// 索引序列- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{    tableView.sectionIndexColor = [UIColor redColor];    tableView.sectionIndexBackgroundColor=[UIColor clearColor];    NSArray * array=[[NSArray arrayWithObject:@"★"] arrayByAddingObjectsFromArray:[[UILocalizedIndexedCollation currentCollation] sectionIndexTitles]];    return [[NSArray arrayWithObject:UITableViewIndexSearch] arrayByAddingObjectsFromArray:array];}

(6)section title
- (NSString )tableView:(UITableView )tableView titleForHeaderInSection:(NSInteger)section
{

NSString *title = [self.peoplePhoneData[section] count] ? [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section]:nil;return title;

}

5、修改联系人

// 修改联系人- (void)updateRecod{    // 1. 拿到通讯录    ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);    // 获取通讯录所有人    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(book);    // 拿到通讯录中的某一个联系人    ABRecordRef people = CFArrayGetValueAtIndex(allPeople, 0);    // 修改联系人信息    ABRecordSetValue(people, kABPersonLastNameProperty, @"Li", NULL);    // 保存通讯录    ABAddressBookSave(book, NULL);//    ABPersonHasImageData(people); // 判断通讯录中的联系人是否有图片//    ABPersonSetImageData(people, <#CFDataRef imageData#>, <#CFErrorRef *error#>); // 设置联系人的图片数据//    ABAddressBookRemoveRecord(<#ABAddressBookRef addressBook#>, <#ABRecordRef record#>, <#CFErrorRef *error#>) // 删除某一个联系人//    ABAddressBookRevert(<#ABAddressBookRef addressBook#>) // 放弃更改信息//    ABAddressBookHasUnsavedChanges(<#ABAddressBookRef addressBook#>) // 函数判断是否有未保存的修改}

5、添加新的联系人

// 添加联系人- (void)creadRecod{    // 1. 创建联系人    ABRecordRef people = ABPersonCreate();    // 2. 设置联系人信息    ABRecordSetValue(people, kABPersonLastNameProperty, @"san", NULL);    ABRecordSetValue(people, kABPersonFirstNameProperty, @"zhang", NULL);    // 创建电话号码    ABMultiValueRef phones = ABMultiValueCreateMutable(kABMultiStringPropertyType);    ABMultiValueAddValueAndLabel(phones, @"123456789", kABPersonPhoneMainLabel, NULL);    ABMultiValueAddValueAndLabel(phones, @"888888", kABPersonPhoneHomeFAXLabel, NULL);    ABRecordSetValue(people, kABPersonPhoneProperty, phones, NULL);    // 3. 拿到通讯录    ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);    // 4. 将联系人添加到通讯录中    ABAddressBookAddRecord(book, people, NULL);    // 5. 保存通讯录    ABAddressBookSave(book, NULL);}

6、联系人的操作基本上就那么多了,有一些属性值是没有涉及到的,但是基本的操作方法都差不多。但是在iOS9之后,系统的通讯录框架改成了 ContactsUI/ContactsUI.h,这个后期会研究一下,并发表出来。

0 0
原创粉丝点击