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.