SwiftUI on macOS: text, rich text, markdown, html and PDF views source code

This is the Swift source code to accompany the article SwiftUI on macOS: text, rich text, markdown, html and PDF views.

MainApp.swift

import SwiftUI

@main
struct ContentTypesApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        
        // each of the six secondary windows
        Window("PDF Window", id: "pdfdemo") {
            PDFdemoView()
        }
        Window("RTF Window", id: "rtfdemo") {
            RTFdemoView()
        }
        Window("RTF2 Window", id: "rtf2demo") {
            RTF2demoView()
        }
        Window("Text Window", id: "textdemo") {
            TextdemoView()
        }
        Window("Markdown Window", id: "mddemo") {
            MDdemoView()
        }
        Window("HTML Window", id: "htmldemo") {
            HTMLdemoView()
        }

        // add the Demos menu
        .commands {
            MenuCommands()
        }
    }
}

MenuCommands.swift

import SwiftUI

struct MenuCommands: Commands {
    @Environment(\.openWindow) var openWindow

    var body: some Commands {
        CommandMenu("Demos") {
            Button("Text demo", action: showTextWindow)
            Button("Markdown demo", action: showMDWindow)
            Button("RTF demo", action: showRTFWindow)
            Button("RTF2 demo", action: showRTF2Window)
            Button("HTML demo", action: showHTMLWindow)
            Button("PDF demo", action: showPDFWindow)
        }
    }
    
    func showPDFWindow() {
        openWindow(id: "pdfdemo")
    }
    func showRTFWindow() {
        openWindow(id: "rtfdemo")
    }
    func showRTF2Window() {
        openWindow(id: "rtf2demo")
    }
    func showTextWindow() {
        openWindow(id: "textdemo")
    }
    func showMDWindow() {
        openWindow(id: "mddemo")
    }
    func showHTMLWindow() {
        openWindow(id: "htmldemo")
    }
}

TextView.swift

import SwiftUI

struct TextdemoView: View {
    
    var text: String {
        var text = "None"
        let strUrl = Bundle.main.url(forResource: "demo", withExtension: "txt")!
        if let data = try? Data(contentsOf: strUrl) {
            if let contents = String(data: data, encoding: .utf8) {
                text = contents
            }
        }
        return text
    }
    
    var body: some View {
        ScrollView {
            Text(text)
        }
    }
}

#Preview {
    TextdemoView()
}

MarkdownView.swift

import SwiftUI

struct MDdemoView: View {
    
    var text: LocalizedStringKey {
        var text = LocalizedStringKey("none")
        let strUrl = Bundle.main.url(forResource: "demo", withExtension: "markdown")!
        if let data = try? Data(contentsOf: strUrl) {
            if let contents = String(data: data, encoding: .utf8) {
                text = LocalizedStringKey(contents)
            }
        }
        return text
    }
    
    var body: some View {

        ScrollView {
            Text(text)
        }
    }
}

#Preview {
    MDdemoView()
}

RichTextDirectView.swift

import SwiftUI

struct RTF2demoView: View {

    var text: AttributedString {
        var text = AttributedString("empty")
        let strUrl = Bundle.main.url(forResource: "demo", withExtension: "rtf")!
        if let data = try? Data(contentsOf: strUrl) {
            if let contents = NSAttributedString(rtf: data, documentAttributes: nil) {
                text = AttributedString(contents)
            }
        }
        return text
    }
    
    var body: some View {
        ScrollView {
            Text(text)
        }
    }
}

#Preview {
    RTF2demoView()
}

HTMLView.swift

import SwiftUI
import WebKit

struct WebView: NSViewRepresentable {
    typealias NSViewType = WKWebView
    
    func makeNSView(context: NSViewRepresentableContext<WebView>) -> WKWebView {
        // create a new WKWebView containing the document
        let strUrl = Bundle.main.url(forResource: "demo", withExtension: "html")!
        let wkView = WKWebView()
        if let data = try? Data(contentsOf: strUrl) {
            if let contents = String(data: data, encoding: .utf8) {
                wkView.loadHTMLString(contents, baseURL: strUrl)
                wkView.allowsBackForwardNavigationGestures = true
            }
        }
        return wkView
    }
    
    func updateNSView(_ uiView: WKWebView, context: NSViewRepresentableContext<WebView>) {
        // not needed here
    }
}

struct HTMLdemoView: View {
    var body: some View {
        WebView()
    }
}

#Preview {
    HTMLdemoView()
}

RichTextAppKitView.swift

import SwiftUI

struct AttrTextView: NSViewRepresentable {
    typealias NSViewType = NSTextView
    
    func makeNSView(context: NSViewRepresentableContext<AttrTextView>) -> NSTextView {
        var text = NSAttributedString("empty")
        let rtfUrl = Bundle.main.url(forResource: "demo", withExtension: "rtf")!
        if let data = try? Data(contentsOf: rtfUrl) {
            if let contents = NSAttributedString(rtf: data, documentAttributes: nil) {
                text = contents
            }
        }
        let textview = NSTextView()
        textview.isSelectable = true
        textview.isRichText = true
        textview.textColor = .textColor
        textview.backgroundColor = .windowBackgroundColor
        textview.textStorage?.setAttributedString(text)
        return textview
    }
    
    func updateNSView(_ nsView: NSTextView, context: NSViewRepresentableContext<AttrTextView>) {
        // not needed
    }
}

struct RTFdemoView: View {
    var body: some View {
        AttrTextView()
    }
}

#Preview {
    RTFdemoView()
}

PDFView.swift

import SwiftUI
import Quartz

struct PDFKitView: NSViewRepresentable {
    typealias NSViewType = PDFView
    
    func makeNSView(context: NSViewRepresentableContext<PDFKitView>) -> PDFView {
        // Create a new PDFVIew containing the document
        let url = Bundle.main.url(forResource: "demo", withExtension: "pdf")!
        let pdfView = PDFView()
        pdfView.document = PDFDocument(url: url)
        pdfView.autoScales = true
        return pdfView
    }
    
    func updateNSView(_ uiView: PDFView, context: NSViewRepresentableContext<PDFKitView>) {
        // no content needed
    }
}

struct PDFdemoView: View {
    var body: some View {
        PDFKitView()
    }
}

#Preview {
    PDFdemoView()
}

End of code supplement.