菜鸟:IOS 学习:磨难记(第五天)
2013-01-20 21:32:15cnblogs.com-fantomlife-点击数:185
消息内容如下:
多项 电话处理:
email处理:
地址处理:
姓,名处理:
头像处理
知识重点:
1、数组
不可变
NSArray*array=[[NSArray alloc] init];
对应
int i = {1, 2,3};
可变
NSMutableArray *mutableArray =[[NSMutableArray alloc] init];
对应
int a[10] = {1};
2、CLASS消息机制 参考文档Cocoa深入检出消息机制
1,首先去该类的方法 cache 中查找,如果找到了就返回它;
2,如果没有找到,就去该类的方法列表中查找。如果在该类的方法列表中找到了,则将 IMP 返回,并将它加入cache中缓存起来。根据最近使用原则,这个方法再次调用的可能性很大,缓存起来可以节省下次调用再次查找的开销。
3,如果在该类的方法列表中没找到对应的 IMP,在通过该类结构中的 super_class指针在其父类结构的方法列表中去查找,直到在某个父类的方法列表中找到对应的IMP,返回它,并加入cache中;
4,如果在自身以及所有父类的方法列表中都没有找到对应的 IMP,则看是不是可以进行动态方法决议;
5,如果动态方法决议没能解决问题,进入消息转发流程
二、分析源码知识重点
1、
ABMultiValueCopyLabelAtIndex 得到手机的多项属性
ABAddressBookCopyLocalizedLabel 得到本地化版本的属性标签
2、CFSTringref 和NSString
CoreFoundation里面的CFStringRef和NSString*是可以直接转换的,两种也都有一个相似的用来直接赋常量的操作。例如:
CFStringRef a = CFSTR("a");
NSString *b = @"b";
CFSTR分配出来的字符串对象是不能自己释放的
b 一个autorelease的对象
3、stringWithString和initWithString
[NSString stringWithString:@""] stringWithString 是类方法,返回一个auto-released的指向NSString的指针,会自动释放,适合临时变量,在一个函数体内部使用
[[NSString alloc] initWithString:@""] initWithString 实例方法,返回一个指向NSString的指针,同时该对象的retain count为1,需要手动释放
4、stringByReplacingOccurrencesOfString
[s stringByReplacingOccurrencesOfString:@"s"withString:@"x"]; //S替换为X
5、ABRecordCopyValue
(__bridgeNSDate *)ABRecordCopyValue(person, kABPersonModificationDateProperty); //最后一次修改該条记录的时间返回记录数据
6、ABRecordCopyCompositeName 返回名称
7、ABAddressBookGetPersonWithRecordID 返回某个人的记录
8、ABMultiValueCopyValueAtIndex 返回指定位置的多值属性
9、[array addObject:...] : 向可变数组尾部添加数据对象。
[array addObjectsFromArray:..] :向可变数组尾部添加一个数组对象。
10、ABPersonHasImageData //表示某人是否有图片
11、ABPersonCopyImageData //返回某人图片
12、
NSData 主要用于数据缓冲
[UIImage imageWithData:data] 创建图片数据
13、ABPersonRemoveImageData 删除图片数据
14、ABPersonSetImageData 设置新图片数据
15、
stringWithFormat 格式化字符串
[NSString stringWithFormat:@"%@", stringName]
16、ABMultiValueAddValueAndLabel //添加多项值到指定标示
17、ABRecordSetValue //添加记录
18、CFDictionaryCreate //创建一个不变的字典
IIAddressBook.h
#import "IIAddressBook.h"@implementation IIAddressBook/** * 得到手机数据 * 1、获取手机lable数据 * 2、转化NSString类型 * 3、替换成正常数据,返回 */// return label, but remove prefix and suffix in "_$!<Mobile>!$_"+ (NSString *)getPhoneLabel:(ABMultiValueRef)phones index:(int)index{ /** * CFStringRef 赋值常量 *ABMultiValueCopyLabelAtIndex 得到手机的多项属性 ABAddressBookCopyLocalizedLabel 得到本地化版本的属性标签 */ CFStringRef origLabel =ABMultiValueCopyLabelAtIndex(phones, index); CFStringRef localizedLabel = ABAddressBookCopyLocalizedLabel(origLabel); /** *改进版 * CFStringRef localizedLabel = ABAddressBookCopyLocalizedLabel(CFAutoRelease(ABMultiValueCopyLabelAtIndex(phones, index)));; **/ //转换为字符串 NSString* finalLabel = [NSString stringWithString:(__bridge NSString *)localizedLabel]; //替换 finalLabel = [finalLabel stringByReplacingOccurrencesOfString:@"_$!<" withString:@""]; finalLabel = [finalLabel stringByReplacingOccurrencesOfString:@">!$_" withString:@""]; //返回处理完的手机数据 return finalLabel;}/** * 返回 最近修改的时间 **/+ (NSDate*)copyModificationDate:(ABRecordRef)person{ //最后一次修改該条记录的时间 NSDate* date = (__bridge NSDate *)ABRecordCopyValue(person, kABPersonModificationDateProperty); return date;}/** * 获取某联系人的名称 * 1、获取某个人的记录 * 2、如果存在数据,调用类消息getFullName处理 */+ (NSString *)getFullName:(ABAddressBookRef)addressBook personId:(int)personId{ //ABAddressBookGetPersonWithRecordID 返回某个人的记录 ABRecordRef personRef =ABAddressBookGetPersonWithRecordID(addressBook, personId); //如果没有数据,跳出 if (!personRef) return nil; else { //如果有数据,调用类消息处理 return[IIAddressBook getFullName:personRef]; }}/** * 获取某联系人名称 * 1、从某个人的记录提取名称 * 2、如果存在数据,转化字符串后返回 */+ (NSString *)getFullName:(ABRecordRef)person{ //ABRecordCopyCompositeName 返回名称 CFStringRef name = ABRecordCopyCompositeName(person); if (name == NULL){ //如果名字为空,跳出 return [NSString stringWithString:@""]; } //转化微字符串 NSString* ret = [NSString stringWithString:(__bridge NSString*)name]; //释放内存 CFRelease(name); //返回名称 return ret;}/** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,调用处理电话的类消息getPhones */+ (NSArray *)getPhonesWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook{ //ABAddressBookGetPersonWithRecordID 返回某个人的记录 ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, personId); if (person){ //有则调用处理电话消息 return [IIAddressBook getPhones:person]; } else { return nil; }}/** * 判断某联系人是否有电话 * 1、调用处理电话消息 getPhones * 2、存在数据,返回YES ,没有返回NO */// get the first phone number to display+ (BOOL)hasPhones:(ABRecordRef)person{ //调用处理电话消息 NSArray* phones = [IIAddressBook getPhones:person]; if (phones != nil && [phones count] > 0){ //返回BOOL return YES; } else { return NO; }}/** * 判断某联系人是否有邮箱 * 1、调用处理邮箱消息 getEmails * 2、存在数据,返回YES ,没有返回NO */+ (BOOL)hasEmails:(ABRecordRef)person{ NSArray* emails = [IIAddressBook getEmails:person]; if (emails != nil && [emails count] > 0){ return YES; } else { return NO; } }/** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串电话数据压入数组 * 3、返回数据 */+ (NSArray *)getPhones:(ABRecordRef)person{ //可变数组初始化 NSMutableArray* phoneList = [[NSMutableArray alloc] init]; //读取电话多值 ABMultiValueRef phones =ABRecordCopyValue(person, kABPersonPhoneProperty); if (phones){ //如果数据存在 int count = ABMultiValueGetCount(phones); //返回电话总数 for (CFIndex i = 0; i < count; i++) { //NSString *phoneLabel = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(phones, i); //转化为多个电话数据为字符串 NSString *phoneNumber = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phones, i); //NSLog(@"phone label (%@), number (%@)", phoneLabel, phoneNumber); //电话数据压入数组 addObject 向可变数组尾部添加数据对象 [phoneList addObject:phoneNumber]; } } //释放内存,返回数据 CFRelease(phones); return phoneList;}/** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串电话数据压入数组 * 3、返回数据 */+ (NSArray *)getEmailsWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook{ //返回某个人的记录 ABRecordRef person =ABAddressBookGetPersonWithRecordID(addressBook, personId); if (person){ //存在回调邮箱处理消息 getEmails return [IIAddressBook getEmails:person]; } else {//没有数据跳出 return nil; }}/** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串邮箱数据压入数组 * 3、返回数据 */// can be refactored to the same implementation later+ (NSArray *)getEmails:(ABRecordRef)person{ //可变数组 NSMutableArray* emailList = [[NSMutableArray alloc] init]; //读取邮箱多值 ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty); if (emails){ //如果有邮箱数据 int emailCount =ABMultiValueGetCount(emails); for (CFIndex i = 0; i < emailCount; i++) { //转化为多个邮箱数据为字符串 NSString *label = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(emails, i); NSString *value = (__bridge NSString *)ABMultiValueCopyValueAtIndex(emails, i); // NSLog(@"email label (%@), number (%@)", label, value); [emailList addObject:value]; } } //释放内存,返回数据 CFRelease(emails); return emailList;}/** * 获取某联系人头像 * 1、初始化图片类型 * 2、判断是否有图片,如果有先读入换缓冲区,在转化微图片类型 * 3、返回图片数据 */+ (UIImage*)getImageByPerson:(ABRecordRef)person{ UIImage* image = nil;//初始化图片类型 if (ABPersonHasImageData(person)){ //表示一人是否有图片 //返回图片到缓冲 NSData* data = (__bridge NSData *)ABPersonCopyImageData(person); image = [UIImage imageWithData:data];//转化图片类型 } return image; }/** * 获取某联系人小头像 * 1没完工 */+ (UIImage*)getSmallImage:(ABRecordRef)person size:(CGSize)size{ UIImage* image = [IIAddressBook getImageByPerson:person]; if (image != nil){ // resize image //return [image imageByScalingAndCroppingForSize:size]; } return nil;}/** * 设置某联系人名称 * 1、读取名,和姓 * 2、设置姓名完整标示,姓,名完整行处理 * 3、根据标示,组合姓名 */+ (NSString*)getShortName:(ABRecordRef)person{ //返回名 NSString* firstName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); //返回姓 NSString* lastName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); //返回公司 NSString* orgName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonOrganizationProperty); BOOL useOrgName = NO; //姓名是否完整标示 if (firstName == nil && lastName == nil) //如果姓名都有,设置YES useOrgName = YES; if (firstName == nil) // 处理名 firstName = @""; if (lastName == nil) //处理姓 lastName = @""; NSString* fullName; //姓名 if (useOrgName == NO){ //如果姓名完整 NSString* countryCode; //是否多国判断 //NSString* countryCode = [LocaleUtils getCountryCode]; if (countryCode != nil && ( [countryCode isEqualToString:@"CN"] == YES || [countryCode isEqualToString:@"TW"] == YES || [countryCode isEqualToString:@"KR"] == YES || [countryCode isEqualToString:@"JP"] == YES) ) { if ([lastName length] > 0){ //如果姓,名有数据,则把姓,名设置给全名变量 fullName = [NSString stringWithFormat:@"%@ %@", lastName, firstName]; } else { //否则把名设置给全名变量 fullName = [NSString stringWithString:firstName]; } }//默认不区分国际 else { if ([firstName length] > 0){ //如果名有数据,则把名设置给全名变量 fullName = [NSString stringWithFormat:@"%@", firstName]; } else { //否则把姓设置给全名变量 fullName = [NSString stringWithString:lastName]; } } } //如果姓名不完整 else { if (orgName == nil) //标示为空 orgName = @""; //格式化标示 fullName = [NSString stringWithFormat:@"%@", orgName]; } //返回姓名 return fullName; }/** * 设置电话 * 1、初始化一些参数 * 2、添加多项值到指定标示 * 3、添加多条记录 */+ (BOOL)addPhone:(ABRecordRef)person phone:(NSString*)phone{ //创建一个新的,空的,可变的多值属性 ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType); CFErrorRef anError = NULL; // The multivalue identifier of the new value isn't used in this example, // multivalueIdentifier is just for illustration purposes. Real-world // code can use this identifier to do additional work with this value. ABMultiValueIdentifier multivalueIdentifier;//多项标示符 //添加多项值到指定标示 if(!ABMultiValueAddValueAndLabel(multi, (__bridge CFStringRef)phone, kABPersonPhoneMainLabel, &multivalueIdentifier)){ CFRelease(multi); return NO; } //添加记录 if (!ABRecordSetValue(person, kABPersonPhoneProperty, multi, &anError)){ CFRelease(multi); return NO; } //释放内存,返回BOOL CFRelease(multi); return YES;}/** * 设置地址 * 1、初始化一些参数 * 2、添加多项值到指定标示 * 3、添加多条记录 */+ (BOOL)addAddress:(ABRecordRef)person street:(NSString*)street{ //创建一个新的,空的,可变的多值属性 ABMutableMultiValueRef address = ABMultiValueCreateMutable(kABDictionaryPropertyType); static int homeLableValueCount = 5; // Set up keys and values for the dictionary. CFStringRef keys[homeLableValueCount];//键数组 CFStringRef values[homeLableValueCount];//值数组 keys[0] = kABPersonAddressStreetKey; //街道 keys[1] = kABPersonAddressCityKey; //城市标示 keys[2] = kABPersonAddressStateKey;//州 keys[3] = kABPersonAddressZIPKey; //邮编 keys[4] = kABPersonAddressCountryKey; //国家 values[0] = (__bridge CFStringRef)street; values[1] = CFSTR(""); values[2] = CFSTR(""); values[3] = CFSTR(""); values[4] = CFSTR(""); //CFDictionaryCreate 创建一个不变的字典 CFDictionaryRef aDict = CFDictionaryCreate( kCFAllocatorDefault, (void *)keys, (void*)values, homeLableValueCount, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); // Add the street address to the person record. ABMultiValueIdentifier identifier; //标示 //添加多项值到指定标示 BOOL result = ABMultiValueAddValueAndLabel(address, aDict, kABHomeLabel, &identifier); CFErrorRef error = NULL; //添加记录 result = ABRecordSetValue(person, kABPersonAddressProperty, address, &error); //释放内存,返回数据 CFRelease(aDict); CFRelease(address); return result;}/** * 设置某联系人头像 * 1、删除旧图片 * 2、设置新的图片,返回图片数据 */+ (BOOL)addImage:(ABRecordRef)person image:(UIImage*)image{ CFErrorRef error = NULL; //错误类型记录 // remove old image data firstly ABPersonRemoveImageData(person, NULL); //删除旧的图片数据 // add new image data 设置新图片数据 BOOL result = ABPersonSetImageData ( person, (__bridge CFDataRef)UIImagePNGRepresentation(image), &error ); // CFRelease(error); return result;}@end
#import <Foundation/Foundation.h>#import <AddressBook/AddressBook.h>//地址薄框架提供联系人数据库,通讯数据库等@interface IIAddressBook : NSObject { }// get label of phone number (e.g. Mobile, Home, etc)/** + 代表类方法 **///得到手机数据 ABMultiValueRef 某一个可能有多个字段数值的记录+ (NSString *)getPhoneLabel:(ABMultiValueRef)phones index:(int)index;// get full name of contact 单个人个名称 ABAddressBookRef 某个通讯录+ (NSString *)getFullName:(ABAddressBookRef)addressBook personId:(int)personId;//某个人的名称 ABRecordRef 某一条通讯录记录+ (NSString *)getFullName:(ABRecordRef)person;// get all phone numbers of one contact 手机号码//获取某联系人全部电话 ABRecordRef 某一条通讯录记录+ (NSArray *)getPhones:(ABRecordRef)person;// get all emails of one contact 邮箱//获取某联系人全部邮箱 ABRecordRef 某一条通讯录记录+ (NSArray *)getEmails:(ABRecordRef)person;// get image of contact//获取某联系人头像 ABRecordRef 某一条通讯录记录+ (UIImage*)getImageByPerson:(ABRecordRef)person;//获取某联系人小头像 ABRecordRef 某一条通讯录记录+ (UIImage*)getSmallImage:(ABRecordRef)person size:(CGSize)size;//设置某联系人名称 ABRecordRef 某一条通讯录记录+ (NSString*)getShortName:(ABRecordRef)person;/** * 类消息 返回最近修改的时间 * ABRecordID 记录的ID int 类型 **/+ (NSDate*)copyModificationDate:(ABRecordRef)person;// set address into contact//设置某联系人地址 ABRecordID 记录的ID int 类型+ (BOOL)addAddress:(ABRecordRef)person street:(NSString*)street;// set phones into contact//设置某联系人电话 ABRecordID 记录的ID int 类型+ (BOOL)addPhone:(ABRecordRef)person phone:(NSString*)phone;// set image into contact//设置某联系人头像 ABRecordID 记录的ID int 类型+ (BOOL)addImage:(ABRecordRef)person image:(UIImage*)image;//判断某联系人邮箱数据 ABRecordID 记录的ID int 类型+ (NSArray *)getEmailsWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook;//判断某联系人电话数据 ABRecordID 记录的ID int 类型+ (NSArray *)getPhonesWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook;//判断某联系人是否有电话 ABRecordRef 某一条通讯录记录+ (BOOL)hasPhones:(ABRecordRef)person;//判断某联系人是否有邮箱 ABRecordRef 某一条通讯录记录+ (BOOL)hasEmails:(ABRecordRef)person;@end
IIAddressBook.m
#import "IIAddressBook.h"@implementation IIAddressBook/** * 得到手机数据 * 1、获取手机lable数据 * 2、转化NSString类型 * 3、替换成正常数据,返回 */// return label, but remove prefix and suffix in "_$!<Mobile>!$_"+ (NSString *)getPhoneLabel:(ABMultiValueRef)phones index:(int)index{ /** * CFStringRef 赋值常量 *ABMultiValueCopyLabelAtIndex 得到手机的多项属性 ABAddressBookCopyLocalizedLabel 得到本地化版本的属性标签 */ CFStringRef origLabel = ABMultiValueCopyLabelAtIndex(phones, index); CFStringRef localizedLabel = ABAddressBookCopyLocalizedLabel(origLabel); /** *改进版 * CFStringRef localizedLabel = ABAddressBookCopyLocalizedLabel(CFAutoRelease(ABMultiValueCopyLabelAtIndex(phones, index)));; **/ //转换为字符串 NSString* finalLabel = [NSString stringWithString:(__bridge NSString *)localizedLabel]; //替换 finalLabel = [finalLabel stringByReplacingOccurrencesOfString:@"_$!<" withString:@""]; finalLabel = [finalLabel stringByReplacingOccurrencesOfString:@">!$_" withString:@""]; //返回处理完的手机数据 return finalLabel;}/** * 返回 最近修改的时间 **/+ (NSDate*)copyModificationDate:(ABRecordRef)person{ //最后一次修改該条记录的时间 NSDate* date = (__bridge NSDate *)ABRecordCopyValue(person, kABPersonModificationDateProperty); return date;}/** * 获取某联系人的名称 * 1、获取某个人的记录 * 2、如果存在数据,调用类消息getFullName处理 */+ (NSString *)getFullName:(ABAddressBookRef)addressBook personId:(int)personId{ //ABAddressBookGetPersonWithRecordID 返回某个人的记录 ABRecordRef personRef = ABAddressBookGetPersonWithRecordID(addressBook, personId); //如果没有数据,跳出 if (!personRef) return nil; else { //如果有数据,调用类消息处理 return [IIAddressBook getFullName:personRef]; }}/** * 获取某联系人名称 * 1、从某个人的记录提取名称 * 2、如果存在数据,转化字符串后返回 */+ (NSString *)getFullName:(ABRecordRef)person{ //ABRecordCopyCompositeName 返回名称 CFStringRef name = ABRecordCopyCompositeName(person); if (name == NULL){ //如果名字为空,跳出 return [NSString stringWithString:@""]; } //转化微字符串 NSString* ret = [NSString stringWithString:(__bridge NSString*)name]; //释放内存 CFRelease(name); //返回名称 return ret;}/** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,调用处理电话的类消息getPhones */+ (NSArray *)getPhonesWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook{ //ABAddressBookGetPersonWithRecordID 返回某个人的记录 ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, personId); if (person){ //有则调用处理电话消息 return [IIAddressBook getPhones:person]; } else { return nil; }}/** * 判断某联系人是否有电话 * 1、调用处理电话消息 getPhones * 2、存在数据,返回YES ,没有返回NO */// get the first phone number to display+ (BOOL)hasPhones:(ABRecordRef)person{ //调用处理电话消息 NSArray* phones = [IIAddressBook getPhones:person]; if (phones != nil && [phones count] > 0){ //返回BOOL return YES; } else { return NO; }}/** * 判断某联系人是否有邮箱 * 1、调用处理邮箱消息 getEmails * 2、存在数据,返回YES ,没有返回NO */+ (BOOL)hasEmails:(ABRecordRef)person{ NSArray* emails = [IIAddressBook getEmails:person]; if (emails != nil && [emails count] > 0){ return YES; } else { return NO; } }/** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串电话数据压入数组 * 3、返回数据 */+ (NSArray *)getPhones:(ABRecordRef)person{ //可变数组初始化 NSMutableArray* phoneList = [[NSMutableArray alloc] init]; //读取电话多值 ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty); if (phones){ //如果数据存在 int count = ABMultiValueGetCount(phones); //返回电话总数 for (CFIndex i = 0; i < count; i++) { //NSString *phoneLabel = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(phones, i); //转化为多个电话数据为字符串 NSString *phoneNumber = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phones, i); //NSLog(@"phone label (%@), number (%@)", phoneLabel, phoneNumber); //电话数据压入数组 addObject 向可变数组尾部添加数据对象 [phoneList addObject:phoneNumber]; } } //释放内存,返回数据 CFRelease(phones); return phoneList;}/** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串电话数据压入数组 * 3、返回数据 */+ (NSArray *)getEmailsWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook{ //返回某个人的记录 ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, personId); if (person){ //存在回调邮箱处理消息 getEmails return [IIAddressBook getEmails:person]; } else { //没有数据跳出 return nil; }}/** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串邮箱数据压入数组 * 3、返回数据 */// can be refactored to the same implementation later+ (NSArray *)getEmails:(ABRecordRef)person{ //可变数组 NSMutableArray* emailList = [[NSMutableArray alloc] init]; //读取邮箱多值 ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty); if (emails){ //如果有邮箱数据 int emailCount = ABMultiValueGetCount(emails); for (CFIndex i = 0; i < emailCount; i++) { //转化为多个邮箱数据为字符串 NSString *label = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(emails, i); NSString *value = (__bridge NSString *)ABMultiValueCopyValueAtIndex(emails, i); // NSLog(@"email label (%@), number (%@)", label, value); [emailList addObject:value]; } } //释放内存,返回数据 CFRelease(emails); return emailList;}/** * 获取某联系人头像 * 1、初始化图片类型 * 2、判断是否有图片,如果有先读入换缓冲区,在转化微图片类型 * 3、返回图片数据 */+ (UIImage*)getImageByPerson:(ABRecordRef)person{ UIImage* image = nil;//初始化图片类型 if (ABPersonHasImageData(person)){ //表示一人是否有图片 //返回图片到缓冲 NSData* data = (__bridge NSData *)ABPersonCopyImageData(person); image = [UIImage imageWithData:data];//转化图片类型 } return image; }/** * 获取某联系人小头像 * 1没完工 */+ (UIImage*)getSmallImage:(ABRecordRef)person size:(CGSize)size{ UIImage* image = [IIAddressBook getImageByPerson:person]; if (image != nil){ // resize image //return [image imageByScalingAndCroppingForSize:size]; } return nil;}/** * 设置某联系人名称 * 1、读取名,和姓 * 2、设置姓名完整标示,姓,名完整行处理 * 3、根据标示,组合姓名 */+ (NSString*)getShortName:(ABRecordRef)person{ //返回名 NSString* firstName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); //返回姓 NSString* lastName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); //返回公司 NSString* orgName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonOrganizationProperty); BOOL useOrgName = NO; //姓名是否完整标示 if (firstName == nil && lastName == nil) //如果姓名都有,设置YES useOrgName = YES; if (firstName == nil) // 处理名 firstName = @""; if (lastName == nil) //处理姓 lastName = @""; NSString* fullName; //姓名 if (useOrgName == NO){ //如果姓名完整 NSString* countryCode; //是否多国判断 //NSString* countryCode = [LocaleUtils getCountryCode]; if (countryCode != nil && ( [countryCode isEqualToString:@"CN"] == YES || [countryCode isEqualToString:@"TW"] == YES || [countryCode isEqualToString:@"KR"] == YES || [countryCode isEqualToString:@"JP"] == YES) ) { if ([lastName length] > 0){ //如果姓,名有数据,则把姓,名设置给全名变量 fullName = [NSString stringWithFormat:@"%@ %@", lastName, firstName]; } else { //否则把名设置给全名变量 fullName = [NSString stringWithString:firstName]; } }//默认不区分国际 else { if ([firstName length] > 0){ //如果名有数据,则把名设置给全名变量 fullName = [NSString stringWithFormat:@"%@", firstName]; } else { //否则把姓设置给全名变量 fullName = [NSString stringWithString:lastName]; } } } //如果姓名不完整 else { if (orgName == nil) //标示为空 orgName = @""; //格式化标示 fullName = [NSString stringWithFormat:@"%@", orgName]; } //返回姓名 return fullName; }/** * 设置电话 * 1、初始化一些参数 * 2、添加多项值到指定标示 * 3、添加多条记录 */+ (BOOL)addPhone:(ABRecordRef)person phone:(NSString*)phone{ //创建一个新的,空的,可变的多值属性 ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType); CFErrorRef anError = NULL; // The multivalue identifier of the new value isn't used in this example, // multivalueIdentifier is just for illustration purposes. Real-world // code can use this identifier to do additional work with this value. ABMultiValueIdentifier multivalueIdentifier;//多项标示符 //添加多项值到指定标示 if (!ABMultiValueAddValueAndLabel(multi, (__bridge CFStringRef)phone, kABPersonPhoneMainLabel, &multivalueIdentifier)){ CFRelease(multi); return NO; } //添加记录 if (!ABRecordSetValue(person, kABPersonPhoneProperty, multi, &anError)){ CFRelease(multi); return NO; } //释放内存,返回BOOL CFRelease(multi); return YES;}/** * 设置地址 * 1、初始化一些参数 * 2、添加多项值到指定标示 * 3、添加多条记录 */+ (BOOL)addAddress:(ABRecordRef)person street:(NSString*)street{ //创建一个新的,空的,可变的多值属性 ABMutableMultiValueRef address = ABMultiValueCreateMutable(kABDictionaryPropertyType); static int homeLableValueCount = 5; // Set up keys and values for the dictionary. CFStringRef keys[homeLableValueCount];//键数组 CFStringRef values[homeLableValueCount];//值数组 keys[0] = kABPersonAddressStreetKey; //街道 keys[1] = kABPersonAddressCityKey; //城市标示 keys[2] = kABPersonAddressStateKey;//州 keys[3] = kABPersonAddressZIPKey; //邮编 keys[4] = kABPersonAddressCountryKey; //国家 values[0] = (__bridge CFStringRef)street; values[1] = CFSTR(""); values[2] = CFSTR(""); values[3] = CFSTR(""); values[4] = CFSTR(""); //CFDictionaryCreate 创建一个不变的字典 CFDictionaryRef aDict = CFDictionaryCreate( kCFAllocatorDefault, (void *)keys, (void *)values, homeLableValueCount, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); // Add the street address to the person record. ABMultiValueIdentifier identifier; //标示 //添加多项值到指定标示 BOOL result = ABMultiValueAddValueAndLabel(address, aDict, kABHomeLabel, &identifier); CFErrorRef error = NULL; //添加记录 result = ABRecordSetValue(person, kABPersonAddressProperty, address, &error); //释放内存,返回数据 CFRelease(aDict); CFRelease(address); return result;}/** * 设置某联系人头像 * 1、删除旧图片 * 2、设置新的图片,返回图片数据 */+ (BOOL)addImage:(ABRecordRef)person image:(UIImage*)image{ CFErrorRef error = NULL; //错误类型记录 // remove old image data firstly ABPersonRemoveImageData(person, NULL); //删除旧的图片数据 // add new image data 设置新图片数据 BOOL result = ABPersonSetImageData ( person, (__bridge CFDataRef)UIImagePNGRepresentation(image), &error ); // CFRelease(error); return result;}@end