AddressBook联系人管理


AddressBook联系人管理

内容概述

  • 概述
  • 读取所有联系人
  • 添加联系人

29.1 概述

苹果提供了读写联系人数据库的接口,这可以通过AddressBook.framework框架中的api来实现。可以通过这些api来查询联系人及其联系人的属性,可以对联系人进行分组,还可以添加联系人以及设置联系人头像等。

在使用AddressBook.framework框架时,首先需要添加该框架到项目当中。并且在头文件中导入#import <AddressBook/AddressBook.h>。添加AddressBook.framework的步骤如下:

  1. 创建一个项目。

  2. 选择项目名称右边的"TARGETS"。

  3. 在"Build Phases"选项中选择"Link Binary With Libraies"。

  4. 点击"+"添加"AddressBook.framework"框架到项目中。

  5. 如下图所示。

29.1 添加AddressBook.framework类库到项目中

另外,联系人不是随便可以访问的,我们的程序需要获得所有人的允许才能访问,为此,我们的程序需要检测所有者是否允许用户访问。这里我们使用ABAddressBookGetAuthorizationStatus()函数来判断,该函数返回一个int类型的值,根据返回值我们可以判断结果。返回的结果定义为如下常量。

typedef CF\_ENUM(CFIndex, ABAuthorizationStatus) {

kABAuthorizationStatusNotDetermined = 0,

kABAuthorizationStatusRestricted,

kABAuthorizationStatusDenied,

kABAuthorizationStatusAuthorized

};

这些常量分别表示:没有授权、访问受限、拒绝访问和允许访问。下面通过一个实例来演示如何检测所有者的访问权限,步骤如下:

  1. 创建一个项目,添加AddressBook.framework到项目中。

  2. 导入AddressBook.h,并在界面上添加一个按钮,并添加单击事件方法。

#import <UIKit/UIKit.h>

// 导入头文件

#import <AddressBook/AddressBook.h>

@interface AmakerViewController : UIViewController

// 检测方法

- (IBAction)check:(id)sender;

@end
  1. 实现检测方法,根据ABAddressBookGetAuthorizationStatus()函数的返回值,判断结果,并使用UIAlertView提示用户。
// 显示检测结果信息

-(void)showMsg:(NSString*)msg{

    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:nil message:msg delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil];

    [alert show];

}

// 检查是否允许访问联系人

- (IBAction)check:(id)sender {

    // 获得授权状态值

    int result = ABAddressBookGetAuthorizationStatus();

    // 判断

    switch (result) {

        case kABAuthorizationStatusAuthorized:

            [self showMsg:@"可以访问"];

            break;

        case kABAuthorizationStatusRestricted:

            [self showMsg:@"访问受限"];

            break;

        case kABAuthorizationStatusDenied:

            [self showMsg:@"拒绝访问"];

            break;

        case kABAuthorizationStatusNotDetermined:

            addressBook = ABAddressBookCreateWithOptions(NULL, nil);

            ABAddressBookRequestAccessWithCompletion

            (addressBook, ^(bool granted, CFErrorRef error) {

                if (granted){

                    NSLog(@"允许访问");

                } else {

                    NSLog(@"拒绝访问");

                }

                if (addressBook != NULL){

                    CFRelease(addressBook);

                }

            });

            break;

    }

}
  1. 程序运行结果如下所示。

29.2 检测结果

29.2 读取所有联系人

读取所有联系人时,首先要判断用户是否允许访问联系人。如果运行则使用ABAddressBookRef ABAddressBookCreateWithOptions (CFDictionaryRef options,CFErrorRef* error);方法创建ABAddressBookRef对象引用。再调用CFArrayRef ABAddressBookCopyArrayOfAllPeople (ABAddressBookRef addressBook);方法获得联系人数组,并进行遍历。实现步骤如下:

  1. 创建一个项目,导入AddressBook.framework框架。

  2. 在界面上添加一个按钮,并添加点击事件方法。

#import <UIKit/UIKit.h>

// 导入头文件

#import <AddressBook/AddressBook.h>

@interface AmakerViewController : UIViewController

// 获得所有联系人方法

- (IBAction)get:(id)sender;

@end
  1. 添加一个read方法,在该方法中实现读取所有联系人。

3.1 通过ABAddressBookCopyArrayOfAllPeople()函数获得所有联系人数组。

3.2 遍历数组获得ABRecordRef联系人记录引用对象。

3.3 通过ABRecordCopyValue函数获得联系人属性。系统定义了大量联系人属性常量通过这些常量,可以访问想要的属性。

// Property keys

AB\_EXTERN const ABPropertyID kABPersonFirstNameProperty;          // First name - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonLastNameProperty;           // Last name - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonMiddleNameProperty;         // Middle name - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonPrefixProperty;             // Prefix ("Sir" "Duke" "General") - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonSuffixProperty;             // Suffix ("Jr." "Sr." "III") - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonNicknameProperty;           // Nickname - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonFirstNamePhoneticProperty;  // First name Phonetic - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonLastNamePhoneticProperty;   // Last name Phonetic - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonMiddleNamePhoneticProperty; // Middle name Phonetic - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonOrganizationProperty;       // Company name - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonJobTitleProperty;           // Job Title - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonDepartmentProperty;         // Department name - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonEmailProperty;              // Email(s) - kABMultiStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonBirthdayProperty;           // Birthday associated with this person - kABDateTimePropertyType

AB\_EXTERN const ABPropertyID kABPersonNoteProperty;               // Note - kABStringPropertyType

AB\_EXTERN const ABPropertyID kABPersonCreationDateProperty;       // Creation Date (when first saved)

AB\_EXTERN const ABPropertyID kABPersonModificationDateProperty;   // Last saved date

3.4 多值的返回值类型是ABMultiValueRef,例如,联系电话。这还需要循环遍历。

- (void) read:(ABAddressBookRef)ab{

    // 获得所有联系人

    NSArray *peoples = (\_\_bridge\_transfer NSArray *)

    ABAddressBookCopyArrayOfAllPeople(ab);

    // 遍历

    NSUInteger i = 0;

    for (i = 0;i < [peoples count];i++){

        // 获得联系人信息

        ABRecordRef per = (\_\_bridge ABRecordRef)[peoples objectAtIndex:i];

        // 获得lastname

        NSString *lastName = (\_\_bridge\_transfer NSString *)ABRecordCopyValue(per, kABPersonLastNameProperty);

        // 输出lastname

        NSLog(@"Name = %@", lastName);

        // 获得电话号码,因为电话号码有多个,所以返回ABMultiValueRef

        ABMultiValueRef phone = ABRecordCopyValue(per, kABPersonPhoneProperty);

        // 遍历电话号码

        NSUInteger j = 0;

        for (j = 0;j < ABMultiValueGetCount(phone);j++){

            // 获得电话号码标签,例如:手机、办公电话等

            NSString *phoneLabel = (\_\_bridge\_transfer NSString *)

            ABMultiValueCopyLabelAtIndex(phone, j);

            // 获得电话号码

            NSString *phoneNumber = (\_\_bridge\_transfer NSString *)

            ABMultiValueCopyValueAtIndex(phone, j);

            // 输出电话标签和号码

            NSLog(@"Label = %@, phoneNumber = %@",phoneLabel,phoneNumber);

        }

    }

}
  1. 定义check检测方法,如果用户允许方法联系人,则调用read方法读取联系人信息。
// 检查是否允许访问联系人

- (void)check{

    // 获得授权状态值

    int result = ABAddressBookGetAuthorizationStatus();

    // 判断

    switch (result) {

        case kABAuthorizationStatusAuthorized:

            // 创建ABAddressBookRef引用

            addressBook = ABAddressBookCreateWithOptions(NULL, nil);

            // 读取所有联系人

            [self read:addressBook];

            break;

        case kABAuthorizationStatusRestricted:

            [self showMsg:@"访问受限"];

            break;

        case kABAuthorizationStatusDenied:

            [self showMsg:@"拒绝访问"];

            break;

            // 授权

        case kABAuthorizationStatusNotDetermined:

            // 创建ABAddressBookRef引用

            addressBook = ABAddressBookCreateWithOptions(NULL, nil);

            ABAddressBookRequestAccessWithCompletion

            (addressBook, ^(bool granted, CFErrorRef error) {

                if (granted){

                    // 如果允许访问,读取所有联系人

                    [self read:addressBook];

                } else {

                    NSLog(@"拒绝访问");

                }

                if (addressBook != NULL){

                    CFRelease(addressBook);

                }

            });

            break;

    }

}
  1. 程序允许结果如下所示。

29.3  读取所有联系人

29.3 添加联系人

添加联系人,首先,使用ABPersonCreate()函数创建一个记录引用对象ABRecordRef,在使用ABRecordSetValue函数为属性赋值。如果是多值属性还需要使用ABMultiValueCreateMutable()函数创建多值引用对象ABMutableMultiValueRef。然后使用ABAddressBookAddRecord()函数添加一条记录,并使用ABAddressBookSave()函数保存更改。实现步骤如下:

  1. 创建一个项目,添加AddressBook.framework.框架。

  2. 在界面上添加一个按钮,并且添加点击事件方法。

#import <UIKit/UIKit.h>

// 导入头文件

#import <AddressBook/AddressBook.h>

@interface AmakerViewController : UIViewController

// 添加方法

- (IBAction)create:(id)sender;

@end
  1. 添加一个createNewPeople方法,添加新的联系人。
// 添加一个新的联系人

- (ABRecordRef) createNewPeople:(NSString *)name

                              phoneNumber:(NSString *)phoneNumber

                         inAddressBook:(ABAddressBookRef)paramAddressBook{

    ABRecordRef result = NULL;

    // 创建一个Person记录

    result = ABPersonCreate();

    BOOL couldSetName = NO;

    BOOL couldSetPhone = NO;

    // 设置Lastname值

    couldSetName = ABRecordSetValue(result,

                                         kABPersonLastNameProperty,

                                         (\_\_bridge CFTypeRef)name,

                                         NULL);

    // 设置电话号码

    ABMutableMultiValueRef multiPhone = ABMultiValueCreateMutable(kABMultiStringPropertyType);

     couldSetPhone = ABMultiValueAddValueAndLabel(multiPhone, (\_\_bridge CFTypeRef)(phoneNumber), kABPersonPhoneMobileLabel, NULL);

    ABRecordSetValue(result, kABPersonPhoneProperty, multiPhone,nil);

    // 添加新记录

    BOOL couldAddPerson = ABAddressBookAddRecord(paramAddressBook,result,nil);

    if (couldAddPerson){

        NSLog(@"添加成功!");

    } else {

        NSLog(@"添加失败!");

        CFRelease(result);

        result = NULL;

        return result;

    }

    // 判断是否有未保存内容

    if (ABAddressBookHasUnsavedChanges(paramAddressBook)){

        CFErrorRef couldSaveAddressBookError = NULL;

        // 保存更新

        BOOL couldSaveAddressBook = ABAddressBookSave(paramAddressBook,

                                                      &amp;couldSaveAddressBookError);

        if (couldSaveAddressBook){

            NSLog(@"保存成功!");

        } else {

            NSLog(@"保存失败!");

        }

    }

    return result;

}
  1. 添加一个检测方法check,如果用户允许访问联系人,则调用createNewPeople方法添加联系人。
// 检查是否允许访问联系人

- (void)check{

    // 获得授权状态值

    int result = ABAddressBookGetAuthorizationStatus();

    // 判断

    switch (result) {

        case kABAuthorizationStatusAuthorized:

            // 创建ABAddressBookRef引用

            addressBook = ABAddressBookCreateWithOptions(NULL, nil);

            // 读取所有联系人

            [self createNewPeople:@"Tom" phoneNumber:@"13800" inAddressBook:addressBook];

            break;

        case kABAuthorizationStatusRestricted:

            [self showMsg:@"访问受限"];

            break;

        case kABAuthorizationStatusDenied:

            [self showMsg:@"拒绝访问"];

            break;

            // 授权

        case kABAuthorizationStatusNotDetermined:

            // 创建ABAddressBookRef引用

            addressBook = ABAddressBookCreateWithOptions(NULL, nil);

            ABAddressBookRequestAccessWithCompletion

            (addressBook, ^(bool granted, CFErrorRef error) {

                if (granted){

                    // 如果允许访问,读取所有联系人

                    [self createNewPeople:@"Tom" phoneNumber:@"13800" inAddressBook:addressBook];

                } else {

                    NSLog(@"拒绝访问");

                }

            });

            break;

    }

}
  1. 程序运行结果如下所示。

 29.4  添加联系人