vcf, 通訊錄導出的一種格式。
如果要把我們iPhone通訊錄裡的數據, 生成vcf格式文件。
我們可以借助iCloud。
參考下面代碼:
-(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; }
用 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); } } }