I’m trying to use a ShareLink to share a PDF file. When using the file URL to the PDF directly, everything looks as I would expect:
let fileURL = URL(filePath: "…")
ShareLink(item: fileURL)
But in my actual app, the PDF isn’t available right away and is expensive to create, so I would like to only create it on demand. The documentation on FileRepresentation sounds to me like this is a use case for a custom type that implements Transferable with a FileRepresentation as its transferRepresentation. Before adding all the actual code to generate the PDF, I’m now trying to write a simple type that wraps a file URL and leads to the same results as using the URL directly. And I’m failing miserably.
This is what I tried:
struct PDFFile: Transferable {
var fileURL: URL
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: .pdf) { pdfFile in
SentTransferredFile(pdfFile.fileURL)
}
}
}
…and then in the view:
let fileURL = URL(filePath: "…")
let pdfFile = PDFFile(fileURL: fileURL)
ShareLink(
item: pdfFile,
preview: SharePreview(fileURL.deletingPathExtension().lastPathComponent, image: Image(systemName: "doc.richtext"), icon: Image(systemName: "doc"))
)
Why are no sharing services showing up? Why is there no icon?
I also tried using .fileURL as the exportedContentType, which then makes the sharing services show up, but actually sharing the file leads to an empty file being shared whose filename is garbage (it looks like the system tries to decode the PDF data as a UTF-8 string and use that as the filename).
So my question is: Is it possible to replicate the behavior of sharing a file URL with a custom type that asynchronously generates the data to share?