I'm using the new UIActivityViewController
class in iOS6 to provide the user with various sharing options. You can pass an array of parameters to it such as text, links and images and it does the rest.
How do I define recipients? For example sharing via mail or SMS should be able to accept recipients but I can't figure out how to invoke this behaviour.
I don't want to have to have to use MFMessageComposeViewController
and UIActivityViewController
separately as that just defeats the purpose of the share controller.
Any suggestions?
UIActivityViewController Class Reference
Edit: This has now been submitted Apple and subsequently merged with a duplicate bug report.
You should be able to include the recipients using an NSUrl object with the mailto: scheme (or sms: for text messages).
From the UIActivity class reference:
Therefore, something like this should work:
For adding subject to the email using UIActivityViewController on iOS6, this is the best solution that anyone can use.. All you have to do is call the following while initializing UIActivityViewController.
And your UIActivityViewController is populated with a subject.
I just come up with a solution to this problem (in my case set the subject of the email): as internally the UIActivityViewController will call at some point the setMessageBody:isHTML: method of the MFMailComposeViewController class, just intercept that call and inside make a call to the setSubject: method. Thanks to "method swizzling" technic, it looks like:
Call the following line of code before using UIActivityViewController:
Then pass to the UIActivityViewController a custom UIActivityItemProvider that for UIActivityTypeMail returns a HTML NSString like:
The subject of the email is extracted from the HTML title (use plain text for that part, no html entities or tags).
Using that method, I let you elaborate an elegant way to set the recipient for the mail.
I'm not sure about recipients, but it seems as though in iOS 7 and later you can set the subject of an email by conforming to the
UIActivityItemSource
protocol and implementing the methodactivityViewController:subjectForActivityType:
.While it does appear that at present the mailto: solution for setting email subject and body isn't working, this would in any case not be adequate if you wanted to set the email body to contain HTML and still make use of Apple's system email icon via UIActivityViewController.
That was exactly what we wanted to do: use the system icon, but have the email contain an HTML body and a custom subject.
Our solution was something of a hack, but it works well, at least for the moment. It does involve using MFMailComposeViewController, but it still lets you use the system mail icon with UIActivityViewController.
Step 1: Create a wrapper class conforming to the UIActivityItemSource like so:
Step 2: Subclass UIActivityViewController and make it into a MFMailComposeViewControllerDelegate like so:
NOTE: when you are calling
super initWithActivityItems
you are wrapping the object you will be sharing in your custom ActivityItemSourceStep 3: Launch your own MFMailComposeViewController instead of the system one when a user taps on the Mail icon.
You would do this in the
activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
method in the ActivityItemSource class:In the
mailComposeControllerWithObject
method you instantiate an instance of the MFMailComposeViewController class and set it up to contain whatever data you want. Note also that you would set theactivityViewController
as the compose view's delegate.The reason this works is that when a compose modal is displayed, it prevents other modals from being displayed, i.e. you displaying your own compose view blocks the system compose view from being shown. Definitely a hack, but it gets the job done.
Hope this helps.
All credit here goes to Emanuelle, since he came up with most of the code.
Though I thought I would post a modified version of his code that helps set the to recipient.
I used a Category on MFMailComposeViewController