Basic example for sharing text or image with UIActivityViewController in Swift

Viewed 192639

I started my search by wanting to know how I could share to other apps in iOS. I discovered that two important ways are

  • UIActivityViewController
  • UIDocumentInteractionController

These and other methods are compared in this SO answer.

Often when I am learning a new concept I like to see a basic example to get me started. Once I get something basic set up I can modify it how I like later.

There are many SO questions related to UIActivityViewController, but I couldn't find any that were just asking for a simple example. Since I just learned how to do this, I will provide my own answer below. Feel free to add a better one (or an Objective-C version).

6 Answers

I've used the implementation above and just now I came to know that it doesn't work on iPad running iOS 13. I had to add these lines before present() call in order to make it work

//avoiding to crash on iPad
if let popoverController = activityViewController.popoverPresentationController {
     popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
     popoverController.sourceView = self.view
     popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}

That's how it works for me

func shareData(_ dataToShare: [Any]){

        let activityViewController = UIActivityViewController(activityItems: dataToShare, applicationActivities: nil)

        //exclude some activity types from the list (optional)
        //activityViewController.excludedActivityTypes = [
            //UIActivity.ActivityType.postToFacebook
        //]

        //avoiding to crash on iPad
        if let popoverController = activityViewController.popoverPresentationController {
            popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
            popoverController.sourceView = self.view
            popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
        }

        self.present(activityViewController, animated: true, completion: nil)
    }

You may use the following functions which I wrote in one of my helper class in a project.

just call

showShareActivity(msg:"message", image: nil, url: nil, sourceRect: nil) 

and it will work for both iPhone and iPad. If you pass any view's CGRect value by sourceRect it will also shows a little arrow in iPad.

func topViewController()-> UIViewController{
    var topViewController:UIViewController = UIApplication.shared.keyWindow!.rootViewController!

    while ((topViewController.presentedViewController) != nil) {
        topViewController = topViewController.presentedViewController!;
    }

    return topViewController
}

func showShareActivity(msg:String?, image:UIImage?, url:String?, sourceRect:CGRect?){
    var objectsToShare = [AnyObject]()

    if let url = url {
        objectsToShare = [url as AnyObject]
    }

    if let image = image {
        objectsToShare = [image as AnyObject]
    }

    if let msg = msg {
        objectsToShare = [msg as AnyObject]
    }

    let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
    activityVC.modalPresentationStyle = .popover
    activityVC.popoverPresentationController?.sourceView = topViewController().view
    if let sourceRect = sourceRect {
        activityVC.popoverPresentationController?.sourceRect = sourceRect
    }

    topViewController().present(activityVC, animated: true, completion: nil)
}
Related