I'm wondering if there is a good way export or share a file through SwiftUI. There doesn't seem to be a way to wrap a UIActivityViewController and present it directly. I've used the UIViewControllerRepresentable to wrap a UIActivityViewController, and it crashes if I, say, present it in a SwiftUI Modal.
I was able to create a generic UIViewController and then from there call a method that presents the UIActivityViewController, but that's a lot of wrapping.
And if we want to share from the Mac using SwiftUI, is there a way to wrap NSSharingServicePicker?
Anyway, if anyone has an example of how they're doing this, it would be much appreciated.
The UIActivityViewController allows the application user to easily share data between the current application and services. A number of services such as social networks, email, and SMS are provided by the OS.
You can define this function anywhere (preferably in the global scope):
@discardableResult
func share(
items: [Any],
excludedActivityTypes: [UIActivity.ActivityType]? = nil
) -> Bool {
guard let source = UIApplication.shared.windows.last?.rootViewController else {
return false
}
let vc = UIActivityViewController(
activityItems: items,
applicationActivities: nil
)
vc.excludedActivityTypes = excludedActivityTypes
vc.popoverPresentationController?.sourceView = source.view
source.present(vc, animated: true)
return true
}
You can use this function in a button action, or anywhere else needed:
Button(action: {
share(items: ["This is some text"])
}) {
Text("Share")
}
Most of the solutions here forget to populate the share sheet on the iPad.
So, if you intend to have an application not crashing on this device, you can use
this method where popoverController
is used and add your desired activityItems
as a parameter.
import SwiftUI
/// Share button to populate on any SwiftUI view.
///
struct ShareButton: View {
/// Your items you want to share to the world.
///
let itemsToShare = ["https://itunes.apple.com/app/id1234"]
var body: some View {
Button(action: { showShareSheet(with: itemsToShare) }) {
Image(systemName: "square.and.arrow.up")
.font(.title2)
.foregroundColor(.blue)
}
}
}
extension View {
/// Show the classic Apple share sheet on iPhone and iPad.
///
func showShareSheet(with activityItems: [Any]) {
guard let source = UIApplication.shared.windows.last?.rootViewController else {
return
}
let activityVC = UIActivityViewController(
activityItems: activityItems,
applicationActivities: nil)
if let popoverController = activityVC.popoverPresentationController {
popoverController.sourceView = source.view
popoverController.sourceRect = CGRect(x: source.view.bounds.midX,
y: source.view.bounds.midY,
width: .zero, height: .zero)
popoverController.permittedArrowDirections = []
}
source.present(activityVC, animated: true)
}
}
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