关闭

ios-vcf格式通讯录的生成和解析(开源),支持5.0以下版本

850人阅读 评论(0) 收藏 举报
分类:
最近研究通讯录同步,做过vcf的亲们都应该知道,苹果5.0之后才推出两个api : ABPersonCreateVCardRepresentationWithPeople 和 ABPersonCreatePeopleInSourceWithVCardRepresentation,但是要某些变态客户要求产品支持4.3的系统(比如我们的大boss),所以我们就必须自己生成和解析vcf文件啦。不熟悉vcf格式的亲们自己问度娘~

话不多说,璐爷我找了枪手帮我写了份代码,自己用了挺好,在此开源分享给大家吧,以下为原创,转载请说明,谢啦~ 以下为一个非常简单demo的.m文件,需要此demo的亲们密我,传给你~

#import "sys/utsname.h"
/*本Demo 专为5哥开发~~*/

@implementation TestAddressBook

//5哥~~ 从这里开始
-(void)testRun {
   //读取本地电话本
   CFArrayRef ref = [self readAddressBook];
   if(ref) {
       //存储vcf文件到本地路径
       NSString* filePath = [self saveVCF:ref];
       if(filePath) {
        //从本地路径读取vcf文件
        [self loadVCF:filePath];
       }
       
    CFRelease(ref);
   }
}

-(CFArrayRef)readAddressBook {
    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef contacts = ABAddressBookCopyArrayOfAllPeople(addressBook);
    [self paintInfo:contacts];
    CFRelease(addressBook);
    return contacts;
}

//5哥,看这里,生成vcf 格式文本
-(NSString*)generateVCardStringWithContacts:(CFArrayRef)contacts {
    NSInteger counter  = 0;
    NSString *vcard = @"";
    
    for(CFIndex i = 0; i < CFArrayGetCount(contacts); i++) {
        
        ABRecordRef person = CFArrayGetValueAtIndex(contacts, i);
        
        NSString *firstName = (NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        firstName = (firstName ? firstName : @"");
        NSString *lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
        lastName = (lastName ? lastName : @"");
        NSString *middleName = (NSString *)ABRecordCopyValue(person, kABPersonMiddleNameProperty);
        NSString *prefix = (NSString *)ABRecordCopyValue(person, kABPersonPrefixProperty);
        NSString *suffix = (NSString *)ABRecordCopyValue(person, kABPersonSuffixProperty);
        NSString *nickName = (NSString *)ABRecordCopyValue(person, kABPersonNicknameProperty);
        NSString *firstNamePhonetic = (NSString *)ABRecordCopyValue(person, kABPersonFirstNamePhoneticProperty);
        NSString *lastNamePhonetic = (NSString *)ABRecordCopyValue(person, kABPersonLastNamePhoneticProperty);
        
        NSString *organization = (NSString *)ABRecordCopyValue(person, kABPersonOrganizationProperty);
        NSString *jobTitle = (NSString *)ABRecordCopyValue(person, kABPersonJobTitleProperty);
        NSString *department = (NSString *)ABRecordCopyValue(person, kABPersonDepartmentProperty);
        
        NSString *compositeName = [NSString stringWithFormat:@"%@%@",firstName,lastName];
        
        if(i > 0) {
            vcard = [vcard stringByAppendingFormat:@"\n"];
        }
        
        vcard = [vcard stringByAppendingFormat:@"BEGIN:VCARD\nVERSION:3.0\nN:%@;%@;%@;%@;%@\n",
                 (firstName ? firstName : @""),
                 (lastName ? lastName : @""),
                 (middleName ? middleName : @""),
                 (prefix ? prefix : @""),
                 (suffix ? suffix : @"")
                 ];
        
        vcard = [vcard stringByAppendingFormat:@"FN:%@\n",compositeName];
        if(nickName) vcard = [vcard stringByAppendingFormat:@"NICKNAME:%@\n",nickName];
        if(firstNamePhonetic) vcard = [vcard stringByAppendingFormat:@"X-PHONETIC-FIRST-NAME:%@\n",firstNamePhonetic];
        if(lastNamePhonetic) vcard = [vcard stringByAppendingFormat:@"X-PHONETIC-LAST-NAME:%@\n",lastNamePhonetic];
        
        // Work
        if(organization) vcard = [vcard stringByAppendingFormat:@"ORG:%@;%@\n",(organization?organization:@""),(department?department:@"")];
        
        if(jobTitle) vcard = [vcard stringByAppendingFormat:@"TITLE:%@\n",jobTitle];
        
        // Mail
        ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
        if(emails) {
            for (int k = 0; k < ABMultiValueGetCount(emails); k++) {
                NSString *label = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(emails, k));
                NSString *email = (NSString *)ABMultiValueCopyValueAtIndex(emails, k);
                NSString *labelLower = [label lowercaseString];
                
                vcard = [vcard stringByAppendingFormat:@"EMAIL;type=INTERNET;type=WORK:%@\n",email];
                
                if ([labelLower isEqualToString:@"home"]) vcard = [vcard stringByAppendingFormat:@"EMAIL;type=INTERNET;type=HOME:%@\n",email];
                else if ([labelLower isEqualToString:@"work"]) vcard = [vcard stringByAppendingFormat:@"EMAIL;type=INTERNET;type=WORK:%@\n",email];
                else {//类型解析不出来的
                    counter++;
                    vcard = [vcard stringByAppendingFormat:@"item%d.EMAIL;type=INTERNET:%@\nitem%d.X-ABLabel:%@\n",counter,email,counter,label];
                }
            }
        }
        
        // Tel
        ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
        if(phoneNumbers) {
            for (int k = 0; k < ABMultiValueGetCount(phoneNumbers); k++) {
                NSString *label = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phoneNumbers, k));
                NSString *number = (NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, k);
                NSString *labelLower = [label lowercaseString];
                
                if ([labelLower isEqualToString:@"mobile"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=CELL:%@\n",number];
                else if ([labelLower isEqualToString:@"home"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=HOME:%@\n",number];
                else if ([labelLower isEqualToString:@"work"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=WORK:%@\n",number];
                else if ([labelLower isEqualToString:@"main"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=MAIN:%@\n",number];
                else if ([labelLower isEqualToString:@"homefax"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=HOME;type=FAX:%@\n",number];
                else if ([labelLower isEqualToString:@"workfax"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=WORK;type=FAX:%@\n",number];
                else if ([labelLower isEqualToString:@"pager"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=PAGER:%@\n",number];
                else if([labelLower isEqualToString:@"other"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=OTHER:%@\n",number];
                else { //类型解析不出来的
                    counter++;
                    vcard = [vcard stringByAppendingFormat:@"item%d.TEL:%@\nitem%d.X-ABLabel:%@\n",counter,number,counter,label];
                }
            }
        }
        
        // Address
        ABMultiValueRef address = ABRecordCopyValue(person, kABPersonAddressProperty);
        if(address) {
            for (int k = 0; k < ABMultiValueGetCount(address); k++) {
                NSString *label = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(label, k));
                NSDictionary *dic = (NSDictionary *)ABMultiValueCopyLabelAtIndex(address, k);
                NSString *labelLower = [label lowercaseString];
                NSString* country = [dic valueForKey:(NSString *)kABPersonAddressCountryKey];
                NSString* city = [dic valueForKey:(NSString *)kABPersonAddressCityKey];
                NSString* state = [dic valueForKey:(NSString *)kABPersonAddressStateKey];
                NSString* street = [dic valueForKey:(NSString *)kABPersonAddressStreetKey];
                NSString* zip = [dic valueForKey:(NSString *)kABPersonAddressZIPKey];
                NSString* countryCode = [dic valueForKey:(NSString *)kABPersonAddressCountryCodeKey];
                NSString *type = @"";
                NSString *labelField = @"";
                counter++;
                
                if([labelLower isEqualToString:@"work"]) type = @"WORK";
                else if([labelLower isEqualToString:@"home"]) type = @"HOME";
                else if(label && [label length] > 0)
                {
                    labelField = [NSString stringWithFormat:@"item%d.X-ABLabel:%@\n",counter,label];
                }
                
                vcard = [vcard stringByAppendingFormat:@"item%d.ADR;type=%@:;;%@;%@;%@;%@;%@\n%@item%d.X-ABADR:%@\n",
                         counter,
                         type,
                         (street ? street : @""),
                         (city ? city : @""),
                         (state ? state : @""),
                         (zip ? zip : @""),
                         (country ? country : @""),
                         labelField,
                         counter,
                         (countryCode ? countryCode : @"")
                         ];
            }
        }
        
        
        // 5哥,剩下的不常用,我就不写了,要是需要,自己补全
        // url
        // TODO:
        
        // IM
        // TODO:
        
        // Photo
        // TODO:
        
        vcard = [vcard stringByAppendingString:@"END:VCARD"];
    }

    return vcard;
}

//5哥,这个是解析vcf文件
-(void)parseVCardString:(NSString*)vcardString {
    NSArray *lines = [vcardString componentsSeparatedByString:@"\n"];
    
    for(NSString* line in lines) {
        
        if ([line hasPrefix:@"BEGIN"]) {
            NSLog(@"parse start");
        } else if ([line hasPrefix:@"END"]) {
            NSLog(@"parse end");
        } else if ([line hasPrefix:@"N:"]) {
            NSArray *upperComponents = [line componentsSeparatedByString:@":"];
            NSArray *components = [[upperComponents objectAtIndex:1] componentsSeparatedByString:@";"];
            
            NSString * lastName = [components objectAtIndex:0];
            NSString * firstName = [components objectAtIndex:1];
            
            NSLog(@"name %@ %@",lastName,firstName);
            
        } else if ([line hasPrefix:@"EMAIL;"]) {
            NSArray *components = [line componentsSeparatedByString:@":"];
            NSString *emailAddress = [components objectAtIndex:1];
            NSLog(@"emailAddress %@",emailAddress);
            
        } else if ([line hasPrefix:@"TEL;"]) {
            NSArray *components = [line componentsSeparatedByString:@":"];
            NSString *phoneNumber = [components objectAtIndex:1];
            NSLog(@"phoneNumber %@",phoneNumber);
        }
    }

}

-(NSString*)saveVCF:(CFArrayRef)contacts {

    NSString *str = @"";
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) { // 5.0版本用系统自带的
        CFDataRef vcards = (CFDataRef)ABPersonCreateVCardRepresentationWithPeople(contacts);
        str = [[NSString alloc] initWithData:(NSData *)vcards encoding:NSUTF8StringEncoding];
        CFRelease(vcards);
    }
    else { //4.x 代码在这里哦~
        str = [self generateVCardStringWithContacts:contacts];
    }
    
    NSLog(@"save vcf str %@",str);
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *folderPath = [paths objectAtIndex:0];
    NSString *filePath = [folderPath stringByAppendingPathComponent:@"contacts.vcf"];
    [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"save vcf to path %@",filePath);
    return filePath;
}

-(void)loadVCF:(NSString*)filePath {
    
    NSString* str = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) { // 5.0版本用系统自带的
        NSLog(@"load vcf str %@",str);
   
        CFDataRef vcardData = (CFDataRef)CFBridgingRetain([str dataUsingEncoding:NSUTF8StringEncoding]);
        ABAddressBookRef book = ABAddressBookCreate();
        ABRecordRef ref = ABAddressBookCopyDefaultSource(book);
        CFArrayRef contacts = ABPersonCreatePeopleInSourceWithVCardRepresentation(ref, vcardData);
        NSLog(@"load vcf form path %@",filePath);
        [self paintInfo:contacts];
   
        CFRelease(vcardData);
        CFRelease(book);
        CFRelease(ref);
    }
    else { //4.x 代码在这里哦~
        [self parseVCardString:str];
    }
    
}

-(void)paintInfo:(CFArrayRef)contacts {
    
    for(CFIndex i = 0; i < CFArrayGetCount(contacts); i++) {
        ABRecordRef person = CFArrayGetValueAtIndex(contacts, i);
        
        NSString *firstName = (NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        NSLog(@"first name: %@",firstName);
        
        NSString *lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
        NSLog(@"last name: %@",lastName);
        
        ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
        if(phones) {
            for (int k = 0; k < ABMultiValueGetCount(phones); k++) {
                NSString *phoneMobile = (NSString *)ABMultiValueCopyValueAtIndex(phones, 0);
                NSLog(@"mobile: %@",phoneMobile);
                
                NSString *label = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phones, k));
                if(label)
                NSLog(@"label: %@",label);
            }
        }
        
        ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
        if(emails) {
            for (int i = 0; i < ABMultiValueGetCount(emails); i++) {
                NSString *workEmail = (NSString *)ABMultiValueCopyValueAtIndex(emails, 0);
                NSLog(@"email: %@",workEmail);
            }
        }
    }
}

@end
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:43629次
    • 积分:901
    • 等级:
    • 排名:千里之外
    • 原创:47篇
    • 转载:3篇
    • 译文:0篇
    • 评论:18条
    文章分类
    最新评论