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.