获取联系人属性,获取通讯录的方式

作者: 计算机网络技术  发布:2019-11-30

iOS 通信录-获取联系人属性

剧情均出自关东升老师的ios开采指南

上风流浪漫篇写了维系人框架的一些须求清楚的文化

几日前写一下读取联系人多稀有关操作

要读取通信录数据库 必要

成立通信录对象查询获取数据(全数可能部分)获取通信录某一条记下(某一个人的兼具数据)获取这厮的种种质量数据 就是那样

 CFErrorRef error = NULL;
    //创建一个通讯录操作对象
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

第风姿洒脱参数是保留参数,传递NULL就能够;

//查找联系人
- (void)filterContentForSearchText:(NSString *)searchText
{
    //判断授权状态
    if (ABAddressBookGetAuthorizationStatus()!=kABAuthorizationStatusAuthorized) {
        return ;
    }
    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
    if (searchText.length == 0) {
        //查找所有
        listContacts = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
    }
    else{
        //根据字符串查找前缀关键字
        CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText);
        listContacts = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText));
        CFRelease(cfSearchText);
    }
    //这里应该刷新表格
    [self.tableView reloadData];
    CFRelease(addressBook);
}

授权的状态:
   kABAuthorizationStatusNotDetermined  用户还没有决定
   kABAuthorizationStatusRestricted, 受限制
   kABAuthorizationStatusDenied, 拒绝
   kABAuthorizationStatusAuthorized 许可

联系人的属性

kABPersonFirstNameProperty;          // 名字
kABPersonLastNameProperty;           // 姓氏
kABPersonMiddleNameProperty;         // 中间名
kABPersonPrefixProperty;             // 前缀
kABPersonSuffixProperty;             // 后缀
kABPersonNicknameProperty;           // 昵称
kABPersonFirstNamePhoneticProperty;  // 名字的汉语拼音或者音标
kABPersonLastNamePhoneticProperty;   // 姓氏汉语拼音或者音标
kABPersonMiddleNamePhoneticProperty; // 中间名的汉语拼音或者音标
kABPersonOrganizationProperty;       // 组织名
kABPersonJobTitleProperty;           // 工作头衔
kABPersonDepartmentProperty;         // 部门
kABPersonNoteProperty;               // 备注
kABPersonBirthdayProperty;           // 生日
kABPersonCreationDateProperty;       // 创建时间
kABPersonModificationDateProperty;   // 修改日期

    //多值属性 (一个属性中又多个值) 有标签、值、id
    kABPersonPhoneProperty ;        //电话号码属性           kABMultiStringPropertyType;//类型
    kABPersonEmailProperty ;        //e-mail属性            kABMultiStringPropertyType;//类型
    kABPersonURLProperty ;          //URL属性               kABMultiStringPropertyType;//类型
    kABPersonRelatedNamesProperty;  // 亲属关系人属性         kABMultiStringPropertyType;//类型
    kABPersonAddressProperty ;      //地址属性               kABMultiDictionaryPropertyType;//类型
    kABPersonInstantMessageProperty;//及时聊天属性            kABMultiDictionaryPropertyType;//类型
    kABPersonSocialProfileProperty; //社交账号属性            kABMultiDictionaryPropertyTypel;//类型

利用方面包车型大巴习性来搜索想要的值

下面是单值属性:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    //从搜索出的联系人数组中获取一条数据 转换为ABRecordRef格式
    ABRecordRef thisPerson = CFBridgingRetain([listContacts objectAtIndex:[indexPath row]]);
    //查找这条记录中的名字
    NSString *firstName = CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonFirstNameProperty));
    firstName = firstName != nil? firstName:@"";
    //查找这条记录中的姓氏
    NSString *lastName = CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonLastNameProperty));
    cell.textLabel.text = [NSString stringWithFormat:@"%@%@",firstName,lastName];
    CFRelease(thisPerson);
    return cell;

}

上面是多值属性的查找方法:

//获取多值属性
- (void)multiValueProperty
{
    ABRecordID personRecordID = [personIDASNumber intValue];//personIDASNumber是NSNumber类型的值用来保存RecordID的值
    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
    //通过ABRecordID属性找到ABRecord
    ABRecordRef personRecord = ABAddressBookGetPersonWithRecordID(addressBook, personRecordID);
    //通过ABRecord 查找多值属性
    ABMultiValueRef emailProperty = ABRecordCopyValue(personRecord, kABPersonEmailProperty);
    //将多值属性的多个值转化为数组
    NSArray * emailArray = CFBridgingRelease(ABMultiValueCopyArrayOfAllValues(emailProperty));
    for (int index = 0; index < emailArray.count; index++) {
        NSString *email = [emailArray objectAtIndex:index];
        NSString *emailLabel = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(emailProperty, index));
        //判断当前这个值得标签
        if ([emailLabel isEqualToString:(NSString *)kABWorkLabel]) {
            NSLog(@"%@", email);
        }
    }
}

收获联系人图片:

//获取联系人的图片
- (void)setImage
{
    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
    ABRecordRef cecordRef = ABAddressBookGetPersonWithRecordID(addressBook,[personIDASNumber intValue]);
    //判断联系人是否有照片
    if (ABPersonHasImageData(cecordRef)) {
        //获取照片数据
        NSData *photoData = CFBridgingRelease(ABPersonCopyImageData(cecordRef));
        self.imageView.image = [UIImage imageWithData:photoData];
    }
}

通信录-获取联系人属性 内容均来源于关东升老师的ios开辟指南 上生机勃勃篇写了联系人框架的朝气蓬勃部分不得不领会的学识 今后写一下读取联系人数据...

获取通信录的章程

  • iOS9以前 使用 AddressBookUI.framework,AddressBook.framework
  • iOS9以后 使用 ContactsUI.framework,Contacts.framework
    大致的辨证下,在那之中 AddressBookUI 和 ContactsUI 是弹出三个简报录分界面提供选择一条关系人音信并且是不必要手动授权, AddressBook 和 Contacts 是拿到全体通信录数据同时需求手动授权
    在意在iOS10拿到通讯录权限需主动在info.plist里增加上提醒音信. 不然会崩溃. 在info.plistkey: Privacy - Contacts Usage Descriptionvalue:是或不是允许此App访问你的通讯录

关联人模型 ContactModel

ContactModel.h

#import <Foundation/Foundation.h>

@interface ContactModel : NSObject
/** num */
@property (nonatomic, copy) NSString *num;
/** 姓名 */
@property (nonatomic, copy) NSString *name;

- (instancetype)initWithName:(NSString *)name phoneNum:(NSString *)num;

@end

ContactModel.m

#import "ContactModel.h"

@implementation ContactModel

- (instancetype)initWithName:(NSString *)name phoneNum:(NSString *)num
{
    if (self = [super init]) {
        self.name = name;
        self.num = num;
    }

    return self;
}


@end

工具类 ContactModel

ContactsTool.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#import "ContactModel.h"
typedef void(^ContactBlock)(ContactModel *contactsModel);

@interface ContactsTool : NSObject
+ (NSMutableArray *)getAllPhoneInfo;

- (void)getOnePhoneInfoWithUI:(UIViewController *)target callBack:(ContactBlock)block;

@end

ContactsTool.m

#import "ContactsTool.h"
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>

#define iOS9Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.0f)


@interface ContactsTool ()<CNContactPickerDelegate, ABPeoplePickerNavigationControllerDelegate>
@property(nonatomic, strong) ContactModel *contactModel;
@property(nonatomic, copy) ContactBlock myBlock;
@end

@implementation ContactsTool
+ (NSMutableArray *)getAllPhoneInfo {
    return iOS9Later ? [self getContactsFromContactsAll] : [self getContactsFromAddressBookAll];
}

- (void)getOnePhoneInfoWithUI:(UIViewController *)target callBack:(ContactBlock)block
{
    if (iOS9Later) {
        [self getContactsFromContactUI:target];
    } else {
        [self getContactsFromAddressBookUI:target];
    }
    self.myBlock = block;
}

#pragma mark - AddressBookUI
- (void)getContactsFromAddressBookUI:(UIViewController *)target {
    ABPeoplePickerNavigationController *pickerVC = [[ABPeoplePickerNavigationController alloc] init];
    pickerVC.peoplePickerDelegate = self;
    [target presentViewController:pickerVC animated:YES completion:nil];
}

/**
 *  当用户选择某一个联系人的某一个属性的时候会执行该方法
 *
 *  @param person       选中的联系人
 *  @param property     选中的联系人的属性
 *  @param identifier   每一个属性都有一个对应的表示
 */

- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person {


    // 将CoreFoundation框架的对象转成Foundation框架对象,那么可以通过桥接的方式
    // 如果是CoreFoundation框架中的对象,如果是通过copy或者create或者retain,必须对应有一个release
    /*
     __bridge type: 通过该桥接方式,那么CoreFoundation对应的对象需要手动来释放,Foundation框架的对象如果是在ARC环境下面,则不需手动释放
     __bridge_transfer type: 通过该桥接方式,那么CoreFoundation对应的对象表示已经交给Foundation对象进行管理,如果是在ARC环境下面,不需要释放任何一个对象
     */

    ABMultiValueRef phonesRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
    if (!phonesRef) { return; }
    NSString *phoneValue = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phonesRef, 0);

    CFStringRef lastNameRef = ABRecordCopyValue(person, kABPersonLastNameProperty);
    CFStringRef firstNameRef = ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSString *lastname = (__bridge_transfer NSString *)(lastNameRef);
    NSString *firstname = (__bridge_transfer NSString *)(firstNameRef);
    NSString *name = [NSString stringWithFormat:@"%@%@", lastname == NULL ? @"" : lastname, firstname == NULL ? @"" : firstname];
    NSLog(@"姓名: %@", name);

    ContactModel *model = [[ContactModel alloc] initWithName:name phoneNum:phoneValue];
    NSLog(@"电话号码: %@", phoneValue);

    CFRelease(phonesRef);
    if (self.myBlock) self.myBlock(model);
}

#pragma mark - ContactsUI
- (void)getContactsFromContactUI:(UIViewController *)target {
    CNContactPickerViewController *pickerVC = [[CNContactPickerViewController alloc] init];
    pickerVC.delegate = self;
    [target presentViewController:pickerVC animated:YES completion:nil];
}

- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact {
    NSString *name = [NSString stringWithFormat:@"%@%@", contact.familyName == NULL ? @"" : contact.familyName, contact.givenName == NULL ? @"" : contact.givenName];
    NSLog(@"姓名: %@", name);

    CNPhoneNumber *phoneNumber = [contact.phoneNumbers[0] value];
    ContactModel *model = [[ContactModel alloc] initWithName:name phoneNum:[NSString stringWithFormat:@"%@", phoneNumber.stringValue]];
    NSLog(@"电话号码: %@", phoneNumber.stringValue);

    if (self.myBlock) self.myBlock(model);
}

#pragma mark - AddressBook
+ (NSMutableArray *)getContactsFromAddressBookAll {
    //取得通讯录访问授权状态
    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
    CFErrorRef myError = NULL;
    // ABAddressBookRef 代表通讯对象
    //调用ABAddressBookCreateWithOptions()方法创建通讯录对象ABAddressBookRef
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &myError);
    if (myError) {
        [self showErrorAlert];
        if (addressBook) CFRelease(addressBook);
        return nil;
    }

    /*

     kABAuthorizationStatusNotDetermined = 0, 没有决定是否授权

     kABAuthorizationStatusRestricted,  受限制

     kABAuthorizationStatusDenied,  拒绝

     kABAuthorizationStatusAuthorized  授权

     */

    __block NSMutableArray *contactModels = [NSMutableArray array];
    if (status == kABAuthorizationStatusNotDetermined) {  // 用户还没有决定是否授权你的程序进行访问
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            if (granted) { //授权成功
                contactModels = [self getAddressBookInfo:addressBook];
            } else {
                [self showErrorAlert];
                if (addressBook) CFRelease(addressBook);
            }
        });
        // 用户已拒绝 或 iOS设备上的家长控制或其它一些许可配置阻止程序与通讯录数据库进行交互
    } else if (status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted) {
        [self showErrorAlert];
        if (addressBook) CFRelease(addressBook);
    } else if (status == kABAuthorizationStatusAuthorized) {  // 用户已授权
        contactModels = [self getAddressBookInfo:addressBook];
    }
    return contactModels;
}

/*

 桥接有三种方式:

 (__bridge type)(expression) : 只是让NSFoundation框架暂时使用CF框架对象,注意需要手动释放 Core Foundation 对象,用CFRelease( )函数。
 (__bridge_transfer type)(expression) / CFBridgingRelease(expression) : CF框架移交对象的管理权给NSFoundation框架,不需要手动释放对象
 前两种是将CF对象转NSFoundation,最后一个是NSFoundation转 CF对象,不常用
 (__bridge_retained )()

 */

+ (NSMutableArray *)getAddressBookInfo:(ABAddressBookRef)addressBook {
    CFArrayRef peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);
    NSInteger peopleCount = CFArrayGetCount(peopleArray);
    NSMutableArray *contactModels = [NSMutableArray array];

    for (int i = 0; i < peopleCount; i++) {
        ABRecordRef person = CFArrayGetValueAtIndex(peopleArray, i);
        ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
        if (phones) {
            NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
            NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
            NSString *name = [NSString stringWithFormat:@"%@%@", lastName == NULL ? @"" : lastName, firstName == NULL ? @"" : firstName];
            NSLog(@"姓名: %@", name);

            CFIndex phoneCount = ABMultiValueGetCount(phones);
            for (int j = 0; j < phoneCount; j++) {
                NSString *phoneValue = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phones, j);
                NSLog(@"电话号码: %@", phoneValue);
                ContactModel *model = [[ContactModel alloc] initWithName:name phoneNum:phoneValue];
                [contactModels addObject:model];
            }
        }
        CFRelease(phones);
    }

    if (addressBook) CFRelease(addressBook);
    if (peopleArray) CFRelease(peopleArray);

    return contactModels;
}


#pragma mark - Contacts
+ (NSMutableArray *)getContactsFromContactsAll {
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    CNContactStore *store = [[CNContactStore alloc] init];
    __block NSMutableArray *contactModels = [NSMutableArray array];

    if (status == CNAuthorizationStatusNotDetermined) { // 用户还没有决定是否授权你的程序进行访问
        [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                contactModels = [self getContactsInfo:store];
            } else {
                [self showErrorAlert];
            }
        }];
        // 用户已拒绝 或 iOS设备上的家长控制或其它一些许可配置阻止程序与通讯录数据库进行交互
    } else if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusRestricted) {
        [self showErrorAlert];
    } else if (status == CNAuthorizationStatusAuthorized) { // 用户已授权
        contactModels = [self getContactsInfo:store];
    }

    return contactModels;
}

+ (NSMutableArray *)getContactsInfo:(CNContactStore *)store {
    NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
    CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
    NSMutableArray *contactModels = [NSMutableArray array];

    [store enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
        NSString *name = [NSString stringWithFormat:@"%@%@", contact.familyName == NULL ? @"" : contact.familyName, contact.givenName == NULL ? @"" : contact.givenName];
        NSLog(@"姓名: %@", name);

        for (CNLabeledValue *labeledValue in contact.phoneNumbers) {
            CNPhoneNumber *phoneNumber = labeledValue.value;
            NSLog(@"电话号码: %@", phoneNumber.stringValue);
            ContactModel *model = [[ContactModel alloc] initWithName:name phoneNum:phoneNumber.stringValue];
            [contactModels addObject:model];
        }
    }];

    return contactModels;
}

#pragma mark - Error
+ (void)showErrorAlert {
    NSLog(@"授权失败, 请允许app访问您的通讯录, 在手机的”设置-隐私-通讯录“选项中设置允许");
}

@end

tips
将CoreFoundation框架的指标转成Foundation框架对象,那么能够因此桥接的不二等秘书技
意气风发旦是CoreFoundation框架中的对象,要是是由此copy可能create只怕retain,必得对应当二个releass
__bridge type: 通过该桥接格局,那么CoreFoundation对应的对象急需手动来释放,Foundation框架的目的如若是在ARC遭遇上面,则不需手动释放
__bridge_transfer type: 通过该桥接方式,那么CoreFoundation对应的目的表示曾经付出Foundation对象开展处理,假诺是在ARC景况上面,无需释放别的贰个目的

桥接有三种办法:

  • (__bridge type)(expression) : 只是让NSFoundation框架暂且使用CF框架对象,注意须求手动释放 Core Foundation 对象,用CFRelease( 卡塔尔国函数。
  • (__bridge_transfer type)(expression)/ CFBridgingRelease(expression) `: CF框架移交对象的管理权给NSFoundation框架,没有必要手动释放对象
    前三种是将CF对象转NSFoundation,
  • (__bridge_retained )(expression) 最终三个是NSFoundation转 CF对象,临时用

上边大概介绍一下通信录操作中常用的门类:

  • ABAddressBookRef:代表通信录对象,通过该目的开采人士不用过多的关爱通信录的储存情势,能够直接以透明的办法去做客、保存(在运用AddressBook.framework操作联系人时,全部的加码、删除、更正后都必须要执行保存操作,肖似于Core Data)等。
  • ABRecordRef:代表一个通用的笔录对象,可以是一条关系人新闻,也得以是三个群组,能够因而-
  • ABRecordGetRecordType()函数获得实际项目。假诺作为联系人(事实上也许有的时候应用它看做交流人),那么这么些记录记录了二个完璧归赵的联系人音信(姓名、性别、电话、邮件等),每条记下都有三个唯黄金时代的ID标示这条记下(能够透过ABRecordGetRecordID(卡塔尔国函数得到)。
  • ABPersonRef:代表联络人新闻,非常少直接运用,实际开拓进度中司空见惯会选择项目为“kABPersonType”的-
  • ABRecordRef 来表示联系人(不问可以知道ABPersonRef其实是生机勃勃种类型为“kABPersonType”的ABRecordRef)
  • ABGroupRef:代表群组,与ABPersonRef近似,少之又少间接采纳ABGroupRef,而是接收项目为“kABGroupType”的ABRecordRef来代表群组,多个群组能够包蕴四个关系人,四个联系人也相近能够四个群组。

首先看一下常用的操作通信录记录的主意:

是因为通信录操作的第一是对ABRecordRef的操作

  • ABPersonCreate():创设四个档案的次序为“kABPersonType”的ABRecordRef。
  • ABRecordCopyValue():获得钦定属性的值。
  • ABRecordCopyCompositeName():获得联系人(或群组)的复合新闻(对于联系人则包括:姓、名、公司等新闻,对于群组则再次来到组名称)。
  • ABRecordSetValue():设置ABRecordRef的属性值。注意在装置ABRecordRef的值时又分为单值属性和多值属性:单值属性设置只要透过ABRecordSetValue(卡塔尔方法钦定属性名和值就可以;
  • 多值属性则要先经过成立二个ABMutableMultiValueRef花色的变量,然后通过ABMultiValueAddValueAndLabel()主意依次增加属性值,最终经过ABRecordSetValue()方法将ABMutableMultiValueRef品类的变量设置为记录值。
  • ABRecordRemoveValue():删除钦赐的属性值
通信录的访谈步骤平日如下:
  1. 调用ABAddressBookCreateWithOptions()主意创设通信录对象ABAddressBookRef。
  2. 调用ABAddressBookRequestAccessWithCompletion()格局获得客商授权访谈通信录。
  3. 调用ABAddressBookCopyArrayOfAllPeople()、ABAddressBookCopyPeopleWithName()办法查询联系人音信。
  4. 读取联系人后如果要体现联系人信息则足以调用ABRecord相关措施读取相应的数码;即便要进行改造联系人音讯,则能够使用相应的主意校勘ABRecord音讯,然后调用ABAddressBookSave(卡塔尔方法提交改善;假设要去除联系人,则足以调用ABAddressBookRemoveRecord(卡塔尔(قطر‎方法删除,然后调用ABAddressBookSave(卡塔尔国提交校勘操作。
  5. 也便是说假使要改过恐怕去除都急需首先查询相应的关联人,然后修改或删除后提交修改。借使顾客要加进叁个关系人则不用举办查询,直接调用ABPersonCreate(卡塔尔方法创造贰个ABRecord然后设置具体的习性,调用ABAddressBookAddRecord方法增加就能够。

收获通信录状态(ios9.0早前的卡塔尔(قطر‎

     kABAuthorizationStatusNotDetermined = 0, 没有决定是否授权
     kABAuthorizationStatusRestricted,  受限制     
     kABAuthorizationStatusDenied,  拒绝
     kABAuthorizationStatusAuthorized  授权

至于iOS9以后的通信录状态kAB换成CN即可 ,比如拒绝状态由kABAuthorizationStatusDenied->CNAuthorizationStatusDenied,别的的类比 就能够
还应该有二个最大的浮动,正是iOS9现在访问通信录属性,要刚开始阶段设置好,不然会奔溃
上边是列表

// 姓名前缀
CNContactNamePrefixKey     
// 名                 
CNContactGivenNameKey                       
// 中间名
CNContactMiddleNameKey  
// 姓                   
CNContactFamilyNameKey            
// 婚前姓         
CNContactPreviousFamilyNameKey
// 姓名后缀
CNContactNameSuffixKey   
// 昵称                   
CNContactNicknameKey                        
// 公司
CNContactOrganizationNameKey                
// 部门
CNContactDepartmentNameKey                  
// 职位
CNContactJobTitleKey                        
// 名字拼音或音标
CNContactPhoneticGivenNameKey
// 中间名拼音或音标              
CNContactPhoneticMiddleNameKey
// 姓拼音或音标
CNContactPhoneticFamilyNameKey  
// 公司拼音或音标            
CNContactPhoneticOrganizationNameKey      
// 生日  
CNContactBirthdayKey   
// 农历                    
CNContactNonGregorianBirthdayKey    
// 备注        
CNContactNoteKey                            
// 图片
CNContactImageDataKey                       
// 缩略图
CNContactThumbnailImageDataKey              
// 图片是否允许访问
CNContactImageDataAvailableKey              
// 类型
CNContactTypeKey                            
// 号码
CNContactPhoneNumbersKey                    
// 电子邮件
CNContactEmailAddressesKey                  
// 地址
CNContactPostalAddressesKey                 
// 日期
CNContactDatesKey   
// URL                        
CNContactUrlAddressesKey                    
// 关联人
CNContactRelationsKey                       
// 社交
CNContactSocialProfilesKey                  
// 即时通讯
CNContactInstantMessageAddressesKey

内需什么样,要先行注明好

NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];

像本人这么些,正是声称了。姓,名,手机号。

备注:
1.上文中所指的以Ref结尾的对象实际是该指标的指针(或引用),在C语言的框架中山大学部类型会以Ref结尾,这一个项目小编便是二个指针,定义时无需加“*”
2.日常方法中带有copy、create、new、retain等根本字的情势创设的变量使用之后供给调用对应的release方法释放。举个例子:使用ABPersonCreate(卡塔尔(英语:State of Qatar);创设完ABRecordRef变量后接受CFRelease(卡塔尔(英语:State of Qatar)方法释放。
3.在与众多C语言框架人机联作时能够都存在Obj-C和C语言类型之间的中间转播(非常是Obj-C和Core Foundation框架中的一些转速),这个时候有可能会用到桥接,只要在强转之后前边加上”__bridge”就可以,经过桥接转变后的花色无需再去手动维护内部存款和储蓄器,也就无需使用相应的release方法释放内部存款和储蓄器。
Demo

本文由今晚买四不像发布于计算机网络技术,转载请注明出处:获取联系人属性,获取通讯录的方式

关键词:

上一篇:杀死IceSword
下一篇:没有了