So in iOS10 if you wanted to share an image with UIActivityViewController, you would just need to write some swift3 code that looked like:
func shareTapped() {
if let image = imageView.image {
let vc = UIActivityViewController(activityItems: [image], applicationActivities: [])
vc.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem
present(vc, animated: true, completion: nil)
}
This method still appears to work if you want to save the image to your camera roll (providing you've asked for the appropriate permissions), or want to share via messenger, airdrop, or any other Apple implementation.
Unfortunately if you attempt to share the image via Twitter, Facebook, Instagram, etc, they won't successfully attach the image and will either throw an error or fail silently.
I've spent a ton of time searching google, youtube and stackoverflow, and everything points to an iOS10 solution and nothing since iOS11 released.
I should note that this function still works fine if you want to pass a string, url, or something on those lines.
The accepted answer did/does not work for all 3rd party apps e.g. Microsoft Teams app. Writing the image data to disk and sharing the URL seemed to work for all apps:
guard
let image = UIImage(named: "your-image"),
let imageData = image.pngData(),
let imagePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("image-to-be-shared")?.appendingPathExtension("png") else {
return
}
do {
try imageData.write(to: imagePath)
} catch {
// handle error
return
}
let activity = UIActivityViewController(activityItems: [imagePath], applicationActivities: nil)
activity.completionWithItemsHandler = { _, _, _, _ in
do {
try FileManager.default.removeItem(at: imagePath)
} catch {
// handle error
}
}
present(activity, animated: true, completion: nil)
Short Version / TLDR
By converting your image into Data first, and then passing that object to the UIActivityViewController solves the Twitter / Facebook problem when trying to pass an image:
if let jpgImage = UIImageJPEGRepresentation(image, 0.8) {
let vc = UIActivityViewController(activityItems: [jpgImage], applicationActivities: [])
}
Longer explantation and full code can be found below:
Longer Version
I reached out to a few experts who all implied it should just work, but even when looking at their sample apps, they all exhibited the same problem. So I ultimately thought this might be an issue with Twitter or Facebook since sharing to the Apple apps just worked. I then got around to playing with the Photos app and decided to hit the share button there, and voila, it worked with Twitter and Facebook! This made me wonder whether this meant there was some incremental setup needed to get it this to work. After trying many different things I finally found a method that worked. By converting the image to Data via a PNG or JPG and passing that new object to your activityItems solves the Twitter / Facebook problem and still seems to work with everything else. The updated swift4 / ios11 code converting the image to JPG would look like:
@objc func shareTapped() {
if let image = imageView.image {
if let jpgImage = UIImageJPEGRepresentation(image, 0.8) {
let vc = UIActivityViewController(activityItems: [jpgImage], applicationActivities: [])
// add the following line if using doing universal and need iPad
vc.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem
present(vc, animated: true)
}
}
}
Hope this helps anyone else that's been struggling sharing an image since iOS11.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With