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.