IOS开发入门自定义iOS通讯录
白羽 2019-07-10 来源 :网络 阅读 442 评论 0

摘要:本文将带你了解IOS开发入门自定义iOS通讯录,希望本文对大家学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频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程