iOS Share text or image
present UIActivityViewController
let controller = UIActivityViewController(activityItems: [someObject], applicationActivities: nil)
//someObject can be UIImage, NSURL, String... iOS decide how to handle it properly
controller.popoverPresentationController?.sourceView = self.view
//add completionWithItemsHandler
controller.completionWithItemsHandler = {
(
activityType: UIActivity.ActivityType?,
completed: Bool,
arrayReturnedItems: [Any]?,
error: Error?
) in
if let error = error {
//error occured
return
}
if completed {
if let activityType = activityType {
switch activityType {
case .saveToCameraRoll:
break
case .copyToPasteboard:
break
case .addToReadingList:
break
case .airDrop:
break
default:
//all others
break
}
}
} else {
//Cancel
}
}
self.present(controller, animated: true)
Save image into library
If you are going to save image into library add NSPhotoLibraryAddUsageDescription
into app's .plist
file or you get runtime error:
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.
additionally you can exclude this opportunity:
controller.excludedActivityTypes = [.saveToCameraRoll]
variant with completionWithItemsHandler
which can helps to add post logic or handle errors.
For example I run into next error when saving UIImage into Photo library in a corresponding handler:
Error Domain=ALAssetsLibraryErrorDomain Code=-1 "Unknown error" UserInfo={NSLocalizedDescription=Unknown error, NSUnderlyingError=0x600003f85110 {Error Domain=PHPhotosErrorDomain Code=3303 "(null)"}}
As figured out I tried to save CIImage
. As a variant you can convert it to CGImage
let context = CIContext()
guard let cgImage = context.createCGImage(output, from: output.extent) else { return nil }
return UIImage(cgImage: cgImage)
Customize UIActivityViewController
class ImageActivityItemSource: NSObject, UIActivityItemSource {
let image: UIImage
let title: String
public init(image: UIImage, title: String) {
self.image = image
self.title = title
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return self.image
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
return self.image
}
public func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
let image = self.image
let imageProvider = NSItemProvider(object: image)
let metadata = LPLinkMetadata()
metadata.title = self.title
metadata.imageProvider = imageProvider
return metadata
}
}
using:
let imageActivityItemSource = ImageActivityItemSource(image: image, title: "Share this image with others")
let ac = UIActivityViewController(activityItems: [imageActivityItemSource], applicationActivities: nil)