Search code examples
swiftvideotwitterinstagramuiactivityviewcontroller

Share a video and text on Twitter, Instagram and other services using UIActivityViewController


I am trying to share a video and a text on Instagram, Facebook, Twitter and the native services like Mail, Messages, .... I can not figure out how to get both, Instagram and Twitter to show up in the sharing actionsheet:

If i pass in an array of text and a URL as activity items into the controller, just Instagram shows up, but not Twitter.

let url: NSURL = NSURL() // a url that directs to a video
let items: [AnyObject] = ["Check out this video", url]    
let shareable = UIActivityViewController(activityItems: items, applicationActivities: nil)

controller.presentViewController(shareable,
                               animated: true,
                               completion: nil)

If i create a class that implements the UIActivityItemSource protocol instead and use that as activityItems, just Twitter shows up, but not Instagram:

class VideoActivityItemSource: NSObject, UIActivityItemSource {

    private let videoUrl: NSURL
    private let shareText = "View the full video here!"

    init(url: NSURL) {
        self.videoUrl = url
    }

    func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
        return ""
    }

    func activityViewController(activityViewController: UIActivityViewController, itemForActivityType activityType: String) -> AnyObject? {
        switch activityType {

        case UIActivityTypePostToFacebook:
            return self.videoUrl
        case UIActivityTypeMail:
            return self.videoUrl
        default:
            return ["text": self.shareText, "url": self.videoUrl]
        }
    }

    func activityViewController(activityViewController: UIActivityViewController, subjectForActivityType activityType: String?) -> String {
        return "Hey check this new cool app!!!"
    }

    func activityViewController(activityViewController: UIActivityViewController, thumbnailImageForActivityType activityType: String?, suggestedSize size: CGSize) -> UIImage? {
        return nil
    }
}

and then replace the items by this:

items = [VideoActivityItemSource(url: url)]

I have no idea why in this case Twitter won't show up in the action sheet. Does somebody have an idea how to solve this?


Solution

  • I found the answer. The correct way to do this is to use the implementation of the UIActivityItemSource protocol. The reason for Instagram not showing up in the second solution where i am using the VideoActivityItemSource class is that i am returning an empty String in the activityViewControllerPlaceholderItem function. Although Apple's documentation says that the type of the object returned in this function does not have to match the type that is used by the itemForActivityType function, it actually needs to be processable by the sharing service. In the case of Instagram it needs to be a video or an image, otherwise Instagram does not show up as a sharing option in the actionsheet.

    So the solution is to return a UIImage in the activityViewControllerPlaceholderItem function instead of an empty String, then both Twitter and Instagram will show up as sharing options.

    func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
        // this needs to return some random image to make sure Twitter and Instagram show up in the sharing actionsheet
        return UIImage(named: "someImage")!
    }