I am developing an app using XCode 4.2 and I am trying to create an ABPerson using initWithVCardRepresentation and/or ABPersonCreatePeopleInSourceWithVCardRepresentation , but I can t find a working example . can someone help?
I get the VCard in an NSString format....
Thanks
This is a full example and it works perfectly, it bases on the latest iOS 8.
First of all you should check authorization status and request access right if not, then save the vcard, let just review the code below:
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized){
NSLog(@"Authorized");
[self addVcardsIntoAddressBook:vcard];
} else{
NSLog(@"Not determined");
ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool granted, CFErrorRef error) {
if (!granted){
NSLog(@"Just denied");
return;
}
NSLog(@"Just authorized");
[self addVcardsIntoAddressBook:vcard];
});
}
This is how to add vcard:
- (void)addVcardsIntoAddressBook:(NSData *)vcard {
CFDataRef vCardData = CFDataCreate(NULL, [vcard bytes], [vcard length]);
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(person);
}
ABAddressBookSave(book, NULL);
}
Here it is Swift version of acoustic's answer;
let vCard : NSData // vcard
let addressBook: ABAddressBook? = ABAddressBookCreateWithOptions(nil, nil)?.takeRetainedValue()
ABAddressBookRequestAccessWithCompletion(addressBook) {
granted, error in
if !granted {
return
}
let vCardData = CFDataCreate(nil, UnsafePointer<UInt8>(vCard.bytes), vCard.length)
let defaultSource = ABAddressBookCopyDefaultSource(addressBook)
let vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource.takeUnretainedValue(), vCardData).takeRetainedValue() as NSArray
for person in vCardPeople {
ABAddressBookAddRecord(addressBook, person, nil)
}
let isSaved = ABAddressBookSave(addressBook, nil)
if isSaved{
//succesfully saved
}
else{
//not saved
}
}
I'm using this code that I found somewhere on a forum:
// Assuming your vCard is stored in vCardString as an NSString
CFDataRef vCardData = (__bridge CFDataRef)[vCardString dataUsingEncoding:NSUTF8StringEncoding];
ABAddressBookRef book = ABAddressBookCreate();
ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
CFIndex index = 0;
ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, index);
I am using it and it is working fine with Vcard 2.1 and 3.0
NSString *filename = [[NSBundle mainBundle] pathForResource:@"Contacts" ofType:@"vcf"];
NSLog(@"openning file %@", filename);
NSData *stringData = [NSData dataWithContentsOfFile:filename];
NSString *vCardString = [[NSString alloc] initWithData:stringData encoding:NSUTF8StringEncoding];
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);