I have a document-based SwiftUI app where the document is a file wrapper. The document has the following writable content types:
static var writableContentTypes: [UTType] {
[.bookDocumentPackage, .epub, .pdf]
}
I am using .fileExporter
to export the document to PDF.
.fileExporter(isPresented: $isPublishing,
document: book,
contentType: .pdf,
defaultFilename: book.metadata.title) { result in
switch result {
case .success(let url):
book.publishPDF(location: url)
case .failure(let error):
print(error.localizedDescription)
}
}
The problem is the URL the file exporter returns is treated as a directory instead of a file.
I have the following code to create a PDF context to create the PDF:
func buildPDFContext(url: URL) -> CGContext? {
// For now, just go with a standard 8.5 by 11 inch page.
let pdfContext = CGContext(url as CFURL,
mediaBox: nil, nil)
return pdfContext
}
When I call the function, I get the following error message in Xcode’s debug console:
CGDataConsumerCreateWithFilename: failed to open
/URL/from/fileExporter
for writing: Is a directory.
The PDF context is not created. Instead of a PDF file, I get my document file wrapper as a collection of files and folders.
I can work around this problem on Mac by using NSSavePanel
instead of SwiftUI’s file exporter. But iOS has no equivalent to NSSavePanel
.
I tried using the FileManager
class to create an empty file at the URL and use that to create the PDF, but the URL is still treated as a directory. I also tried making PDF the only writable content type, but the error persists.
How do I get the URL the file exporter returns to be treated as a file instead of a directory?