抓取通讯录

#import <ContactsUI/ContactsUI.h>
#import <Contacts/Contacts.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import <AddressBook/ABPerson.h>

添加代理方法

<CNContactPickerDelegate,ABPeoplePickerNavigationControllerDelegate>

iOS9.0以后用的方法

pragma mark - 点击某个联系人的某个属性(property)时触发并返回该联系人属性(contactProperty)。

//只实现该方法时,可以进入到联系人详情页面(如果predicateForSelectionOfProperty属性没被设置或符合筛选条件,如不符合会触发默认操作,即打电话,发邮件等)。

- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty  API_AVAILABLE(ios(9.0)){
    NSLog(@"%@",contactProperty);
    CNContact *contact = contactProperty.contact;
    NSLog(@"givenName: %@, familyName: %@", contact.givenName, contact.familyName);
    //    self.nameTextView.text = [NSString stringWithFormat:@"%@%@",contact.familyName,contact.givenName];
    if (![contactProperty.value isKindOfClass:[CNPhoneNumber class]]) {
        //        [[HNPublicTool shareInstance] showHudErrorMessage:@"请选择11位手机号"];
        return;
    }
    CNPhoneNumber *phoneNumber = contactProperty.value;
    NSString *phoneStr = [self RemoveSpecialCharacters:phoneNumber.stringValue];
    NSLog(@"号码:%@",phoneStr);
    if ([self valiMobile:phoneStr]) {
        BasicInfoAndContactsModel *model = self.dataMutArray[self.indexPath.row];
        model.subTitle = phoneStr;
        [self.tableView reloadData];
    }else{
        [Utils showToast:@"手机号码不正确,请重新选择."];
    }
    
}

//请求通讯录权限

pragma mark 请求通讯录权限

- (void)requestContactAuthorAfterSystemVersion9{
    
    if (@available(iOS 9.0, *)) {
        CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
        if (status == CNAuthorizationStatusNotDetermined) {
            CNContactStore *store = [[CNContactStore alloc] init];
            [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError*  _Nullable error) {
                if (error) {
                    NSLog(@"授权失败");
                }else {
                    NSLog(@"成功授权");
                    CNContactPickerViewController *contactPickerViewController = [[CNContactPickerViewController alloc] init];
                    contactPickerViewController.delegate = self;
                    contactPickerViewController.displayedPropertyKeys = @[CNContactPhoneNumbersKey];
                    [self presentViewController:contactPickerViewController animated:YES completion:nil];
                    
                    [self openContact];
                }
            }];
        }
        else if(status == CNAuthorizationStatusRestricted)
        {
            NSLog(@"用户拒绝");
            [self showAlertViewAboutNotAuthorAccessContact];
        }
        else if (status == CNAuthorizationStatusDenied)
        {
            NSLog(@"用户拒绝");
            [self showAlertViewAboutNotAuthorAccessContact];
        }
        else if (status == CNAuthorizationStatusAuthorized)//已经授权
        {
            //有通讯录权限-- 进行下一步操作
            CNContactPickerViewController *contactPickerViewController = [[CNContactPickerViewController alloc] init];
            contactPickerViewController.delegate = self;
            contactPickerViewController.displayedPropertyKeys = @[CNContactPhoneNumbersKey];
            [self presentViewController:contactPickerViewController animated:YES completion:nil];
            
            [self openContact];
        }
        
    } else {
        // Fallback on earlier versions
        [self requestAuthorizationAddressBook];
    }
    
}

//有通讯录权限-- 进行下一步操作

- (void)openContact{
    [self.phoneBookMutArray removeAllObjects];
    // 获取指定的字段,并不是要获取所有字段,需要指定具体的字段
    if (@available(iOS 9.0, *)) {
        NSArray *keysToFetch = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
        CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch];
        CNContactStore *contactStore = [[CNContactStore alloc] init];
        
        [contactStore enumerateContactsWithFetchRequest:fetchRequest error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
            NSLog(@"-------------------------------------------------------");
            
            NSString *givenName = contact.givenName;
            NSString *familyName = contact.familyName;
            NSLog(@"givenName=%@, familyName=%@", givenName, familyName);
            //拼接姓名
            NSString *nameStr = [NSString stringWithFormat:@"%@%@",[Utils strIsNil:contact.familyName] ? @"" : contact.familyName,[Utils strIsNil:contact.givenName] ? @"" : contact.givenName];
            
            NSArray *phoneNumbers = contact.phoneNumbers;
            NSMutableArray *phoneArray = [NSMutableArray array];
            for (CNLabeledValue *labelValue in phoneNumbers) {
                //遍历一个人名下的多个电话号码
                //            NSString *label = labelValue.label;
                //            NSString *    phoneNumber = labelValue.value;
                CNPhoneNumber *phoneNumber = labelValue.value;
                
                NSString * string = [self RemoveSpecialCharacters:phoneNumber.stringValue] ;
                [phoneArray addObject:string];
                NSLog(@"姓名=%@, 电话号码是=%@", nameStr, string);
            }
            NSDictionary *dict = @{
                                   @"name" : nameStr,
                                   @"phones" : phoneArray
                                   };
            [self.phoneBookMutArray addObject:dict];
            //    *stop = YES; // 停止循环,相当于break;
            
        }];
    } else {
        // Fallback on earlier versions
    }
    
    
}

//提示没有通讯录权限

- (void)showAlertViewAboutNotAuthorAccessContact{
    
    UIAlertController *alertController = [UIAlertController
                                          alertControllerWithTitle:@"请授权通讯录权限"
                                          message:@"请在iPhone的\"设置-隐私-通讯录\"选项中,允许APP访问你的通讯录"
                                          preferredStyle: UIAlertControllerStyleAlert];
    
    UIAlertAction *OKAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];
    [alertController addAction:OKAction];
    [self presentViewController:alertController animated:YES completion:nil];
}

pragma mark - 系统8.0通讯录方法

- (void)requestAuthorizationAddressBook {//系统8.0请求通讯录权限
    __weak typeof(self)weakSelf = self;
    ABAddressBookRef bookref = ABAddressBookCreateWithOptions(NULL, NULL);
    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
    /*kABAuthorizationStatusNotDetermined = 0,    // 未进行授权选择
     kABAuthorizationStatusRestricted,           // 未授权,且用户无法更新,如家长控制情况下
     kABAuthorizationStatusDenied,               // 用户拒绝App使用
     kABAuthorizationStatusAuthorized            // 已授权,可使用*/
    if (status == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(bookref, ^(bool granted, CFErrorRef error) {
            if (error) {
                NSLog(@"授权错误");
            }
            if (granted) {
                NSLog(@"授权chengg");
                ABPeoplePickerNavigationController *peosonVC = [[ABPeoplePickerNavigationController alloc] init];
                peosonVC.peoplePickerDelegate = weakSelf;
                peosonVC.displayedProperties = @[[NSNumber numberWithInt:kABPersonPhoneProperty]];
                [weakSelf presentViewController:peosonVC animated:YES completion:nil];
                [self getAllPeoplePhoneNumber];
            }
        });
    }
    if (status == kABAuthorizationStatusAuthorized) {
        ABPeoplePickerNavigationController *peosonVC = [[ABPeoplePickerNavigationController alloc] init];
        peosonVC.peoplePickerDelegate = weakSelf;
        peosonVC.displayedProperties = @[[NSNumber numberWithInt:kABPersonPhoneProperty]];
        [weakSelf presentViewController:peosonVC animated:YES completion:nil];
        [self getAllPeoplePhoneNumber];
    }else
    {
//        @"您未开启通讯录权限,请前往设置中心开启"];
        UIAlertView * alart = [[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"请您设置允许APP访问您的通讯录\n设置-隐私-通讯录" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        [alart show];
    }
    
}

pragma mark - ios8走这个 选中联系人的某个属性的时候调用

- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    // 获取该联系人多重属性--电话号
    ABMutableMultiValueRef phoneMulti = ABRecordCopyValue(person, kABPersonPhoneProperty);
    
    // 获取该联系人的名字,简单属性,只需ABRecordCopyValue取一次值
    ABMutableMultiValueRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSString *firstname = (__bridge NSString *)(firstName);
    ABMutableMultiValueRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
    NSString *lastname = (__bridge NSString *)(lastName);
    // 获取点击的联系人的电话
    NSLog(@"联系人名字 : %@%@",lastname,firstname);
    
    // 点击某个联系人电话后dismiss联系人控制器,并回调点击的数据
    [self dismissViewControllerAnimated:YES completion:^{
        // 从多重属性——电话号中取值,参数2是取点击的索引
        NSString *aPhone =  (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phoneMulti, ABMultiValueGetIndexForIdentifier(phoneMulti,identifier)) ;
        // 去掉电话号中特殊符号
        aPhone = [self RemoveSpecialCharacters:aPhone];
        NSLog(@"去掉特殊符号:%@",aPhone);
        if ([self valiMobile:aPhone]) {
            BasicInfoAndContactsModel *model = self.dataMutArray[self.indexPath.row];
            model.subTitle = aPhone;
            [self.tableView reloadData];
        }else{
            [Utils showToast:@"手机号码不正确,请重新选择."];
        }
    }];
}

//抓取所有联系人

- (void)getAllPeoplePhoneNumber{
    [self.phoneBookMutArray removeAllObjects];
    // 2. 获取所有联系人
    ABAddressBookRef addressBookRef = ABAddressBookCreate();
    CFArrayRef arrayRef = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
    long count = CFArrayGetCount(arrayRef);
    for (int i = 0; i < count; i++) {
        //获取联系人对象的引用
        ABRecordRef people = CFArrayGetValueAtIndex(arrayRef, i);
        
        //获取当前联系人名字
        NSString *firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
        
        //获取当前联系人姓氏
        NSString *lastName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty));
        NSLog(@"--------------------------------------------------");
        NSLog(@"name=%@%@", ([Utils strIsNil:firstName] ? @"" : firstName), ([Utils strIsNil:lastName] ? @"" : lastName));
        NSString *name = [NSString stringWithFormat:@"%@%@", [Utils strIsNil:firstName] ? @"" : firstName, [Utils strIsNil:lastName] ? @"" : lastName];
        //获取当前联系人的电话 数组
        NSMutableArray *phoneArray = [[NSMutableArray alloc]init];
        ABMultiValueRef phones = ABRecordCopyValue(people, kABPersonPhoneProperty);
        for (NSInteger j=0; j<ABMultiValueGetCount(phones); j++) {
            NSString *phone = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(phones, j));
            phone = [self RemoveSpecialCharacters:phone];
            NSLog(@"phone=%@", phone);
            [phoneArray addObject:phone];
        }
        NSDictionary *dict = @{
                               @"name" : name,
                               @"phones" : phoneArray
                               };
        [self.phoneBookMutArray addObject:dict];
    }
}

//去除电话号码中的特殊字符

- (NSString *)RemoveSpecialCharacters:(NSString *)str{
    NSString *string = str;
    string = [string stringByReplacingOccurrencesOfString:@"+86" withString:@""];
    NSCharacterSet *setToRemove = [[ NSCharacterSet characterSetWithCharactersInString:@"0123456789"]invertedSet];
    string = [[string componentsSeparatedByCharactersInSet:setToRemove]componentsJoinedByString:@""];
    return string;
}

pragma mark - 电话正则

- (BOOL)valiMobile:(NSString *)mobileNum
{
    if (mobileNum.length != 11)
    {
        return NO;
    }
    /**
     * 判断字符串是否符合手机号码格式
     * 移动号段: 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
     * 联通号段: 130,131,132,145,155,156,170,171,175,176,185,186
     * 电信号段: 133,149,153,170,173,177,180,181,189
     */
    NSString *telRegex = @"^((13[0-9])|(14[5,7,9])|(15[^4])|(18[0-9])|(17[0,1,3,5,6,7,8]))\\d{8}$";// "[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
    NSPredicate *regextestTelRegex = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", telRegex];
    if (([regextestTelRegex evaluateWithObject:mobileNum] == YES))
    {
        return YES;
    }
    else
    {
        return NO;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容