74

I want to set subject for email sharing in UIActivityViewController and also want to share in Twitter. I know in Twitter if we want to share — we need compress text to 140 chars. I checked many SO solutions, but nothing is working.

Is this issue fixed in latest iOS releases? Any other "working solutions"?

Sahil Kapoor
  • 11,183
  • 13
  • 64
  • 87
Femina
  • 1,239
  • 1
  • 12
  • 25

4 Answers4

97

Check below code for the email for setting up your email subject:

UIActivityViewController* avc = [[UIActivityViewController alloc] initWithActivityItems:@[@"Your String to share"]
                                  applicationActivities:nil];
[avc setValue:@"Your email Subject" forKey:@"subject"];

avc.completionHandler = ^(NSString *activityType, BOOL completed) {
    // ...
};

Here the line

[avc setValue:@"Your email Subject" forKey:@"subject"];

Makes the subject as "Your email Subject" if user picks email option in the UIActivityViewController.

I hope it helps...

emreoktem
  • 2,409
  • 20
  • 36
  • 1
    [activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) { if([activityType isEqualToString: UIActivityTypeMail]){ NSLog(@"Mail type selected"); [activityVC setValue:@"Share!" forKey:@"subject"]; } }]; Its not working emreoktem! – Femina Oct 30 '13 at 10:12
  • @Meenu You should set the subject *before* the completion handler. – colinta Apr 18 '14 at 17:02
  • 3
    This doesn't seem to be working in iOS8, is there another way of doing this? – svarrall Nov 06 '14 at 15:07
  • is There any way to set recipient also?? – Aanchal Chaurasia Apr 07 '15 at 08:54
  • 1
    This and the activityViewController:subjectForActivityType: are annoyingly setting email subject and navigation bar title to the same string. It would be nice to have a official and documented way to do that. – Claus May 20 '15 at 13:49
  • 2
    but email subject is not showing when I am opening gmail application.I am getting Body content in Gmail Subject section – Ansal Antony Oct 25 '16 at 14:31
  • It's undocumented and not preferred. – Timur Bernikovich Dec 06 '16 at 10:45
95

It seems as though emreoktem's solution—sending setValue:forKey: to the UIActivityViewController—is undocumented.

On iOS 7 and later, you can implement the activityViewController:subjectForActivityType: method in an object conforming to the UIActivityItemSource protocol to do this in a way that is documented.

Tim Arnold
  • 8,359
  • 8
  • 44
  • 67
  • 8
    Yes, `activityViewController:subjectForActivityType:` is the correct solution. Strangely the iOS Mail app uses the subject correctly **but Google Inbox** uses the message for the subject as well (not the subject supplied via `subjectForActivityType`) – Leslie Godwin Jul 22 '15 at 05:46
  • 3
    @LeslieGodwin Did you found any solution for sharing via gmail? – Zalak Patel Apr 18 '16 at 05:30
  • @TimCamber Though I have tried above way it is still showing problem via sharing in gmail. Please help to resolve – Zalak Patel Apr 18 '16 at 05:31
  • @jalakpatel I'm not sure what you are asking. Are you sharing something to the Google Gmail app? In that case, it may not be `UIActivityViewController`'s fault that the Gmail app is not picking up `activityViewController:subjectForActivityType:`. – Tim Arnold Apr 18 '16 at 18:54
  • Thank you, this is the correct answer. I've added an answer with a concrete class for Swift 3+ that I found very useful. – biomiker Mar 21 '18 at 18:20
32

Here's a concrete solution for Swift 3.0+ based on the accepted answer. Note that, like the accepted answer, this is known to work only on the iOS Mail app and not necessarily other apps.

Implementation:

class MessageWithSubject: NSObject, UIActivityItemSource {

    let subject:String
    let message:String

    init(subject: String, message: String) {
        self.subject = subject
        self.message = message

        super.init()
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return message
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType) -> Any? {
        return message
    }

    func activityViewController(_ activityViewController: UIActivityViewController,
                                subjectForActivityType activityType: UIActivityType?) -> String {
        return subject
    }
}

Usage:

Here's an example of usage. Note that it works well to use this as the first item in the activityItems array, and include any additional items to follow:

let message = MessageWithSubject(subject: "Here is the subject", message: "An introductory message")
let itemsToShare:[Any] = [ message, image, url, etc ]

let controller = UIActivityViewController(activityItems: itemsToShare, applicationActivities: nil)
biomiker
  • 3,108
  • 1
  • 29
  • 26
19

For Swift 2.0+ & ios 8.0+

let title = "Title of the post"
let content = "Content of the post"
let objectsToShare = [title, content]

let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)      
activityVC.setValue(title, forKey: "Subject")
self.presentViewController(activityVC, animated: true, completion: nil)
PAC
  • 1,664
  • 1
  • 18
  • 24
  • does this work for sharing a link to a website? like [title, content, link] or does the URL has to be part of the content itself and let the email client parse it and make it clickable? – gadget00 May 16 '16 at 03:52
  • Per the accepted answer, this is undocumented and unreliable. – biomiker Mar 21 '18 at 18:21
  • One suggestion is to leave the 'title' off the objectsToShare, since adding the title in the setValue sets the Subject in the Email already. Works for me. – AndiAna Feb 20 '21 at 14:54