Forum Archive

Show objc mail composer without closing view (or relaunching afterward?)

blowhard

I'm generating a PDF using jinja in the background, and then want to email that through the iOS email composer after a button press in the UI. The following code works if I call it without the UI, and if I call view.close() first before calling the mail composer function. But otherwise the mail composer seems to close in the background instantly (without an error) and I never see it. I'm trying to do this in fullscreen mode, though it doesn't seem to make a difference.

Alternatively, is there a way to relaunch the view after the composer is dismissed? When I try to do so it says the view is already being presented even though I've called close().

Call from script:

show_mail_sheet('me@you.com', 'Test', [reference to PDF], 'text/pdf')

function:

```

- (void)mailComposeController:(MFMailComposeViewController )controller didFinishWithResult:(MFMailComposeResult)result error:(NSError )error

def mailComposeController_didFinishWithResult_error_(self, _cmd, controller, result, error):
print('Mail composer finished')
# Wrap the controller parameter in an ObjCInstance, so we can send messages:
mail_vc = ObjCInstance(controller)
# Set delegate to nil, and release its memory:
mail_vc.setMailComposeDelegate
(None)
ObjCInstance(self).release()
# Dismiss the sheet:
mail_vc.dismissViewControllerAnimated_completion
(True, None)

methods = [mailComposeController_didFinishWithResult_error_]
protocols = ['MFMailComposeViewControllerDelegate']
MyMailComposeDelegate = create_objc_class('MyMailComposeDelegate', NSObject, methods=methods, protocols=protocols)

@on_main_thread
def show_mail_sheet(recipient, subject, filename, mimetype):
print("Showing mail sheet")
load_framework('MessageUI')
MFMailComposeViewController = ObjCClass('MFMailComposeViewController')
mail_composer = MFMailComposeViewController.alloc().init().autorelease()
# Use our new delegate class:
delegate = MyMailComposeDelegate.alloc().init()
mail_composer.setMailComposeDelegate_(delegate)
mail_composer.setToRecipients([recipient])
mail_composer.setSubject(subject)
filepath = os.path.join(os.getcwd(), filename)
mail_composer.addAttachmentData_mimeType_fileName_(NSData.dataWithContentsOfFile_(filepath), mimetype, filename )
# Present the mail sheet:
root_vc = UIApplication.sharedApplication().keyWindow().rootViewController()
root_vc.presentViewController_animated_completion_(mail_composer, True, None)```

cvp

@blowhard could you check if after your problem a file _objc_exception.txt has been created or updated in the root of Pythonista. Perhaps is your problem coming from an Objectivec exception. If yes, you can post its content.

I think about a thread problem

mikael

@blowhard, if I understand correctly what you are trying to do, open the composer as a modal subcontroller to your ui.View, instead of a main controller:

vc = SUIViewController.viewControllerForView_(
    your_view.objc_instance)
vc.presentModalViewController_animated_(mail_composer, True)
blowhard

@mikael said:

vc = SUIViewController.viewControllerForView_(
your_view.objc_instance)
vc.presentModalViewController_animated_(mail_composer, True)

This worked perfectly. Thanks!