Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding vCard data directly to the system Address Book

I am designing a QR code reader, and it needs to detect and import contact cards in vCard format (.vcf).

is there a way to add the card data to the system Address Book directly, or do I need to parse the vCard myself and add each field individually?

like image 586
user1044771 Avatar asked Nov 14 '11 01:11

user1044771


3 Answers

If you're running on iOS 5 or later, this code should do the trick:

#import <AddressBook/AddressBook.h>

// This gets the vCard data from a file in the app bundle called vCard.vcf
//NSURL *vCardURL = [[NSBundle bundleForClass:self.class] URLForResource:@"vCard" withExtension:@"vcf"];
//CFDataRef vCardData = (CFDataRef)[NSData dataWithContentsOfURL:vCardURL];

// This version simply uses a string. I'm assuming you'll get that from somewhere else.
NSString *vCardString = @"vCardDataHere";
// This line converts the string to a CFData object using a simple cast, which doesn't work under ARC
CFDataRef vCardData = (CFDataRef)[vCardString dataUsingEncoding:NSUTF8StringEncoding];
// If you're using ARC, use this line instead:
//CFDataRef vCardData = (__bridge CFDataRef)[vCardString dataUsingEncoding:NSUTF8StringEncoding];

ABAddressBookRef book = ABAddressBookCreate();
ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
for (CFIndex index = 0; index < CFArrayGetCount(vCardPeople); index++) {
    ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, index);
    ABAddressBookAddRecord(book, person, NULL);
}

CFRelease(vCardPeople);
CFRelease(defaultSource);
ABAddressBookSave(book, NULL);
CFRelease(book);

Make sure to link to the AddressBook framework in your project.

like image 133
Carter Allen Avatar answered Oct 21 '22 08:10

Carter Allen


Carter Allen's answer worked for me except that it caused my app to crash on the final statement CFRelease(book);

It turns out that the CFRelease(person); statement should be removed. Doing so stopped my app from crashing. See this answer for explanation https://stackoverflow.com/a/1337086/881103

Also checkout The Create Rule and The Get Rule sections on this page https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html

like image 20
Tom Epps Avatar answered Oct 21 '22 08:10

Tom Epps


Contacts is pretty forgiving and will do its best to import your vCard, however it seems that your address is not correct. There should be 7 parameters, separated by semicolons: PO box, Suite #, street address, city, state, ZIP, country. Most people leave off the PO box (and suite #), which is why a typical address has a semicolon (or two) at the beginning. If your address is ill-formed, parameters might end up in the wrong places.

The various fields in a vCard are terminated by a <return>: @"\r"

You don't need CHARSET=utf-8

like image 22
Cliff Harris Avatar answered Oct 21 '22 09:10

Cliff Harris