My app is able to provide a variety of UIActivityItem types (text, data, rich text, print page renderer, etc) for sharing for a variety of purposes, including printing, copy/paste, and saving as a file. For the purpose of copy/paste, it needs to include plain text, attributed string, data (JSON Data) and JSON string).
However, because several data types are provided, the UIActivityViewController's "Save to Files" option results in several files being saved - one for each of the item types that can be saved as a file.
If I reduce it to just one UIActivityItem, then copy/paste functionality is severely reduced so that it would not work with all of the various different pasteboard types it should (eg, my app's custom JSON data format AND with plain text AND attributed string).
So I'm attempting to use a UIActivityItemProvider subclass to overcome the issue, but I still cannot figure out how to get only one file to be saved, instead of multiple files (one for each item type). Is this even possible?
Relevant parts of my UIActivityItemProvider subclass are below.
(Note that I'm using multiple instances of a single subclass for this, but the same problem would occur with using different subclasses.)
class RatsActivityItemProvider: UIActivityItemProvider {
var rats: [Rat]
init(placeholderItem: Any, rats: [Rat]) {
RatsActivityItemProvider.selectedOption = nil
self.rats = rats
super.init(placeholderItem: placeholderItem)
}
class func allProviders(forRats rats: [Rat]) -> [RatsActivityItemProvider] {
var providers: [RatsActivityItemProvider] = []
providers.append(RatsActivityItemProvider(placeholderItem: NSAttributedString(), rats: rats))
providers.append(RatsActivityItemProvider(placeholderItem: RatPrintPageRenderer(), rats: rats))
providers.append(RatsActivityItemProvider(placeholderItem: [:] as [String:Any], rats: rats))
providers.append(RatsActivityItemProvider(placeholderItem: Data(), rats: rats))
return providers
}
override var item: Any {
print("\(activityType!.rawValue as Any) - \(type(of: placeholderItem!))")
switch activityType {
case UIActivity.ActivityType.print:
return RatPrintPageRenderer(rats)
case UIActivity.ActivityType.copyToPasteboard:
var pasteboardDict: [String:Any] = attrString.pasteables()
// (Add custom types to dictionary here)
return pasteboardDict
default:
// "Save To Files" activity is not available in UIActivity.ActivityType so check the raw value instead
if activityType?.rawValue.contains("com.apple.CloudDocsUI.AddToiCloudDrive") ?? false {
//
// HOW TO HAVE ONLY ONE OF THE PROVIDERS RETURN A VALUE HERE???
//
}
}
}
}
When I run this and choose "Save to Files" I get the following output (one line from each of the providers):
com.apple.CloudDocsUI.AddToiCloudDrive - NSConcreteAttributedString
com.apple.CloudDocsUI.AddToiCloudDrive - RecipePrintPageRenderer
com.apple.CloudDocsUI.AddToiCloudDrive - __EmptyDictionarySingleton
com.apple.CloudDocsUI.AddToiCloudDrive - _NSZeroData
...and a file gets created for each of these, if I simply pass back the item for that data type.