Search code examples
objective-ccontactsaddressbookvcf-vcard

Exporting all contacts in one .vcf file using Contacts.Framework in Objective - C


Using I AddressBook.framework I used to create Contacts.vcf from all contacts and save it in Documents Directory. Here is the code I used to use :

ABAddressBookRef addressBook1 = ABAddressBookCreate();
NSArray *arrayOfAllPeople = (__bridge_transfer NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook1);
long cnt = (unsigned long)[arrayOfAllPeople count];
if (cnt==0) {

    ABAddressBookRequestAccessWithCompletion(addressBook1, nil);

}

if(ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
{
    ABAddressBookRef addressBook2 = ABAddressBookCreate();


    CFArrayRef contacts = ABAddressBookCopyArrayOfAllPeople(addressBook2);
    CFDataRef vcards = (CFDataRef)ABPersonCreateVCardRepresentationWithPeople(contacts);


    NSString *vcardString = [[NSString alloc] initWithData:(__bridge NSData *)vcards encoding:NSUTF8StringEncoding];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *folderPath = [paths objectAtIndex:0];
    NSString *filePath = [folderPath stringByAppendingPathComponent:@"Contacts.vcf"];
    [vcardString writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    CFRelease(addressBook2); }

How do I create a Contacts.vcf file having all device contacts using Contacts.framework and save it in documents directory ?


Solution

  • You can use this method to get all the contacts in .vcf file. It return the same output that you get using AddressBook.framework.

    - (void)getContacts {
        NSMutableArray *contactsArray=[[NSMutableArray alloc] init];
        CNContactStore *store = [[CNContactStore alloc] init];
        [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (!granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                });
                return;
            }
            NSMutableArray *contacts = [NSMutableArray array];
    
            NSError *fetchError;
    
            CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[[CNContactVCardSerialization descriptorForRequiredKeys], [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]]];
    
            BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
                [contacts addObject:contact];
            }];
            if (!success) {
                NSLog(@"error = %@", fetchError);
            }
    
            // you can now do something with the list of contacts, for example, to show the names
    
            CNContactFormatter *formatter = [[CNContactFormatter alloc] init];
    
            for (CNContact *contact in contacts) {
    
                [contactsArray addObject:contact];
                // NSString *string = [formatter stringFromContact:contact];
    
                //NSLog(@"contact = %@", string);
            }
    
            //NSError *error;
            NSData *vcardString =[CNContactVCardSerialization dataWithContacts:contactsArray error:&error];
    
            NSString* vcardStr = [[NSString alloc] initWithData:vcardString encoding:NSUTF8StringEncoding];
            NSLog(@"vcardStr = %@",vcardStr);
    
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *folderPath = [paths objectAtIndex:0];
            NSString *filePath = [folderPath stringByAppendingPathComponent:@"Contacts.vcf"];
            [vcardStr writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
        }];
    }