0

I'm trying to import vcf file into my address book using ABAddressBook.

First, I read the file, and get NSData:

    NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString *fileName = [documentsDirectory stringByAppendingPathComponent:@"VZAllContactBackup.vcf"];

    NSData *vcardData = [[NSFileManager defaultManager] contentsAtPath:fileName];

    NSInvocationOperation *newoperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(importVcardData:) object:vcardData];
    [serailPhotoQueue addOperation:newoperation];

Then, try to import them using below code:

- (void) importAllVcard: (NSData *)VcardData {

    ABAddressBookRef book = ABAddressBookCreate();
    ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
    CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, (__bridge CFDataRef)(VcardData));

    numberOfContacts = CFArrayGetCount(vCardPeople);

    for (CFIndex index = 0; index < CFArrayGetCount(vCardPeople); index++) {
        @autoreleasepool {
            ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, index);
            ABAddressBookAddRecord(book, person, NULL);
        } 
    }

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

This logic works fine for me when testing, but somehow, I received a lot of crashs on the line:

numberOfContacts = CFArrayGetCount(vCardPeople); // line 76

with below crash report:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Triggered by Thread:  11

...

Thread 11 name:
Thread 11 Crashed:
0   CoreFoundation                  0x0000000181590508 CFArrayGetCount + 36
1   contenttransfer                 0x000000010007ad44 -[VZContactsImport importAllVcard:] (VZContactsImport.m:76)
2   contenttransfer                 0x000000010007ad44 -[VZContactsImport importAllVcard:] (VZContactsImport.m:76)
3   contenttransfer                 0x00000001000865fc -[VZBonjourReceiveDataVC importVcardData:] (VZBonjourReceiveDataVC.m:2228)
4   CoreFoundation                  0x00000001816b8ae0 __invoking___ + 144
5   CoreFoundation                  0x00000001815b0548 -[NSInvocation invoke] + 284
6   Foundation                      0x000000018206c9c4 -[NSInvocationOperation main] + 40
7   Foundation                      0x0000000181faeed8 -[__NSOperationInternal _start:] + 604
8   Foundation                      0x000000018206e904 __NSOQSchedule_f + 224
9   libdispatch.dylib               0x00000001810fd47c _dispatch_client_callout + 16
10  libdispatch.dylib               0x00000001811094c0 _dispatch_queue_drain + 864
11  libdispatch.dylib               0x0000000181100f80 _dispatch_queue_invoke + 464
12  libdispatch.dylib               0x000000018110b390 _dispatch_root_queue_drain + 728
13  libdispatch.dylib               0x000000018110b0b0 _dispatch_worker_thread3 + 112
14  libsystem_pthread.dylib         0x0000000181315470 _pthread_wqthread + 1092
15  libsystem_pthread.dylib         0x0000000181315020 start_wqthread + 4

It seems like the vcardData I read is empty? or when I was trying to write this vcf file, it failed?

NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:@"VZAllContactBackup.vcf"];

[[NSFileManager defaultManager] removeItemAtPath:fileName error:nil];
[receivedData writeToFile:fileName atomically:NO];

Or any other case may cause this issue?

Xin
  • 47
  • 7
  • numberOfContacts is defined as? Most like your VZAllContactBackup.vcf is corrupt or incorrect on actual device. Try replicating the problem on real device – Sam B Aug 19 '16 at 14:59
  • numberOfContacts is defined as NSInteger.@SamB – Xin Aug 19 '16 at 15:01
  • That's not right. It needs to be CFIndex e.g. CFIndex nPeople = CFArrayGetCount(allPeopleArray); – Sam B Aug 19 '16 at 15:02

1 Answers1

0

It looks like ABPersonCreatePeopleInSourceWithVCardRepresentation is returning NULL, so you are crashing on the CFArrayGetCount() call with a NULL dereference. You need to check for NULL. Not sure there is any way to determine why it returned NULL. Perhaps the file didn't exist (too low on disk space to write it?), so you passed a nil data in. Or you tried to do this at a time when the file was still encrypted on disk by Apple's file protection. Or any number of other reasons.

Carl Lindberg
  • 2,902
  • 18
  • 22