In my App, Crashlytics is used to gather crash reports from users. Here is one crash report from a user. It is possibly depending on the contacts informations of the user. I can not recreate the crash, as I do not know what's in his/her contacts. Does any one has an idea about this situation?
com.apple.root.default-priority Crashed
0 CoreFoundation CFStringCreateCopy + 13
1 AppSupport CPSqliteDatabaseCreateWithPath + 36
2 AppSupport CPSqliteDatabaseCreateWithPath + 36
3 AppSupport CPRecordStoreGetDatabase + 16
4 AppSupport _getReaderConnection + 10
5 AppSupport CPRecordStoreProcessQueryWithBindBlock + 22
6 AppSupport CPRecordStoreCopyAllInstancesOfClassWhereWithBindBlock + 98
7 AddressBook ABCCopyArrayOfAllPeopleInSourceWithSortOrdering + 244
8 SeeYouKee PhoneNumberInputViewController.m line 538-[PhoneNumberInputViewController dofetchContacts:]
9 AddressBook __37-[ABTCC accessRequestWithCompletion:]_block_invoke_0 + 26
10 TCC __TCCAccessRequest_block_invoke_038 + 316
11 ... libxpc.dylib _xpc_connection_call_reply + 26
12 libdispatch.dylib _dispatch_root_queue_drain + 278
13 libdispatch.dylib _dispatch_worker_thread2 + 92
14 libsystem_c.dylib _pthread_wqthread + 360
The code for 8 SeeYouKee PhoneNumberInputViewController.m line 538-[PhoneNumberInputViewController dofetchContacts:]
is:
NSArray *contactsInAddressBook = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, kABPersonSortByLastName));
EDIT 1
-(void)dofetchContacts:(ABAddressBookRef)addressBook{
NSMutableArray *contactMutArr = [NSMutableArray array];
NSMutableString *mStrOfContacts = [NSMutableString string];
NSArray *contactsInAddressBook = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, kABPersonSortByLastName));
if (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatLastNameFirst) {
for (id aPerson in contactsInAddressBook) {
ABRecordRef person = (__bridge ABRecordRef)(aPerson);
ABMultiValueRef phoneMultiValue = ABRecordCopyValue(person, kABPersonPhoneProperty);
ABMultiValueRef emailMultiValue = ABRecordCopyValue(person, kABPersonEmailProperty);
int countPhone = 0;
int countEmail = 0;
NSMutableArray *phoneStrArr;
NSMutableArray *emailStrArr;
if (phoneMultiValue != NULL) {
countPhone = ABMultiValueGetCount(phoneMultiValue);
}
if (emailMultiValue != NULL) {
countEmail = ABMultiValueGetCount(emailMultiValue);
}
if (countEmail>0) {
emailStrArr = [NSMutableArray array];
for (int i = 0; i < countEmail; i++) {
CFStringRef anEmailCF = ABMultiValueCopyValueAtIndex(emailMultiValue, i);
NSString *anEmail = (__bridge NSString *)anEmailCF;
[emailStrArr addObject:anEmail];
if (anEmailCF != NULL)CFRelease(anEmailCF);
}
}
if (countPhone > 0) {
phoneStrArr = [NSMutableArray array];
for (int i = 0; i < countPhone; i++) {
CFStringRef anPhoneCF = ABMultiValueCopyValueAtIndex(phoneMultiValue, i);
NSString *anPhone = (__bridge NSString *)anPhoneCF;
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
NSString *anPhonePureNumber = [[anPhone componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
[phoneStrArr addObject:anPhonePureNumber];
if (anPhoneCF != NULL)CFRelease(anPhoneCF);
}
}
// if (arrRefOfEmails != NULL)CFRelease(arrRefOfEmails);
CFStringRef lastNameMultiValueCF = ABRecordCopyValue(person, kABPersonLastNameProperty);
CFStringRef firstNmaeMultiValueCF = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef middleNmaeMultiValueCF = ABRecordCopyValue(person, kABPersonMiddleNameProperty);
NSString *lastNameMultiValue = (__bridge NSString *)lastNameMultiValueCF;
NSString *firstNmaeMultiValue = (__bridge NSString *)firstNmaeMultiValueCF;
NSString *middleNmaeMultiValue = (__bridge NSString *)middleNmaeMultiValueCF;
NSString *name = [NSString stringWithFormat:@"%@%@%@",(![lastNameMultiValue length])?@"":lastNameMultiValue, (![middleNmaeMultiValue length])?@"":middleNmaeMultiValue, (![firstNmaeMultiValue length])?@"":firstNmaeMultiValue];
if (lastNameMultiValueCF != NULL)CFRelease(lastNameMultiValueCF);
if (firstNmaeMultiValueCF != NULL)CFRelease(firstNmaeMultiValueCF);
if (middleNmaeMultiValueCF != NULL)CFRelease(middleNmaeMultiValueCF);
CFDataRef anAvatarCF = ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail);
NSData *anAvatarData = (__bridge NSData *)anAvatarCF;
UIImage *anAvatar = [UIImage imageWithData:anAvatarData];
if (anAvatarCF != NULL)CFRelease(anAvatarCF);
NSDictionary *aPersonDict = [NSDictionary dictionaryWithObjectsAndKeys:name, @"name", [phoneStrArr componentsJoinedByString:@"; "], @"phoneNumber", [emailStrArr componentsJoinedByString:@"; "], @"email", anAvatar, @"avatar", nil];
[contactMutArr addObject:aPersonDict];
NSLog(@"------phoneStrArr :%@",phoneStrArr);
NSString *enPhoneNumber = @"";
if (phoneStrArr) {
enPhoneNumber = [EncryptWithMD5 encryptWithMD5: [phoneStrArr componentsJoinedByString:@"; "]];
}
[mStrOfContacts appendString:enPhoneNumber];
[mStrOfContacts appendString:@", "];
if (phoneMultiValue != NULL)CFRelease(phoneMultiValue);
if (emailMultiValue != NULL)CFRelease(emailMultiValue);
}
}else{
for (id aPerson in contactsInAddressBook) {
ABRecordRef person = (__bridge ABRecordRef)(aPerson);
ABMultiValueRef phoneMultiValue = ABRecordCopyValue(person, kABPersonPhoneProperty);
ABMultiValueRef emailMultiValue = ABRecordCopyValue(person, kABPersonEmailProperty);
int countEmail = 0;
NSMutableArray *emailStrArr;
NSMutableArray *phoneStrArr;
if (emailMultiValue != NULL) {
countEmail = ABMultiValueGetCount(emailMultiValue);
}
if (countEmail>0) {
emailStrArr = [NSMutableArray array];
for (int i = 0; i < countEmail; i++) {
CFStringRef anEmailCF = ABMultiValueCopyValueAtIndex(emailMultiValue, i);
NSString *anEmail = (__bridge NSString *)anEmailCF;
[emailStrArr addObject:anEmail];
if (anEmailCF != NULL)CFRelease(anEmailCF);
}
}
int count = ABMultiValueGetCount(phoneMultiValue);
if (count > 0) {
phoneStrArr = [NSMutableArray array];
for (int i = 0; i < count; i++) {
CFStringRef anPhoneCF = ABMultiValueCopyValueAtIndex(phoneMultiValue, i);
NSString *anPhone = (__bridge NSString *)anPhoneCF;
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
NSString *anPhonePureNumber = [[anPhone componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
[phoneStrArr addObject:anPhonePureNumber];
if (anPhoneCF != NULL)CFRelease(anPhoneCF);
}
}
CFStringRef lastNameMultiValueCF = ABRecordCopyValue(person, kABPersonLastNameProperty);
CFStringRef firstNmaeMultiValueCF = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef middleNmaeMultiValueCF = ABRecordCopyValue(person, kABPersonMiddleNameProperty);
NSString *lastNameMultiValue = (__bridge NSString *)lastNameMultiValueCF;
NSString *firstNmaeMultiValue = (__bridge NSString *)firstNmaeMultiValueCF;
NSString *middleNmaeMultiValue = (__bridge NSString *)middleNmaeMultiValueCF;
NSString *name = [NSString stringWithFormat:@"%@%@%@", (![firstNmaeMultiValue length])?@"":firstNmaeMultiValue, (![middleNmaeMultiValue length])?@"":middleNmaeMultiValue,(![lastNameMultiValue length])?@"":lastNameMultiValue];
if (lastNameMultiValueCF != NULL)CFRelease(lastNameMultiValueCF);
if (firstNmaeMultiValueCF != NULL)CFRelease(firstNmaeMultiValueCF);
if (middleNmaeMultiValueCF != NULL)CFRelease(middleNmaeMultiValueCF);
CFDataRef anAvatarCF = ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail);
NSData *anAvatarData = (__bridge NSData *)anAvatarCF;
UIImage *anAvatar = [UIImage imageWithData:anAvatarData];
if (anAvatarCF != NULL)CFRelease(anAvatarCF);
NSDictionary *aPersonDict = [NSDictionary dictionaryWithObjectsAndKeys:name, @"name", [phoneStrArr componentsJoinedByString:@"; "], @"phoneNumber", [emailStrArr componentsJoinedByString:@"; "], @"email", anAvatar, @"avatar", nil];
[contactMutArr addObject:aPersonDict];
NSString *enPhoneNumber = [EncryptWithMD5 encryptWithMD5: [phoneStrArr componentsJoinedByString:@"; "]];
[mStrOfContacts appendString:enPhoneNumber];
[mStrOfContacts appendString:@", "];
if (phoneMultiValue != NULL)CFRelease(phoneMultiValue);
if (emailMultiValue != NULL)CFRelease(emailMultiValue);
}
}
self.contactArr = [[NSArray alloc] initWithArray: contactMutArr];
strOfContacts = [NSString stringWithString:mStrOfContacts];
}
Edit 2
-(void)beginFetchContacts{
// Request authorization to Address Book
ABAddressBookRef addressBookRef = NULL;
if (ABAddressBookRequestAccessWithCompletion) {
CFErrorRef *aError=nil;
addressBookRef = ABAddressBookCreateWithOptions(NULL, aError);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
// First time access has been granted, add the contact
if (granted) {
[self dofetchContacts:addressBookRef];
}else{
// [self alertActionSwitchOnTheContactsAccess];
[self buttonCancelPressed:nil];
}
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
// The user has previously given access, add the contact
[self dofetchContacts:addressBookRef];
}
}else{
addressBookRef = ABAddressBookCreate();
[self dofetchContacts:addressBookRef];
}
if (addressBookRef != NULL)CFRelease(addressBookRef);
}