I'm seeing a weird crash after calling "[MFMailComposeViewController canSendMail]".
I cannot reproduce it, it's from iTunesConnect. That method (canSendMail) is being called from the main thread, and at that point, i'm not doing anything with the address book.
Any idea / suggestion will be VERY MUCH appreciated.
Thanks in advance!
Note: This happened in iOS 5.1.1.
Exception Type: SIGABRT
Exception Codes: #0 at 0x3583232c
Crashed Thread: 0
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x3583232c __pthread_kill + 8
1 libsystem_c.dylib 0x347e729f abort + 95
2 AppSupport 0x3133cc57 abortAfterFailingIntegrityCheck + 39
3 AppSupport 0x3133ceef runIntegrityCheckAndAbort + 535
4 AppSupport 0x3133d025 checkResultWithStatement + 113
5 AppSupport 0x3133ea13 _connectAndCheckVersion + 1059
6 AppSupport 0x3133eab7 CPSqliteDatabaseConnectionForWriting + 43
7 AppSupport 0x3133eb8d CPSqliteDatabaseRegisterFunction + 21
8 AddressBook 0x337873f7 ABCDBContextCreateWithPathAndAddressBook + 215
9 AddressBook 0x3377b429 ABCCreateAddressBookWithDatabaseDirectoryAndForceInProcessMigrationInProcessLinkingAndResetSortKeys + 233
10 AddressBook 0x33789cd7 ABAddressBookCreate + 15
11 Message 0x31072453 MFThreadLocalAddressBook + 87
12 MessageUI 0x313a5471 +[MFMailComposeController initialize] + 9
13 libobjc.A.dylib 0x35edc973 _class_initialize + 239
14 libobjc.A.dylib 0x35edc87b prepareForMethodLookup + 143
15 libobjc.A.dylib 0x35edc747 lookUpMethod + 47
16 libobjc.A.dylib 0x35edc713 _class_lookupMethodAndLoadCache3 + 19
17 libobjc.A.dylib 0x35edbfcb objc_msgSend_uncached + 27
18 MessageUI 0x313a5455 +[MFMailComposeViewController canSendMail] + 33
=============
UPDATE:
The snippet of code that causes this crash is the following:
-(IBAction)helpButtonPressed
{
if([MFMailComposeViewController canSendMail])
{
NSString* mail = self.feedbackSettings[@"mail"];
NSString* title = self.feedbackSettings[@"title"];
MFMailComposeViewController* mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
mailComposer.toRecipients = @[ mail ];
mailComposer.subject = title;
[self presentViewController:mailComposer animated:YES completion:nil];
[mailComposer release], mailComposer = nil;
}
else
{
[UIAlertView showAlertViewWithTitle:nil message:NSLocalizedString(@"Please, setup a mail account in your phone first.", nil) buttonTitle:NSLocalizedString(@"OK", nil)];
}
}
I recently saw a crash report from a customer running iOS 5 that is essentially a duplicate of this one. My best guess is that it's caused by a corrupt address book database. Notice that the crash happens in a call to ABAddressBookCreate
(which is a misleading name; it's more like open); there's nothing you are doing that should be able to cause this.
If you have control over the address book, and you're syncing it somewhere, you might try turning off sync, deleting all the contacts, and then syncing them back again (backing up first, of course).
MFMailComposeViewController
is accessing the address book, presumably, to offer the user To: addresses.
[Nit: not much point in nil'ing a automatic variable just before you exit a function.]
Just to add some data here, this looks like something that's beyond your control. Crash data from a live app shows this same crash happening to 11 users out tens of thousands. All the crashes occurred in some flavor of iOS 5.1 and 5.1.1, so it looks like the problem has been resolved in iOS 6.
As mentioned in another answer, you can wrap the call to [MFMailComposeViewController canSendMail]
in a @try { }
block, and do nothing in the case where it throws an exception. This will at least prevent those poor users with corrupted address books from crashing.
This is a bug in iOS 5 that was resolved in iOS 6. It cannot be "fixed" on iOS 5 devices and is not your fault.
Here is what I do to handle it...
What I've done is put a try/catch around my code, and if this exception is caught, I either:
A: If the user is on a device that CANNOT be upgraded to iOS 6 (devices older and NOT on this list: http://ipod.about.com/od/iPhoneQandA/f/What-Devices-Are-Ios-6-Compatible.htm), gracefully pop a dialog saying that we've encountered an error caused by Apple that we can't control or fix, and that only a newer iOS device fixes this problem.
OR
B: If the user is on a device that CAN be upgraded iOS 6, pop a dialog that lets users know about that bug and instructs them to upgrade to iOS 6 to fix the problem in the future.
Hopefully that handles this in the best way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With