你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 如何自定義iOS通訊錄

如何自定義iOS通訊錄

編輯:IOS開發綜合

蘋果給用戶提供了自己的通訊錄,但是根據業務的需求,需要自定義通訊錄,我們就需要根據業務需求來自定義。
首先我們需要知道蘋果的提供的一些Foundation、UIKit框架,了解其中的一些特性,可以打開手機查看蘋果系統提供的原生的通訊錄,可以看到:

1.搜索框
2.右側搜索條
3.聯系人分組
4.添加聯系人
5.獲取聯系人頭像及聯系方式

根據需求,可以總結出自定義通訊錄需要做的一些功能,一項大的功能可以差分成一些小的功能,然後一個一個實現,將復雜的問題差分成小問題解決。

1.自定義搜索框
2.獲取首字母
3.權限判斷
4.排序
5.自定義搜索
6.自定義聯系人界面
(考慮多值的情況,獲取通訊錄頭像)

簡答介紹下排序:

IOS項目中會用到對通訊錄的聯系人或是會員按姓名為關鍵字排序,因為NSArray並不直接支持對漢字的排序,這就要通過將漢字轉換成拼音完成按A~Z的排序,這看起來是個頭疼的問題,因為牽扯到漢字轉為拼音,獲取漢字的首字的首字母,如將“王”變成“W”。

函數原理是:我們知道,在Objective C語言中,字符串是以unicode進行編碼的。在unicode字符集中,漢字的編碼范圍為4E00 到 9FA5 之間(即從第19968開始的20902個字符是中文簡體字符)。我們把這些字符的拼音首字母按照順序都存放在一個char數組中。當我們查找一個漢字的拼音首字母時,只需把這個漢字的unicode碼(即char強制轉換為int)減去19968,然後用這個數字作為索引去找char數組中存放的字母即可。
給出項目的源碼,注釋很清楚。代碼如:
RYAddressBook.h

#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 

RYAddressBook.m

#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

#import <Foundation/Foundation.h> 
#import <AddressBook/AddressBook.h> 
 
@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) 
// iMessage 
PROPERTY_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 

RYPersonInfo.m

#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 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved