8

I'm migrating to use the UIActivityViewController for sharing in iOS6, but I can't figure out how to create email attachment objects to be included when sharing by email.

The corresponding code in iOS5 is:

MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
[picker addAttachmentData:data mimeType:@"application/XXX" fileName:fileName];
Setomidor
  • 954
  • 9
  • 15

3 Answers3

26

You have very limited control over UIActivityViewController, but if you're attaching well-know mime types, I found you can get it to work correctly by providing the associated file extension in a file URL. For example, if your attachment is a vCard, use the ".vcf" extension in the file URL:

NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
// The file extension is important so that some mime magic happens!
NSString *filePath = [docsPath stringByAppendingPathComponent:@"vcard.vcf"];
NSURL *fileUrl     = [NSURL fileURLWithPath:filePath];

[data writeToURL:fileUrl atomically:YES]; // save the file

// Now pass the file URL in the activity items array
UIActivityViewController *avc = [[UIActivityViewController alloc] initWithActivityItems:
    @[@"Here's an attached vCard", fileUrl] applicationActivities:nil];
[vc presentModalViewController:avc animated:YES];
markiv
  • 1,578
  • 16
  • 12
  • This actually worked, thanks markiv :) I combined this with another guide on how to create custom files for an app (e.g. files using .myApp), and got that to work as well with the fileURL. – Setomidor Dec 11 '12 at 12:48
  • 1
    sorry for bringing up this old question, but shouldn't `[data writeToURL:filePath atomically:YES]` be `[data writeToURL:fileURL atomically:YES]`? – Gabriele Petronella Apr 05 '13 at 05:35
  • @GabrielePetronella Yes or I believe [data writeToFile:filePath atomically:YES] would work as well. – Steve Moser Aug 05 '15 at 18:58
2

For anyone wondering why their files aren't being shared using UIActivityViewController to apps like DropBox and other generic file handling applications, what you really want is a UIDocumentInteractionController.

Use it something like this:

class ViewController {
    var openInController:UIDocumentInteractionController!

    init() {
        openInController = UIDocumentInteractionController(URL: docURL)
    }

    func shareDoc {
        openInController.presentOptionsMenuFromRect(CGRectZero, inView: self.view, animated: true)
    }
}
voidref
  • 1,113
  • 11
  • 15
0

From what I can tell you can't do this with the UIActivityViewController -- I can't even manage to make it present HTML content for the message body -- so you may be better off using SLComposeViewController.

Christopher King
  • 1,691
  • 23
  • 28
  • It is possible to add html content by tagging the string you pass into activity items with ... - only then will it be interpreted as html. – SMSidat Nov 06 '13 at 14:17
  • @SMSidat are you sure? that's exactly what I did and it was rendered literally (i.e. not interpreted as HTML) – Christopher King Nov 07 '13 at 19:47
  • I'm pretty sure - I've done it and it works. I don't really want to hijack this Q&A thread, so if you have one on this already, I'll be happy to help you there, or you can make a new one with a copy of the relevant part of your code and I'll see what I can do – SMSidat Nov 08 '13 at 08:54