2013-05-13 30 views
8

Trong ứng dụng của tôi, Crashlytics được sử dụng để thu thập các báo cáo sự cố từ người dùng. Đây là một báo cáo sự cố từ người dùng. Nó có thể phụ thuộc vào thông tin liên lạc của người dùng. Tôi không thể tái tạo sự cố, vì tôi không biết những gì có trong danh bạ của anh ấy/cô ấy. Có ai có ý tưởng về tình huống này không?Báo cáo sự cố khi người dùng truy cập sổ địa chỉ

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 

Mã cho 8 SeeYouKee PhoneNumberInputViewController.m line 538-[PhoneNumberInputViewController dofetchContacts:] là:

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:@""] 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])[email protected]"":lastNameMultiValue, (![middleNmaeMultiValue length])[email protected]"":middleNmaeMultiValue, (![firstNmaeMultiValue length])[email protected]"":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:@""] 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])[email protected]"":firstNmaeMultiValue, (![middleNmaeMultiValue length])[email protected]"":middleNmaeMultiValue,(![lastNameMultiValue length])[email protected]"":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]; 
} 

Chỉnh sửa 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); 
} 
+0

Nếu có thể, bạn vui lòng cung cấp biểu mẫu mã nguồn nơi bạn đang tìm nạp địa chỉ liên hệ từ sổ địa chỉ? Vài ngày trở lại ngay cả khi tôi đã nhận được một vụ tai nạn và nó bật ra được phát hành sai của đối tượng Core Foundation. –

+0

@Deepesh Vui lòng kiểm tra cập nhật. –

+0

@Deepesh Tôi nghĩ tôi có lý do. Nó nằm trên ABPersonGetCompositeNameFormat. –

Trả lời

5

Nó có thể được rằng bạn đang gọi điện thoại ABAddressBookCreateWithOptions() và/hoặc ABAddressBookRequestAccessWithCompletion() trên một chủ đề khác nhau từ nơi bạn đang gọi điện thoại ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering()?

Xin lưu ý sau đây từ tài liệu API của Apple:

Việc xử lý hoàn thành được gọi vào một hàng đợi tùy ý. Nếu ứng dụng của bạn sử dụng sổ địa chỉ trong suốt ứng dụng, bạn có trách nhiệm đảm bảo rằng tất cả việc sử dụng sổ địa chỉ đó được gửi đến một hàng đợi duy nhất để đảm bảo hoạt động an toàn cho luồng chính xác.

Nguồn: http://developer.apple.com/library/ios/#documentation/AddressBook/Reference/ABAddressBookRef_iPhoneOS/Reference/reference.html

Ngoài ra, kiểm tra để chắc chắn rằng bạn không sớm phát hành ABAddressBookRef bạn nhận lại từ ABAddressBookCreateWithOptions(). Hãy nhớ rằng ABAddressBookRequestAccessWithCompletion() là không đồng bộ.

+0

Tôi đã chỉnh sửa bài viết, Có thể là vấn đề liên quan đến nếu (addressBookRef! = NULL) CFRelease (addressBookRef); –

6

Tôi thấy rằng các chủ đề đâm là "com.apple.root.default ưu tiên"

ABAddressBook KHÔNG chủ đề an toàn, vì vậy nếu bạn gọi nó từ hai chủ đề khác nhau, nó ném một ngoại lệ và bị treo ứng dụng.

ngay cả khi bạn luôn gửi cuộc gọi đến DISPATCH_QUEUE_PRIORITY_DEFAULT, nó có thể chạy trên hai luồng khác nhau, vì DISPATCH_QUEUE_PRIORITY_DEFAULT không phải là hàng đợi nối tiếp.

Sử dụng này để tạo hàng đợi của bạn nối tiếp mà công văn để DISPATCH_QUEUE_PRIORITY_DEFAULT:

dispatch_queue_t abQueue = dispatch_queue_create("myabqueue", DISPATCH_QUEUE_SERIAL); 
dispatch_set_target_queue(abQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); 

Ghi cử (sync hoặc async) tất cả các cuộc gọi của bạn để giải quyết cuốn sách vào hàng đợi này.

EDIT:

Dường như bạn đang gọi dofetchContacts trong một khối xử lý hoàn thành chuyển vào chức năng ABAddressBookRequestAccessWithCompletion. Đảm bảo gửi cuộc gọi này đến chủ đề chính!

Các tài liệu nói:

Việc xử lý hoàn thành được gọi vào một hàng đợi tùy ý. Nếu ứng dụng của bạn sử dụng sổ địa chỉ trong toàn bộ ứng dụng, bạn chịu trách nhiệm đảm bảo rằng tất cả việc sử dụng sổ địa chỉ đó sẽ được gửi đến một hàng đợi duy nhất để đảm bảo thao tác an toàn theo luồng chính xác.

+0

Trên thực tế "dofetchContacts:" chạy trong chủ đề chính "com.apple.root.default-priority" là một lưu ý từ CrashLytics –

+1

Không, thực sự mã này không chạy trên luồng chính, bởi vì trình xử lý hoàn thành được gọi từ một – Felix

0
- (IBAction)btn_addprofile:(id)sender 
{ 
    // creating the picker 
    ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init]; 
    // place the delegate of the picker to the controll 
    picker.peoplePickerDelegate = self; 

    // showing the picker 

    app.appstart=0; 
    [self presentModalViewController:picker animated:YES]; 
    // releasing 
    [picker release]; 
} 

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker 
{ 
    // assigning control back to the main controller 
    [self dismissModalViewControllerAnimated:YES]; 
} 

- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person { 

    add_profile_screen *viewcontroller=[[add_profile_screen alloc]initWithNibName:@"add_profile_screen" bundle:nil]; 



    // setting the first name 

    NSString *str_f =(NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
    NSString *str_l=(NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); 

    NSLog(@"%@",str_f); 
    NSLog(@"%@",str_l); 

    if([str_f isEqualToString:@""] || [str_l isEqualToString:@""] || !str_f || !str_l) 
    { 
     if([str_f isEqualToString:@""] || !str_f) 
     { 
      viewcontroller.strfirstname=[NSString stringWithFormat:@"%@",str_l]; 
     } 
     else 
     { 
      viewcontroller.strfirstname=[NSString stringWithFormat:@"%@ ",str_f]; 
     } 
    } 
    else 
    { 
     viewcontroller.strfirstname=[NSString stringWithFormat:@"%@ %@",str_f,str_l]; 
    } 

    // viewcontroller.strname=[NSString stringWithFormat:@"%@",(NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty)]; 



    ABMutableMultiValueRef multi = ABRecordCopyValue(person, kABPersonEmailProperty); 
    if (ABMultiValueGetCount(multi) > 0) 
    { 
     // collect all emails in array 
     // for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) 
     for (CFIndex i = 0; i <1; i++) 
     { 
      CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i); 
      viewcontroller.strlastname= (NSString *)emailRef; 
      CFRelease(emailRef); 
     } 
    } 

    // setting the number 
    ABMultiValueRef multi1 = ABRecordCopyValue(person, kABPersonPhoneProperty); 
    viewcontroller.strnumber=[NSString stringWithFormat:@"%@",(NSString*)ABMultiValueCopyValueAtIndex(multi1, 0)]; 
    NSLog(@"%@",viewcontroller.strnumber); 


    [self.navigationController pushViewController:viewcontroller animated:YES]; 
    [viewcontroller release]; 


     // remove the controller 
    [self dismissModalViewControllerAnimated:YES]; 

    return NO; 
} 

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier 
{ 
    return NO; 
} 
Các vấn đề liên quan