摘要:本文将带你了解IOS开发入门自定义iOS通讯录,希望本文对大家学IOS有所帮助。
本文将带你了解IOS开发入门自定义iOS通讯录,希望本文对大家学IOS有所帮助。
苹果给用户提供了自己的通讯录,但是根据业务的需求,需要自定义通讯录,我们就需要根据业务需求来自定义
首先我们需要知道苹果的提供的一些Foundation、UIKit框架,了解其中的一些特性,可以打开手机查看苹果系统提供的
原生的通讯录,可以看到:
1.搜索框
2.右侧搜索条
3.联系人分组
4.添加联系人
5.获取联系人头像及联系方式
根据需求,可以总结出自定义通讯录需要做的一些功能,一项大的功能可以差分成一些小的功能,然后
一个一个实现,将复杂的问题差分成小问题解决。
1.自定义搜索框
2.获取首字母
3.权限判断
4.排序
5.自定义搜索
6.自定义联系人界面(考虑多值的情况,获取通讯录头像)
简答介绍下排序:
?12IOS项目中会用到对通讯录的联系人或是会员按姓名为关键字排序,因为NSArray并不直接支持对汉字的排序,这就要通过将汉字转换成拼音完成按A~Z的排序,这看起来是个头疼的问题,因为牵扯到汉字转为拼音,获取汉字的首字的首字母,如将“王”变成“W”。 函数原理是:我们知道,在Objective
C语言中,字符串是以unicode进行编码的。在unicode字符集中,汉字的编码范围为4E00 到 9FA5
之间(即从第19968开始的20902个字符是vc4PAwB0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnHnsPj63Pjn4Pjm4n1c1n1n1rf"
rel="nofollow"
target="_blank">中文简体字符)。我们把这些字符的拼音首字母按照顺序都存放在一个char数组中。当我们查找一个汉字的拼音首字母时,只需把这个汉字的unicode码(即char强制转换为int)减去19968,然后用这个数字作为索引去找char数组中存放的字母即可。
给出项目的源码,注释很清楚。代码如:
RYAddressBook.h
?1234567891011121314151617181920212223242526272829303132333435363738394041#import
<foundation foundation.h="">#import
"RYPersonInfo.h" typedef void (^AddressBookBlock) (NSArray *personInfos); @interface
RYAddressBook : NSObject /** * 将数字转化为字母 0~26 1~25=a~z
26=# */NSString* SpellFromIndex(int index); /** *
获取索引 */int Index(NSString *firstSpell);/** *
获取用户所有通讯录信息 * * @return 所有通讯录数据信息数组 */+
(void)getPersonInfo:(AddressBookBlock)addressBookBlock; /** *
根据关键字匹配所有用户信息 * * @param keyWord 匹配关键字 * *
@return 匹配到的通讯录数据信息数组 */+ (void)searchPersonInfo:(NSString *)keyWord
addressBookBlock:(AddressBookBlock)addressBookBlock; /** *
根据姓名进行数组的重排序 * * @param personInfos 获取的通讯录数据信息数组 */+
(NSArray *)sortPersonInfos:(NSArray
*)personInfos; @end</foundation>
RYAddressBook.m
?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160#import
"RYAddressBook.h" @interface RYAddressBook () @property
(nonatomic, copy) AddressBookBlock
addressBookBlock; @end @implementation RYAddressBook NSString*
SpellFromIndex(int index){ if (index ==
26) return
@"#"; else return
[NSString stringWithFormat:@"%c", [@"A"
characterAtIndex:0]+index];} int Index(NSString
*firstSpell){ int i = [firstSpell characterAtIndex:0]
- [@"a"
characterAtIndex:0]; if
([firstSpell isEqualToString:@"#"] || i < 0 || i > 26)
{ return
26; } return
[firstSpell characterAtIndex:0] - [@"a"
characterAtIndex:0];} /** * 获取用户所有通讯录信息 */+
(void)getPersonInfo:(AddressBookBlock)addressBookBlock{ [[self
alloc] getPersonInfo:addressBookBlock];} /** *
根据关键字匹配所有用户信息 */+ (void)searchPersonInfo:(NSString *)keyWord
addressBookBlock:(AddressBookBlock)addressBookBlock{ [[self
alloc] searchPersonInfo:keyWord addressBookBlock:addressBookBlock];} /** *
根据姓名进行数组的重排序 */+ (NSArray *)sortPersonInfos:(NSArray
*)personInfos{ return [[self alloc]
sortPersonInfos:personInfos];} -
(void)getPersonInfo:(AddressBookBlock)addressBookBlock{ self.addressBookBlock
= addressBookBlock; [self
searchPersonInfo:@""];} - (void)searchPersonInfo:(NSString
*)keyWord
addressBookBlock:(AddressBookBlock)addressBookBlock{ self.addressBookBlock
= addressBookBlock; [self
searchPersonInfo:keyWord];} - (NSArray *)sortPersonInfos:(NSArray
*)personInfos{ if (![personInfos
isKindOfClass:[NSArray class]]) { return
nil; } NSMutableArray
*arr = [NSMutableArray
array]; for (int i = 0;
i < 27; i++) { [arr
addObject:[NSMutableArray
array]]; } for
(NSObject *obj in personInfos)
{ if
(![obj isKindOfClass:[RYPersonInfo class]])
{ continue; } RYPersonInfo
*personInfo = (RYPersonInfo
*)obj; NSMutableArray
*subArr = [arr
objectAtIndex:Index(personInfo.firstSpell)]; [subArr
addObject:personInfo]; } return
arr;} /** * 根据关键字查询通讯录信息 */-
(void)searchPersonInfo:(NSString *)keyWord{ CFErrorRef
error = NULL; ABAddressBookRef addressBook =
ABAddressBookCreateWithOptions(NULL,
&error); //
开始查询通讯录 ABAddressBookRequestAccessWithCompletion(addressBook,
^(bool granted, CFErrorRef error)
{ if
(granted) { [self
filterContentForSearchText:keyWord]; } });} /** *
开始匹配通讯录信息 */- (void)filterContentForSearchText:(NSString*)searchText{ //如果没有授权则退出 if
(ABAddressBookGetAuthorizationStatus() != kABAuthorizationStatusAuthorized)
{ return; } NSArray
*blockArray = [NSArray
array]; CFErrorRef error
= NULL; ABAddressBookRef addressBook =
ABAddressBookCreateWithOptions(NULL,
&error); if([searchText
length]==0) { //查询所有 blockArray
= (__bridge NSArray
*)ABAddressBookCopyArrayOfAllPeople(addressBook); }
else
{ //条件查询 CFStringRef
cfSearchText =
(CFStringRef)CFBridgingRetain(searchText); blockArray
= CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook,
cfSearchText)); CFRelease(cfSearchText); } //
类型转换 blockArray = transformElements(blockArray); //
返回BlockArray self.addressBookBlock(blockArray);} /** *
将所有元素转化为JXPersonInfo类型数组 */NSArray* transformElements(NSArray* arr){ NSMutableArray
*rtnArray = [NSMutableArray array]; for (int i = 0; i
< arr.count; i++)
{ ABRecordRef recordRef =
CFBridgingRetain([arr objectAtIndex:i]); RYPersonInfo
*personInfo = [RYPersonInfo
personInfoWithABRecordRef:recordRef]; [rtnArray
addObject:personInfo]; } return
rtnArray;}@end
RYPersonInfo.h
?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586#import
<foundation foundation.h="">#import @interface
RYPersonInfo : NSObject /** * 单值信息 */#define
PROPERTY_STR_READONLY(name) @property (nonatomic, copy) NSString *name;//
姓PROPERTY_STR_READONLY(firstName)// 名PROPERTY_STR_READONLY(lastName)//
中间名PROPERTY_STR_READONLY(middlename)// 全名PROPERTY_STR_READONLY(fullName)//
搜索索引PROPERTY_STR_READONLY(firstSpell)// 前缀PROPERTY_STR_READONLY(prefix)//
后缀PROPERTY_STR_READONLY(suffix)// 昵称PROPERTY_STR_READONLY(nickname)//
姓_音标PROPERTY_STR_READONLY(firstnamePhonetic)//
名_音标PROPERTY_STR_READONLY(lastnamePhonetic)//
中间名_音标PROPERTY_STR_READONLY(middlenamePhonetic)//
公司PROPERTY_STR_READONLY(organization)// 工作PROPERTY_STR_READONLY(jobtitle)//
部门PROPERTY_STR_READONLY(department)// 生日PROPERTY_STR_READONLY(birthday)//
备忘录PROPERTY_STR_READONLY(note)//
第一次创建用户信息的时间PROPERTY_STR_READONLY(firstknow)//
最后一次更改用户信息的时间PROPERTY_STR_READONLY(lastknow)//
名片类型(company/person)PROPERTY_STR_READONLY(kind) // 多值信息#define PROPERTY_ARR_READONLY(name)
@property (nonatomic, strong) NSArray *name;//
邮箱PROPERTY_ARR_READONLY(email)// 地址PROPERTY_ARR_READONLY(address)//
日期PROPERTY_ARR_READONLY(dates)// iMessagePROPERTY_ARR_READONLY(iMessage)//
电话号码PROPERTY_ARR_READONLY(phone)// URL链接PROPERTY_ARR_READONLY(url) #define
PROPERTY_IMG_READONLY(name) @property (nonatomic, strong) UIImage *name;//
图片//PROPERTY_IMG_READONLY(image)/** * 初始化方法 * *
@param ref 联系人属性 * * @return 实例对象 */- (id)initWithABRecordRef:(ABRecordRef)ref; /** *
初始化类方法 * * @param ref 联系人属性 * * @return
实例对象 */+
(id)personInfoWithABRecordRef:(ABRecordRef)ref; @end</addressbook></foundation>
RYPersonInfo.m
?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196#import
"RYPersonInfo.h" #define nullStrToEmpty(str) \[str
rangeOfString:@"null"].location==0? @"" :
str /** * 单值信息 */#define GET_PROPERTY_METHOD(property,
property_key) \- (NSString *)property {\return (NSString
*)CFBridgingRelease(ABRecordCopyValue(_recordRef,
property_key));\} /** * 多值信息 */#define
DICT_ADD_STR_FOR_KEY(dict, str, key) \if (str) {\[dict setObject:str
forKey:key];\}#define GET_PROPERTY_SIGLE_VALUE_METHOD(property, property_key)\-
(NSArray *)property\{\NSMutableArray *rtnArray = [NSMutableArray
array];\\ABMultiValueRef ref = ABRecordCopyValue(_recordRef,
property_key);\long count = ABMultiValueGetCount(ref);\for (int i = 0; i <
count; i++)\{\NSString* label = (__bridge
NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(ref,
i));\NSString* content = (__bridge
NSString*)ABMultiValueCopyValueAtIndex(ref, i);\NSMutableDictionary *dict =
[NSMutableDictionary dictionary];\DICT_ADD_STR_FOR_KEY(dict, content,
label);\\[rtnArray addObject:dict];\}\return rtnArray;\} @interface
RYPersonInfo () @property (nonatomic , assign)ABRecordRef
recordRef; @end @implementation RYPersonInfo -
(id)initWithABRecordRef:(ABRecordRef)ref { if (self =
[super init]) { _recordRef =
ref; } return self;} +
(id)personInfoWithABRecordRef:(ABRecordRef)ref { return
[[[self class] alloc] initWithABRecordRef:ref];} GET_PROPERTY_METHOD(
firstName ,
kABPersonFirstNameProperty);GET_PROPERTY_METHOD(
lastName ,
kABPersonLastNameProperty);GET_PROPERTY_METHOD( middlename ,
kABPersonMiddleNameProperty);GET_PROPERTY_METHOD(
prefix ,
kABPersonPrefixProperty);GET_PROPERTY_METHOD(
suffix ,
kABPersonSuffixProperty);GET_PROPERTY_METHOD( nickname
, kABPersonNicknameProperty);GET_PROPERTY_METHOD( organization ,
kABPersonOrganizationProperty);GET_PROPERTY_METHOD(
jobtitle ,
kABPersonJobTitleProperty);GET_PROPERTY_METHOD( department , kABPersonDepartmentProperty);GET_PROPERTY_METHOD(
birthday ,
kABPersonBirthdayProperty);GET_PROPERTY_METHOD(
note ,
kABPersonNoteProperty);GET_PROPERTY_METHOD( firstknow ,
kABPersonCreationDateProperty);GET_PROPERTY_METHOD(
lastknow ,
kABPersonModificationDateProperty);GET_PROPERTY_METHOD( firstnamePhonetic ,
kABPersonFirstNamePhoneticProperty);GET_PROPERTY_METHOD(
lastnamePhonetic , kABPersonLastNamePhoneticProperty);GET_PROPERTY_METHOD(
middlenamePhonetic,
kABPersonMiddleNamePhoneticProperty); GET_PROPERTY_SIGLE_VALUE_METHOD(email,
kABPersonEmailProperty)GET_PROPERTY_SIGLE_VALUE_METHOD(dates,
kABPersonDateProperty)GET_PROPERTY_SIGLE_VALUE_METHOD(url ,
kABPersonURLProperty)GET_PROPERTY_SIGLE_VALUE_METHOD(phone,
kABPersonPhoneProperty) - (NSString
*)kind{ NSString *rtnStr =
nil; CFNumberRef recordType = ABRecordCopyValue(_recordRef,
kABPersonKindProperty); if (recordType ==
kABPersonKindOrganization)
{ rtnStr =
@"company"; } else
{ rtnStr =
@"person"; } return
rtnStr;} - (NSArray *)iMessage{ NSMutableArray
*rtnArray = [NSMutableArray array]; ABMultiValueRef
instantMessage = ABRecordCopyValue(_recordRef,
kABPersonInstantMessageProperty); for (int i = 1; i
< ABMultiValueGetCount(instantMessage);
i++) { NSString*
label = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(instantMessage,
i); NSDictionary* content
=(__bridge NSDictionary*) ABMultiValueCopyValueAtIndex(instantMessage,
i); NSMutableDictionary
*imessageInfoDict = [NSMutableDictionary
dictionary]; NSString*
username = [content valueForKey:(NSString
*)kABPersonInstantMessageUsernameKey]; NSString*
service = [content valueForKey:(NSString
*)kABPersonInstantMessageServiceKey]; DICT_ADD_STR_FOR_KEY(imessageInfoDict,
username,
@"username"); DICT_ADD_STR_FOR_KEY(imessageInfoDict,
service,
@"service"); NSDictionary
*imessageDict = @{label:
imessageInfoDict}; [rtnArray
addObject:imessageDict]; } return
rtnArray;} -(NSArray *)address{ NSMutableArray
*rtnArray = [NSMutableArray
array]; ABMultiValueRef
address = ABRecordCopyValue(_recordRef,
kABPersonAddressProperty); long count = ABMultiValueGetCount(address); for(int
i = 0; i < count;
i++) { NSString*
addressLabel = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(address,
i); NSDictionary*
personaddress =(__bridge NSDictionary*) ABMultiValueCopyValueAtIndex(address,
i); NSMutableDictionary
*addressInfoDict = [NSMutableDictionary
dictionary]; NSString* country
= [personaddress valueForKey:(NSString
*)kABPersonAddressCountryKey]; NSString*
city = [personaddress valueForKey:(NSString
*)kABPersonAddressCityKey]; NSString*
state = [personaddress valueForKey:(NSString
*)kABPersonAddressStateKey]; NSString*
street = [personaddress valueForKey:(NSString
*)kABPersonAddressStreetKey]; NSString*
zip = [personaddress valueForKey:(NSString
*)kABPersonAddressZIPKey]; NSString*
coutntrycode = [personaddress valueForKey:(NSString
*)kABPersonAddressCountryCodeKey]; DICT_ADD_STR_FOR_KEY(addressInfoDict,
country, @"country"); DICT_ADD_STR_FOR_KEY(addressInfoDict,
city,
@"city"); DICT_ADD_STR_FOR_KEY(addressInfoDict,
state,
@"state"); DICT_ADD_STR_FOR_KEY(addressInfoDict,
street,
@"street"); DICT_ADD_STR_FOR_KEY(addressInfoDict,
zip,
@"zip"); DICT_ADD_STR_FOR_KEY(addressInfoDict,
coutntrycode, @"coutntrycode"); NSDictionary
*addressDict = @{addressLabel:
addressInfoDict}; [rtnArray
addObject:addressDict]; } return
rtnArray;} //- (UIImage *)image//{// NSData *data =
(__bridge NSData*)ABPersonCopyImageData(_recordRef);//
return [UIImage imageWithData:data];//} #pragma mark -#pragma mark -
CustomProperty/** * 全名 */- (NSString
*)fullName{ return [NSString
stringWithFormat:@"%@%@%@", nullStrToEmpty(self.lastName), nullStrToEmpty(self.middlename), nullStrToEmpty(self.firstName)];}/** *
首字母 */- (NSString *)firstSpell{ return
getFirstSpell(self.fullName);} /** * 输出模型所有信息 */-
(NSString *)description{ return [NSString
stringWithFormat:@"%@ -- InfoPacket", self.fullName];} /** *
获取首字母 */NSString* getFirstSpell(NSString
*fullName){ NSMutableString *ms = [[NSMutableString
alloc] initWithString:fullName]; CFStringTransform((__bridge
CFMutableStringRef)ms, 0, kCFStringTransformMandarinLatin,
NO); CFStringTransform((__bridge
CFMutableStringRef)ms, 0, kCFStringTransformStripDiacritics,
NO); if (fullName.length
> 0) return [[ms
substringWithRange:NSMakeRange(0, 1)]
lowercaseString]; else return
@"#";} @end
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号