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,这个后期会研究一下,并发表出来。
- iOS系统通讯录授权,获取,修改,创建联系人
- IOS获取系统通讯录联系人信息
- IOS获取系统通讯录联系人信息
- IOS获取系统通讯录联系人信息
- IOS获取系统通讯录联系人信息
- iOS 调用系统通讯录 获取联系人信息
- iOS 获取系统通讯录联系人信息
- iOS 获取通讯录联系人信息
- iOS 通讯录-获取联系人属性
- iOS 通讯录-获取联系人属性
- iOS 获取通讯录联系人信息
- iOS获取通讯录联系人信息
- iOS获取通讯录联系人信息
- iOS获取通讯录联系人信息
- iOS获取通讯录联系人信息
- ios 通讯录 获取分组以及各组联系人
- iOS 获取通讯录联系人信息并展示
- iOS开发:通讯录联系人获取相关
- 【Stanford机器学习笔记】4-Regularization for Solving the Problem of Overfitting
- Java封装(修饰符+包+内部类)
- storyBoard正传逆传代理解耦
- Light Oj 1284 Lights inside 3D Grid(概率期望)
- 递归反转字符串
- iOS系统通讯录授权,获取,修改,创建联系人
- 优化Innodb存储引擎
- 使用CMD/PowerShell调用7-Zip压缩文件夹
- 【翻译自mos文章】怎么获得Oracle Database 12c中的audit session id
- [可并堆] BZOJ 1078 [SCOI2008]斜堆
- 1024. 科学计数法 (20)
- 在PowerShell中巧用$OFS
- 查看当前Linux内核配置文件/proc/config.gz
- 对象初始化总结