问题
I can't get MFMailComposeViewController to open without throwing a fatal error in iOS 9 Simulator.
The same code (Objective C) works flawlessly in iOS 8.x and lower but today I installed Xcode 7 beta 5 and when I run the app on iOS 9 Simulator, I get a dialog box titled "MailCompositionService quit unexpectedly" and when I view the error report, I see:
Application Specific Information: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI isEqualToString:]: unrecognized selector sent to instance 0x7fd314280b10'
terminating with uncaught exception of type NSException abort() called CoreSimulator 179 - Device: iPhone 6 - Runtime: iOS 9.0 (13A4325c) - DeviceType: iPhone 6
The error happens when the mail composition view comes up. It freezes for a few seconds and then the error dialog box comes up.
The code that opens the mail composition view is:
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:@"Comment title"];
[picker setMessageBody:@"Comment description" isHTML:NO];
[self.window.rootViewController presentModalViewController:picker animated:YES];
[picker release];
}
If it helps to know, before the app crashes, mailComposeController:didFinishWithResult:error:
is called with result
= MFMailComposeResultCancelled
and error
= nil
.
I'd appreciate tips on how to find the cause of this error. Thanks!
回答1:
The issue is with simulator, on the real device mail composer is working correctly.
回答2:
As per Apple Developer Forum, more details are here.
The simulator doesn't support mail. You should likely try testing mail functionality in a device.
回答3:
You should use :
[self.window.rootViewController presentViewController:picker animated:YES completion:NULL];
presentModalViewController is DEPRECATED since ios6 is and has been replaced by presentViewController:animated:completion:
ie:
- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 6_0);
回答4:
I have no idea why it happens or how did I discovered it, the crash seems to be generated by setting the NSFontAttributeName in the Appearance proxy for the navigation bar, if I uncomment that line the app crashes.
NSDictionary* format = @{
NSForegroundColorAttributeName:[UIColor whiteColor],
//NSFontAttributeName: [UIFont boldSystemFontOfSize:20],
};
[[UINavigationBar appearance] setTitleTextAttributes:format];
Please @Sleiman try and see if this fixes the issue for you too.
回答5:
As a simple work around for this problem, you can use "mailto" protocol, it will:
- Not crash the app (device and simulator)
- Prompt the user to login if the device has not login with any mail account
Example in swift:
Swift 3.0
let mailRecipient = "support@abc.com"
let mailSubject = "Help with ABC for iOS"
let mailBody = "xxx"
let mailTo = "mailto:\(mailRecipient)?subject=\(mailSubject)&body=\(mailBody)"
guard let escapedMailTo = mailTo.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
NSLog("Invalid mail to format")
return
}
guard let url = NSURL(string: escapedMailTo) else {
NSLog("Invalid mail to format: \(escapedMailTo)")
return
}
UIApplication.sharedApplication().openURL(url)
Swift 2.3
let mailRecipient = "support@abc.com"
let mailSubject = "Help with ABC for iOS"
let mailBody = "xxx"
let mailTo = "mailto:\(mailRecipient)?subject=\(mailSubject)&body=\(mailBody)"
guard let escapedMailTo = mailTo.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet()) else {
NSLog("Invalid mail to format")
return
}
guard let url = NSURL(string: escapedMailTo) else {
NSLog("Invalid mail to format: \(escapedMailTo)")
return
}
UIApplication.sharedApplication().openURL(url)
来源:https://stackoverflow.com/questions/32078073/mfmailcomposeviewcontroller-throws-an-error-only-in-ios-9