unable to create a person using VCard representati

2019-04-02 03:26发布

问题:

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

回答1:

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

}



回答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
                    }
        }


回答3:

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


回答4:

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