1.获取通讯录的方法在其他的博客中都有,我主要写一些我当时没有查到的。
2.编辑联系人
注意:我的编辑联系人用的是ABNewPersonViewController,这样就可以省掉联系人简介这一步
//编辑联系人
- (void)editButtonAction{
if (SYSTEM_VERSION <9.0f) {
NSLog(@"EDIT ios7,8");
//ABPersonViewController *personController=[[ABPersonViewController alloc]init];
ABNewPersonViewController *personController = [[ABNewPersonViewController alloc] init];
//设置联系人
ABAddressBookRef addressBook=ABAddressBookCreateWithOptions(NULL, NULL);
ABRecordRef recordRef= ABAddressBookGetPersonWithRecordID(addressBook, currentContactPerson.recordID);//取得id为1的联系人记录
personController.displayedPerson=recordRef;
//设置代理
// personController.personViewDelegate=self;
personController.newPersonViewDelegate = self;
//设置其他属性
//personController.allowsActions=YES;//是否显示发送信息、共享联系人等按钮
//personController.allowsEditing=YES;//允许编辑
// personController.displayedProperties=@[@(kABPersonFirstNameProperty),@(kABPersonLastNameProperty)];//显示的联系人属性信息,默认显示所有信息
personController.navigationItem.title = @"编辑联系人";
//使用导航控制器包装
UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:personController];
[self presentViewController:navigationController animated:YES completion:nil];
}else{
NSLog(@"EDIT ios9");
CNContactStore *store = [[CNContactStore alloc] init];
// 3.2.创建联系人的请求对象
// keys决定这次要获取哪些信息,比如姓名/电话
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactIdentifierKey, CNContactEmailAddressesKey, CNContactBirthdayKey, CNContactImageDataKey, CNContactPhoneNumbersKey, [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName], [CNContactViewController descriptorForRequiredKeys]]];
//CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:fetchKeys];
// 3.3.请求联系人
NSError *error = nil;
[store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
// stop是决定是否要停止
// 1.获取姓名
NSString *firstname = contact.givenName;
NSString *lastname = contact.familyName;
//NSLog(@"%@ %@", firstname, lastname);
//通过姓名寻找联系人
NSMutableString *fullName= [[NSMutableString alloc] init];
if (lastname!=nil||lastname.length>0) {
[fullName appendString:lastname];
}
if (firstname!=nil||firstname.length>0) {
[fullName appendString:firstname];
}
if ([fullName isEqualToString:currentContactPerson.fullName]) {
*stop = YES;
//CNContactViewController *controller = [CNContactViewController viewControllerForContact:contact];
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:contact];
controller.navigationItem.title = @"";
//代理内容根据自己需要实现
controller.delegate = self;
//4.跳转
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentViewController:navigation animated:YES completion:^{
}];
}
// 2.获取电话号码
NSArray *phones = contact.phoneNumbers;
// 3.遍历电话号码
for (CNLabeledValue *labelValue in phones) {
CNPhoneNumber *phoneNumber = labelValue.value;
// NSLog(@"%@ %@", phoneNumber.stringValue, labelValue.label);
}
}];
/*
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:contact];
//代理内容根据自己需要实现
controller.delegate = self;
//4.跳转
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentViewController:navigation animated:YES completion:^{
}];
*/
}
}
//ios7,8
#pragma mark - ABPersonViewController代理方法
//选择一个人员属性后触发,返回值YES表示触发默认行为操作,否则执行代理中自定义的操作
-(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
return YES;
/*
if (person) {
NSLog(@"选择了属性:%i,值:%@.",property,(__bridge NSString *)ABRecordCopyValue(person, property));
}
return NO;
*/
}
//ios7,8
#pragma mark - ABNewPersonViewController代理方法
//完成新增(点击取消和完成按钮时调用),注意这里不用做实际的通讯录增加工作,此代理方法调用时已经完成新增,当保存成功的时候参数中得person会返回保存的记录,如果点击取消person为NULL
-(void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person{
//如果有联系人信息
if (person) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self loadPerson];
dispatch_sync(dispatch_get_main_queue(), ^{
//刷新列表
[contactTableView reloadData];
});
});
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshDialContact" object:nil];
NSLog(@"%@ 信息保存成功.",(__bridge NSString *)(ABRecordCopyCompositeName(person)));
}else{
NSLog(@"点击了取消.");
}
//关闭模态视图窗口
[self dismissViewControllerAnimated:YES completion:nil];
}
//iOS9
#pragma mark - CNContactViewControllerDelegate
- (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(nullable CNContact *)contact{
if(contact){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self loadPerson];
dispatch_sync(dispatch_get_main_queue(), ^{
//刷新列表
[contactTableView reloadData];
});
});
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshDialContact" object:nil];
}
[viewController dismissViewControllerAnimated:YES completion:^{
}];
}
3.新建联系人和添加到现有联系人
//保存到现有联系人实现
- (void)saveExistContact{
if (SYSTEM_VERSION < 9.0f) {
NSLog(@"save exist contact ios7,8");
ABPeoplePickerNavigationController *peoplePickerController=[[ABPeoplePickerNavigationController alloc]init];
//设置代理
peoplePickerController.peoplePickerDelegate=self;
if(SYSTEM_VERSION >= 8.0f){
peoplePickerController.predicateForSelectionOfPerson = [NSPredicate predicateWithValue:false]; }
[self presentViewController:peoplePickerController animated:YES completion:nil];
}else{
NSLog(@"save exist contact ios9");
//1.跳转到联系人选择页面,注意这里没有使用UINavigationController
CNContactPickerViewController *controller = [[CNContactPickerViewController alloc] init];
controller.delegate = self;
[self presentViewController:controller animated:YES completion:^{
}];
}
}
//新建联系人
- (void)addNewPerson
{
if(SYSTEM_VERSION < 9.0f){
NSLog(@"create ios7,8");
CFErrorRef error = NULL;
// Create New Contact
ABRecordRef person = ABPersonCreate ();
// Add phone number
ABMutableMultiValueRef multiValue =
ABMultiValueCreateMutable(kABStringPropertyType);
//mainTitle.text是你要添加的手机号
ABMultiValueAddValueAndLabel(multiValue, (__bridge CFTypeRef)(mainTitle.text), kABPersonPhoneMainLabel,
NULL);
ABRecordSetValue(person, kABPersonPhoneProperty, multiValue, &error);
ABNewPersonViewController *newPersonCtrl = [[ABNewPersonViewController alloc] init];
newPersonCtrl.newPersonViewDelegate = self;
newPersonCtrl.displayedPerson = person;
CFRelease(person); // TODO check
UINavigationController *navCtrl = [[UINavigationController alloc]
initWithRootViewController:newPersonCtrl];
navCtrl.navigationBar.barStyle = UIBarStyleBlackOpaque;
[self.parentViewController presentModalViewController:navCtrl animated:YES];
}else{
//ios9
NSLog(@"create ios9");
//1.创建Contact对象,必须是可变的
CNMutableContact *contact = [[CNMutableContact alloc] init];
//2.为contact赋值,这块比较恶心,很混乱,setValue4Contact中会给出常用值的对应关系
[self setValue4Contact:contact existContect:NO];
//3.创建新建好友页面
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:contact];
//代理内容根据自己需要实现
controller.delegate = self;
//4.跳转
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentViewController:navigation animated:YES completion:^{
}];
}
}
//设置要保存的contact对象
- (void)setValue4Contact:(CNMutableContact *)contact existContect:(BOOL)exist{
if (!exist) {
//名字和头像
contact.nickname = @"";
// UIImage *logo = [UIImage imageNamed:@"..."];
// NSData *dataRef = UIImagePNGRepresentation(logo);
// contact.imageData = dataRef;
}
//电话,每一个CNLabeledValue都是有讲究的,如何批评,可以在头文件里面查找,这里给出几个常用的,别的我也不愿意去研究
CNLabeledValue *phoneNumber = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMobile value:[CNPhoneNumber phoneNumberWithStringValue:mainTitle.text]];
if (!exist) {
contact.phoneNumbers = @[phoneNumber];
}
//现有联系人情况
else{
if ([contact.phoneNumbers count] >0) {
NSMutableArray *phoneNumbers = [[NSMutableArray alloc] initWithArray:contact.phoneNumbers];
[phoneNumbers addObject:phoneNumber];
contact.phoneNumbers = phoneNumbers;
}else{
contact.phoneNumbers = @[phoneNumber];
}
}
//网址:CNLabeledValue *url = [CNLabeledValue labeledValueWithLabel:@"" value:@""];
//邮箱:CNLabeledValue *mail = [CNLabeledValue labeledValueWithLabel:CNLabelWork value:self.poiData4Save.mail];
//特别说一个地址,PostalAddress对应的才是地址
CNMutablePostalAddress *address = [[CNMutablePostalAddress alloc] init];
address.state = @"";
address.city = @"";
address.postalCode = @"";
//外国人好像都不强调区的概念,所以和具体地址拼到一起
address.street = @"";
//生成的上面地址的CNLabeledValue,其中可以设置类型CNLabelWork等等
CNLabeledValue *addressLabel = [CNLabeledValue labeledValueWithLabel:CNLabelWork value:address];
if (!exist) {
contact.postalAddresses = @[addressLabel];
}else{
if ([contact.postalAddresses count] >0) {
NSMutableArray *addresses = [[NSMutableArray alloc] initWithArray:contact.postalAddresses];
[addresses addObject:addressLabel];
contact.postalAddresses = addresses;
}else{
contact.postalAddresses = @[addressLabel];
}
}
}
//iOS9
#pragma mark - CNContactViewControllerDelegate
- (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(nullable CNContact *)contact{
if (contact) {
//异步获取通讯录信息
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self loadPerson];
dispatch_sync(dispatch_get_main_queue(), ^{
[phoneBookTableView reloadData];
});
});
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshContact" object:nil];
}
[viewController dismissViewControllerAnimated:YES completion:^{
}];
}
#pragma mark - CNContactPickerDelegate
//2.实现点选的代理,其他代理方法根据自己需求实现
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{
[picker dismissViewControllerAnimated:YES completion:^{
//3.copy一份可写的Contact对象,不要尝试alloc一类,mutableCopy独此一家
CNMutableContact *c = [contact mutableCopy];
//4.为contact赋值
[self setValue4Contact:c existContect:YES];
//5.跳转到新建联系人页面
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:c];
controller.delegate = self;
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentViewController:navigation animated:YES completion:^{
}];
}];
}
#pragma mark ABNewPersonViewControllerDelegate
- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController
didCompleteWithNewPerson:(ABRecordRef)person
{
if (person) {
//异步获取通讯录信息
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self loadPerson];
dispatch_sync(dispatch_get_main_queue(), ^{
[phoneBookTableView reloadData];
});
});
//更新通讯录界面的数据
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshContact" object:nil];
}
[newPersonViewController dismissViewControllerAnimated:YES completion:^{
}];
}
#pragma mark ABPeoplePickerNavigationControllerDelegate
// Called after a property has been selected by the user.
//ios8
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person NS_AVAILABLE_IOS(8_0){
[self peoplePickerNavigationController:peoplePicker shouldContinueAfterSelectingPerson:person];
}
#pragma mark ABPeoplePickerNavigationControllerDelegate
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
CFErrorRef error = NULL;
BOOL status;
ABMutableMultiValueRef multiValue;
// Inserer le numéro dans la fiche de la personne
// Add phone number
CFTypeRef typeRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
if (ABMultiValueGetCount(typeRef) == 0)
multiValue = ABMultiValueCreateMutable(kABStringPropertyType);
else
multiValue = ABMultiValueCreateMutableCopy (typeRef);
// TODO type (mobile, main...)
// TODO manage URI
status = ABMultiValueAddValueAndLabel(multiValue, (__bridge CFTypeRef)mainTitle.text, kABPersonPhoneMainLabel,
NULL);
status = ABRecordSetValue(person, kABPersonPhoneProperty, multiValue, &error);
status = ABAddressBookSave(peoplePicker.addressBook, &error);
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshContact" object:nil];
[peoplePicker dismissModalViewControllerAnimated:YES];
return NO;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
//点击取消按钮
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{
[peoplePicker dismissModalViewControllerAnimated:YES];
NSLog(@"取消选择.");
}