SwiftUI on macOS: Documents, Source Code

This is the Swift source code to accompany the article SwiftUI on macOS: Documents.

URL App

import SwiftUI

@main
struct DroperaApp: App {
    var body: some Scene {
        DocumentGroup(viewing: DroperaDocument.self) { fileConfig in
            ContentView(document: fileConfig.$document, url: fileConfig.fileURL)
        }
    }
}

URL ContentView

import SwiftUI

struct ContentView: View {
    @Binding var document: DroperaDocument
    var url: URL?

    var body: some View {
        Text(url?.path ?? "no path")
            .padding()
    }
}

#Preview {
    ContentView(document: .constant(DroperaDocument()))
}

PDFViewer App

import SwiftUI

@main
struct PDFViewerApp: App {
    var body: some Scene {
        DocumentGroup(newDocument: PDFViewerDocument()) { file in
            ContentView(pdfDocument: file.$document)
        }
    }
}

PDFViewer FileDocument struct

import SwiftUI
import Quartz
import UniformTypeIdentifiers

struct PDFViewerDocument: FileDocument {

    var pdfFile: PDFDocument?

    init() {
        pdfFile = PDFDocument()
    }

    static var readableContentTypes: [UTType] { [UTType.pdf] }

    init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents
        else {
            throw CocoaError(.fileReadCorruptFile)
        }
        pdfFile = PDFDocument(data: data)
    }
    
    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        let data = pdfFile?.dataRepresentation() ?? Data()
        return .init(regularFileWithContents: data)
    }
}

PDFViewer ContentView

import SwiftUI
import Quartz

struct PDFKitView: NSViewRepresentable {
    typealias NSViewType = PDFView
    
    var pdfDocument: PDFViewerDocument
    
    init(document: PDFViewerDocument) {
        pdfDocument = document
    }
    
    func makeNSView(context: NSViewRepresentableContext<PDFKitView>) -> PDFView {
        // Create a new PDFVIew containing the document
        let pdfView = PDFView()
        pdfView.document = pdfDocument.pdfFile
        pdfView.autoScales = true
        pdfView.displayMode = .singlePageContinuous
        pdfView.displaysPageBreaks = true
        return pdfView
    }
    
    func updateNSView(_ uiView: PDFView, context: NSViewRepresentableContext<PDFKitView>) {
        // no content needed
    }
}

struct ContentView: View {
    @Binding var pdfDocument: PDFViewerDocument

    var body: some View {
        PDFKitView(document: pdfDocument)
    }
}

PDFViewer ReferenceFileDocument class

import SwiftUI
import Quartz
import UniformTypeIdentifiers

final class PDFViewerDocument: ReferenceFileDocument {
    
    typealias Snapshot = Data
    
    var pdfFile: PDFDocument?
    
    init() {
        pdfFile = PDFDocument()
    }
    
    static var readableContentTypes: [UTType] { [UTType.pdf] }
    
    required init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents
        else {
            throw CocoaError(.fileReadCorruptFile)
        }
        pdfFile = PDFDocument(data: data)
    }
    
    func fileWrapper(snapshot: Snapshot, configuration: WriteConfiguration) throws -> FileWrapper {
        let data = pdfFile?.dataRepresentation() ?? Data()
        return FileWrapper(regularFileWithContents: data)
    }

    func snapshot(contentType: UTType) throws -> Data {
        return pdfFile?.dataRepresentation() ?? Data()
    }

}

End of code supplement.