iOS 学习之读取用户通讯录

在开发过程中有时候会遇到一种场景,读取用户的通讯录数据,但是不需要进行跳转通讯录的界面,只需要拿到用户数据即可。

其实代码也很简单,但是为了代码的简洁易读性和借耦合,做了一些封装处理,便于一行代码调用。

在这里,封装了一个类来管理,有需要的童鞋拷贝复制一下就可以使用,非常的简单。

创建一个功能管理类

WYAddressBookManager.h

1
2
3
4
5
6
7
8
9
10
11
12
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "WYAddressBookModel.h"

/** 获取通讯录回调 */
typedef void(^Obtainresult)(BOOL success, NSArray <WYAddressBookModel *> *addressArray);
@interface WYAddressBookManager : NSObject

/** 请求通讯录数据 */
- (void)getAddressBook:(Obtainresult)result;

@end

WYAddressBookManager.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#import "WYAddressBookManager.h"
#import <AddressBookUI/ABPeoplePickerNavigationController.h>
#import <AddressBook/ABPerson.h>

@implementation WYAddressBookManager

- (void)getAddressBook:(Obtainresult)result {
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error)
{
CFErrorRef *error1 = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error1);
result(YES, [self copyAddressBook:addressBook]);
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
{
CFErrorRef *error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
result(YES, [self copyAddressBook:addressBook]);
}
else
{
result(NO, @[]);
}
}

- (NSArray <WYAddressBookModel *> *)copyAddressBook:(ABAddressBookRef)addressBook {
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSMutableArray <WYAddressBookModel *> *addressBookArray = [[NSMutableArray <WYAddressBookModel *> alloc] init];

for ( int i = 0; i < numberOfPeople; i++) {
ABRecordRef person = CFArrayGetValueAtIndex(people, i);

WYAddressBookModel *persenModel = [[WYAddressBookModel alloc] init];
persenModel.firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty)) ?: @"";
persenModel.lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty)) ?: @"";
persenModel.name = [NSString stringWithFormat:@"%@%@", persenModel.lastName, persenModel.firstName] ?: @"";
persenModel.middlename = (__bridge NSString*)ABRecordCopyValue(person, kABPersonMiddleNameProperty) ?: @"";
persenModel.prefix = (__bridge NSString*)ABRecordCopyValue(person, kABPersonPrefixProperty) ?: @"";
persenModel.suffix = (__bridge NSString*)ABRecordCopyValue(person, kABPersonSuffixProperty) ?: @"";
persenModel.nickname = (__bridge NSString*)ABRecordCopyValue(person, kABPersonNicknameProperty) ?: @"";
persenModel.firstnamePhonetic = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNamePhoneticProperty) ?: @"";
persenModel.lastnamePhonetic = (__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNamePhoneticProperty) ?: @"";
persenModel.middlenamePhonetic = (__bridge NSString*)ABRecordCopyValue(person, kABPersonMiddleNamePhoneticProperty) ?: @"";
persenModel.organization = (__bridge NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty) ?: @"";
persenModel.job = (__bridge NSString*)ABRecordCopyValue(person, kABPersonJobTitleProperty) ?: @"";
persenModel.department = (__bridge NSString*)ABRecordCopyValue(person, kABPersonDepartmentProperty) ?: @"";
persenModel.birthday = (__bridge NSDate*)ABRecordCopyValue(person, kABPersonBirthdayProperty);
persenModel.note = (__bridge NSString*)ABRecordCopyValue(person, kABPersonNoteProperty) ?: @"";
persenModel.firstknow = (__bridge NSString*)ABRecordCopyValue(person, kABPersonCreationDateProperty) ?: @"";
persenModel.lastknow = (__bridge NSString*)ABRecordCopyValue(person, kABPersonModificationDateProperty) ?: @"";

ABMultiValueRef email = ABRecordCopyValue(person, kABPersonEmailProperty);
long emailcount = ABMultiValueGetCount(email);
NSMutableArray *emaillArray = [NSMutableArray <WYAddressBookEmailModel *> array];
for (int x = 0; x < emailcount; x++) {
WYAddressBookEmailModel *emallModel = [[WYAddressBookEmailModel alloc] init];
emallModel.emailTitle = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(email, x)) ?: @"";
emallModel.email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(email, x) ?: @"";
[emaillArray addObject:emallModel];
}
persenModel.email = [emaillArray mutableCopy];

ABMultiValueRef address = ABRecordCopyValue(person, kABPersonAddressProperty);
long count = ABMultiValueGetCount(address);
NSMutableArray *addressArray = [[NSMutableArray <WYAddressBookAddressModel *> alloc] init];
for(int j = 0; j < count; j++) {
WYAddressBookAddressModel *adressModel = [[WYAddressBookAddressModel alloc] init];
NSString *addressTitle = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(address, j);
NSRange range1 = [addressTitle rangeOfString:@"<"];
NSString *str1 = [addressTitle substringFromIndex:range1.location+range1.length];
NSRange range2 = [str1 rangeOfString:@">"];
adressModel.addressTitle = [str1 substringToIndex:range2.location];

NSDictionary *personaddress = (__bridge NSDictionary*) ABMultiValueCopyValueAtIndex(address, j);
adressModel.country = [personaddress valueForKey:(NSString *)kABPersonAddressCountryKey] ?: @"";
adressModel.city = [personaddress valueForKey:(NSString *)kABPersonAddressCityKey] ?: @"";
adressModel.state = [personaddress valueForKey:(NSString *)kABPersonAddressStateKey] ?: @"";
adressModel.street = [personaddress valueForKey:(NSString *)kABPersonAddressStreetKey] ?: @"";
adressModel.zip = [personaddress valueForKey:(NSString *)kABPersonAddressZIPKey] ?: @"";
adressModel.address = [NSString stringWithFormat:@"%@%@%@%@", adressModel.country, adressModel.state, adressModel.city, adressModel.street];
[addressArray addObject:adressModel];
}
persenModel.address = [addressArray mutableCopy];

ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSMutableArray *phoneArray = [[NSMutableArray <WYAddressBookPhoneModel *> alloc] init];;
for (int k = 0; k<ABMultiValueGetCount(phone); k++) {
WYAddressBookPhoneModel *phoneModel = [[WYAddressBookPhoneModel alloc] init];
phoneModel.phoneTitle = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phone, k)) ?: @"";
NSString *phoneString = [self getPhoneNumber:(__bridge NSString*)ABMultiValueCopyValueAtIndex(phone, k) ?: @""];
phoneModel.phone = phoneString;
[phoneArray addObject:phoneModel];
}
persenModel.phone = [phoneArray mutableCopy];

ABMultiValueRef url = ABRecordCopyValue(person, kABPersonURLProperty);
NSMutableArray *urlArray = [[NSMutableArray <WYAddressBookURLModel *> alloc] init];;
for (int m = 0; m < ABMultiValueGetCount(url); m++) {
WYAddressBookURLModel *urlModel = [[WYAddressBookURLModel alloc] init];
urlModel.urlTitle = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(url, m)) ?: @"";
urlModel.url = (__bridge NSString*)ABMultiValueCopyValueAtIndex(url,m) ?: @"";
[urlArray addObject:urlModel];
}
persenModel.url = [urlArray mutableCopy];
persenModel.image = (__bridge NSData*)ABPersonCopyImageData(person);
[addressBookArray addObject:persenModel];
}
return [addressBookArray mutableCopy];
}

// 截取字符串中的数字
- (NSString *)getPhoneNumber:(NSString *)number {
NSMutableArray *characters = [NSMutableArray array];
NSMutableString *mutStr = [NSMutableString string];
// 分离出字符串中的所有字符,并存储到数组characters中
for (int i = 0; i < number.length; i ++) {
NSString *subString = [number substringToIndex:i + 1];
subString = [subString substringFromIndex:i];
[characters addObject:subString];
}
// 利用正则表达式,匹配数组中的每个元素,判断是否是数字,将数字拼接在可变字符串mutStr中
for (NSString *b in characters) {
NSString *regex = @"^[0-9]*$";
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];// 谓词
BOOL isShu = [pre evaluateWithObject:b];// 对b进行谓词运算
if (isShu) {
[mutStr appendString:b];
}
}
return mutStr;
}

@end

再创建一个通讯录数据模型类

WYAddressBookEmailModel.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#import <Foundation/Foundation.h>
@class WYAddressBookEmailModel, WYAddressBookAddressModel, WYAddressBookPhoneModel, WYAddressBookURLModel;

@interface WYAddressBookModel : NSObject

/** 名 */
@property (nonatomic, copy) NSString *firstName;

/** 姓 */
@property (nonatomic, copy) NSString *lastName;

/** 完整姓名 */
@property (nonatomic, copy) NSString *name;

/** 名和姓之间的文字 */
@property (nonatomic, copy) NSString *middlename;

/** 前缀 */
@property (nonatomic, copy) NSString *prefix;

/** 后缀 */
@property (nonatomic, copy) NSString *suffix;

/** 昵称 */
@property (nonatomic, copy) NSString *nickname;

/** 名拼音音标 */
@property (nonatomic, copy) NSString *firstnamePhonetic;

/** 姓拼音音标 */
@property (nonatomic, copy) NSString *lastnamePhonetic;

/** 中名拼音音标 */
@property (nonatomic, copy) NSString *middlenamePhonetic;

/** 公司 */
@property (nonatomic, copy) NSString *organization;

/** 工作 */
@property (nonatomic, copy) NSString *job;

/** 部门 */
@property (nonatomic, copy) NSString *department;

/** 生日 */
@property (nonatomic, copy) NSDate *birthday;

/** 备忘录 */
@property (nonatomic, copy) NSString *note;

/** 第一次添加该条记录的时间 */
@property (nonatomic, copy) NSString *firstknow;

/** 最后一次修改該条记录的时间 */
@property (nonatomic, copy) NSString *lastknow;

/** email */
@property (nonatomic, copy) NSArray <WYAddressBookEmailModel *> *email;

/** 地址 */
@property (nonatomic, copy) NSArray <WYAddressBookAddressModel *> *address;

/** 电话 */
@property (nonatomic, copy) NSArray <WYAddressBookPhoneModel *> *phone;

/** URL */
@property (nonatomic, copy) NSArray <WYAddressBookURLModel *> *url;

/** 照片 */
@property (nonatomic, copy) NSData *image;

@end


@interface WYAddressBookEmailModel : NSObject

/** 邮箱类型 Home/Work */
@property (nonatomic, copy) NSString *emailTitle;

/** 邮箱 */
@property (nonatomic, copy) NSString *email;

@end


@interface WYAddressBookAddressModel : NSObject

/** 国家 */
@property (nonatomic, copy) NSString *country;

/** 地址类型 Home/Work */
@property (nonatomic, copy) NSString *addressTitle;

/** 街道 */
@property (nonatomic, copy) NSString *street;

/** 邮编 */
@property (nonatomic, copy) NSString *zip;

/** 省 */
@property (nonatomic, copy) NSString *state;

/** 市 */
@property (nonatomic, copy) NSString *city;

/** 完整地址 */
@property (nonatomic, copy) NSString *address;

@end


@interface WYAddressBookPhoneModel : NSObject

/** 电话类型 Home/Work */
@property (nonatomic, copy) NSString *phoneTitle;

/** 电话号码 */
@property (nonatomic, copy) NSString *phone;

@end


@interface WYAddressBookURLModel : NSObject

/** 电话类型 Home/Work */
@property (nonatomic, copy) NSString *urlTitle;

/** 电话号码 */
@property (nonatomic, copy) NSString *url;

@end

WYAddressBookEmailModel.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#import "WYAddressBookModel.h"

@implementation WYAddressBookModel

@end

@implementation WYAddressBookEmailModel

@end

@implementation WYAddressBookAddressModel

@end

@implementation WYAddressBookPhoneModel

@end

@implementation WYAddressBookURLModel

@end