Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MFMailComposeViewController throws a viewServiceDidTerminateWithError and then exits when using a custom title font

I've got the weirdest issue I've encountered in a long time...and I've run out of ideas.

So I've got a MFMailComposeViewController that is being launched from tapping on a UIButton and it's launching the mail composer view just fine. You see the subject I've assigned but before the to: or body fields are populated the window kind of flashes and disappears. It throws this error:

viewServiceDidTerminateWithError: Error Domain=XPCObjectsErrorDomain Code=2 "The operation couldn't be completed. (XPCObjectsErrorDomain error 2.)"

Now here's the crazy part. If I switch over to another app that also uses a MFMailComposeViewController and launch that one, then switch back to my app and launch the mail composer again, it works just fine. I can't explain that.

This only seems to be an issue on phones running iOS 6 that are not iPhone 5's.

I've searched around and can't seem to find anyone else who's experienced this same problem. Anyone got any suggestions?

I've got the MessageUI.framework linked and I also found that this wasn't working in the Simulator or on a device, but when I also linked the Security.framework it started working in the Simulator, but it still doesn't work on the devices.

My code for launching the MFMailComposeViewController is below:

in the .h file

#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>

in the .m file

-(void)displayComposerSheet {
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;

[picker setSubject:@"Support Request"];

// Set up recipients
NSArray *toRecipients = [NSArray arrayWithObject:@"[email protected]"];

[picker setToRecipients:toRecipients];

// Fill out the email body text
NSString *emailBody = @"\n\nEmail from iOS";
[picker setMessageBody:emailBody isHTML:NO];

[self presentModalViewController:picker animated:YES];
}


// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation. 
- (void)mailComposeController:(MFMailComposeViewController*)controller     didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{

    [self dismissModalViewControllerAnimated:YES];
}

Update: I think I've narrowed it down to the settings I have passed to the appearance delegate for the UINavigationBar. I have it using a custom font, and if I turn that off it seems to work...but why would that work on the iPhone5...

like image 928
gplocke Avatar asked Sep 27 '12 14:09

gplocke


5 Answers

Setting a custom font for the UITextAttributeFont to the titleTestAttributes of the UINavigationBar appearance proxy causes the bug as the OP and MightlyLeader identified.

Workaround Code:

// remove the custom nav bar font
NSMutableDictionary* navBarTitleAttributes = [[UINavigationBar appearance] titleTextAttributes].mutableCopy;
UIFont* navBarTitleFont = navBarTitleAttributes[UITextAttributeFont];
navBarTitleAttributes[UITextAttributeFont] = [UIFont systemFontOfSize:navBarTitleFont.pointSize];
[[UINavigationBar appearance] setTitleTextAttributes:navBarTitleAttributes];

// set up and present the MFMailComposeViewController
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setSubject:emailInfo[@"subject"]];
[mailComposer setMessageBody:emailInfo[@"message"] isHTML:YES];
mailComposer.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:mailComposer animated:YES completion:^{

    // add the custom navbar font back
    navBarTitleAttributes[UITextAttributeFont] = navBarTitleFont;
    [[UINavigationBar appearance] setTitleTextAttributes:navBarTitleAttributes];
}];
like image 53
dberwick Avatar answered Nov 08 '22 06:11

dberwick


This problem recently popped up on a project I'm working on. I didn't really like the workaround above so instead I created the following (maybe a little cleaner) workaround:

// Implement the custom font for all UINavigationBar items
[[UINavigationBar appearance] setTitleTextAttributes:
@{
    UITextAttributeFont : [UIFont custom_superAwesomeFontWithSize:16.0f],
}];


// Disable the custom font when the NavigationBar is presented in a MFMailComposeViewController
[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setTitleTextAttributes:
 @{
    UITextAttributeFont : [UIFont boldSystemFontOfSize:14.0f],
 }];
like image 12
jnjosh Avatar answered Nov 08 '22 05:11

jnjosh


I had the same issue. I had set the text attributes of the title bar to a custom font. When I removed the custom font specification (but left all the other attributes to custom values) the issue disappeared.

My diagnosis is that custom fonts take too long to load and it triggers a time-out from the wait-fences.

like image 9
Cocoadelica Avatar answered Nov 08 '22 05:11

Cocoadelica


Make this an ivar:

MFMailComposeViewController *picker 

Then after this line:

[self dismissModalViewControllerAnimated:YES];

add this:

dispatch_async(dispatch_get_main_queue(), ^{ picker = nil; });

So that the release of the picker does not happen until the next runloop cycle.

like image 3
David H Avatar answered Nov 08 '22 06:11

David H


This happens when we put fractional value in the custom UINavigationBar for example [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(1.5, -1.5) forBarMetrics:UIBarMetricsDefault]; Set offset value as UIOffsetMake(1.0, -1.0) and this will work. Hope this helps.

like image 2
Slashik Avatar answered Nov 08 '22 06:11

Slashik