Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save christianselig/b272af7bb329e1db7d9d74b940f08900 to your computer and use it in GitHub Desktop.
Save christianselig/b272af7bb329e1db7d9d74b940f08900 to your computer and use it in GitHub Desktop.
import UIKit
class RootViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let text = "Cute cat"
let image = UIImage(named: "cat.jpg")!
// Note: you can't wrap the text and image into a single "TextImage" object and selectively return both or one as UIActivityItemSource doesn't like holding arrays
let activityViewController = UIActivityViewController(activityItems: [image, OptionalTextActivityItemSource(text: text)], applicationActivities: nil)
navigationController?.present(activityViewController, animated: true, completion: nil)
}
}
class OptionalTextActivityItemSource: NSObject, UIActivityItemSource {
let text: String
init(text: String) {
self.text = text
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return text
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
if activityType?.rawValue == "net.whatsapp.WhatsApp.ShareExtension" {
return nil
} else {
return text
}
}
}
@christianselig
Copy link
Author

christianselig commented May 14, 2020

Here's some further additions you can make that:

  • Fix a bug in iOS 13 where UIActivityViewController won't create previews for UIImage and if you pass an image URL it won't work with Messages.
  • Adds an alert on the first presentation with WhatsApp to cut down on support emails from users emailing you understandably confused why WhatsApp won't accept text and an image.
import UIKit

#if canImport(LinkPresentation)
    import LinkPresentation
#endif

class RootViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        let text = "Cute cat"
        let image = UIImage(named: "cat.jpg")!
        
        let activityViewController = UIActivityViewController(activityItems: [ImageActivityItemSource(image: image), OptionalTextActivityItemSource(text: text)], applicationActivities: nil)
        
        navigationController?.present(activityViewController, animated: true, completion: nil)
    }
}

class OptionalTextActivityItemSource: NSObject, UIActivityItemSource {
    let text: String
    weak var viewController: UIViewController?
    
    init(text: String) {
        self.text = text
    }
    
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return text
    }
    
    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        if activityType?.rawValue == "net.whatsapp.WhatsApp.ShareExtension" {
            // WhatsApp doesn't support both image and text, so return nil and thus only sharing an image. Also alert user about this on the first time.
            let alertedAboutWhatsAppDefaultsKey = "DidAlertAboutWhatsAppLimitation"
            
            if !UserDefaults.standard.bool(forKey: alertedAboutWhatsAppDefaultsKey) {
                DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
                    guard let presentedViewController = activityViewController.presentedViewController else { return }
                    UserDefaults.standard.set(true, forKey: alertedAboutWhatsAppDefaultsKey)
                    
                    let alert = UIAlertController(title: "WhatsApp Doesn't Support Text + Image", message: "Unfortunately WhatsApp doesn’t support sharing both text and an image at the same time. As a result, only the image will be shared.", preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
                    presentedViewController.present(alert, animated: true, completion: nil)
                }
            }
            
            return nil
        } else {
            return text
        }
    }
}

/// For whatever reason `UIActivityViewController` on iOS 13 only provides a preview of the image if it's passed as a URL, rather than a `UIImage` (if `UIImage` just shows app icon, see here: https://stackoverflow.com/questions/57850483/).
/// However we can't pass the URL to the image because when paired with a String on iOS 13 (image URLs are fine on their own) Messages won't accept it.
/// So when sharing both, wrap the UIImage object and manually provide the preview via the `LinkPresentation` framework.
class ImageActivityItemSource: NSObject, UIActivityItemSource {
    let image: UIImage
    
    init(image: UIImage) {
        self.image = image
    }
    
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return image
    }
    
    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        return image
    }
    
    @available(iOS 13.0, *)
    func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
        let imageProvider = NSItemProvider(object: image)
        
        let metadata = LPLinkMetadata()
        metadata.imageProvider = imageProvider
        metadata.title = "Image & Text"
        return metadata
    }
}

@Arnav-arw
Copy link

WhatsApp still doesn't support sending Text and image together?

@dipeshpatel7733-hub
Copy link

Is it possible to upload both text and image on WhatsApp? is there any solution for this?

@Mh-Alim
Copy link

Mh-Alim commented May 1, 2024

Is it possible to upload both text and image on WhatsApp? is there any solution for this?

did anyone find anything about this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment