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?