unable to create a person using VCard representation
Asked Answered
B

4

2

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

Broca answered 12/1, 2012 at 15:42 Comment(0)
P
2

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);

}

Probable answered 6/2, 2015 at 6:35 Comment(0)
S
2

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
                    }
        }
Sasser answered 22/10, 2015 at 5:54 Comment(4)
should book be addrressBook? i am also getting a built error Variable 'vCard' let vCard: NSData // vcard vCard = code Cannot assign a value of type 'String' to a value of type 'NSData'` How do i cast readableObject.stringValue to readableObject NSData??Pantograph
I need the scanned code (in string) to be converted to NSData ` func foundCode(code: String) { print("Scanned vCard info (code)") // start let vCard: NSData // vcard vCard = code let addressBook: ABAddressBook? = ABAddressBookCreateWithOptions(nil, nil)?.takeRetainedValue()`Pantograph
Ok for those looking for converting link i post my own question nowPantograph
You are right, book should be addressBook , I edited my answer. Please up vote this answer if it works for you.Sasser
H
1

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);
Huckaby answered 15/7, 2012 at 0:12 Comment(0)
C
0

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);
Collateral answered 23/11, 2015 at 17:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.