vcf, 通讯录导出的一种格式。
一。生成vcf文件
如果要把我们iPhone通讯录里的数据, 生成vcf格式文件。
我们可以借助iCloud。
小技巧:通过iCloud导出iPhone通讯录的方法
当然, 如果你想在应用中, 利用代码生成, 完全可以。先导出通讯录数据, 再解析, 再生成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 : @"")
];
}
}
// 剩下的不常用,我就不写了,要是需要,自己补全
// url
// TODO:
// IM
// TODO:
// Photo
// TODO:
vcard = [vcard stringByAppendingString:@"END:VCARD"];
}
return vcard;
}
二。解析vcf文件
用 UIDocumentInteractionController 也就是用QuickLook去显示这个文件。 那他会自动的解析, 并且有添加到通讯录选项。
当然,我们也可以自己来解析。
具体代码如下:
//解析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);
}
}
}