The solutions here are all good but it's worth considering implementing the UIActivityItemSource
protocol and LinkPresentation
framework.
My solution achieves the following:
- App icon and title showing at the top of the
UIActivityViewController
- Direct link to App Store for AirDrop
ActivityType
- Custom text for messages and emails, including an opportunity to add a link to the app on Google Play if required
- Subject for emails
- Doesn't use the
LPMetaDataProvider
fetch request (as described in this WWDC 2019 262 video) so faster to load
0. Init the UIActivityViewController
:
Set the items to self
:
let activityVC = UIActivityViewController(activityItems: [self], applicationActivities: nil)
Exclude certain ActivityType
s which don't apply:
activityVC.excludedActivityTypes = [.addToReadingList, .assignToContact, .markupAsPDF, .openInIBooks, .saveToCameraRoll]
For iPad set the popoverPresentationController.sourceView
or .barButtonItem
(this is ignored on iPhone):
activityVC.popoverPresentationController?.sourceView = myButton
Present it:
present(activityVC, animated: true, completion: nil)
1. Implement the required UIActivityItemSource
methods
https://developer.apple.com/documentation/uikit/uiactivityitemsource
You must implement the placeholder method which according to the docs:
Placeholder objects do not have to contain any real data but should be configured as closely as possible to the actual data object you intend to provide.
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return ""
}
And the actual data, returning a link to the app for AirDrop and text for everything else:
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
if activityType == .airDrop {
return URL(string: "APP_STORE_URL")!
}
return "Check out the APP_NAME on the App Store: APP_STORE_URL or on the Google Play Store: PLAY_STORE_URL"
}
2. Implement the subject method
From the docs:
For activities that support a subject field, returns the subject for the item.
func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String {
return "EMAIL_SUBJECT" // e.g. App name
}
3. Implement the LPLinkMetaData
method
From the docs:
Returns metadata to display in the preview header of the share sheet.
@available(iOS 13.0, *)
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
let metadata = LPLinkMetadata()
metadata.title = "APP_NAME"
return metadata
}