SwiftUI on macOS: Drag and drop, Source Code

This is the Swift source code to accompany the article SwiftUI on macOS: Drag and drop, and more.

App

import SwiftUI

@main
struct DroperaApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}

Window(“Help Window”, id: “help”) {
HelpView()
}

.commands {
HelpCommands()
}
}
}

Menu Commands

import SwiftUI

struct HelpCommands: Commands {
@Environment(.openWindow) var openWindow

var body: some Commands {
CommandGroup(replacing: .help) {
Button(“Dropera Help”, action: showHelpWindow)
}
}

func showHelpWindow() {
openWindow(id: “help”)
}
}

Content View

import SwiftUI

struct ContentView: View {
@State private var fileInfo: [String] = []

var body: some View {
let dropDelegate = DroperaDropDelegate(fileInfo: $fileInfo)

ScrollView {
Text(fileInfo.joined(separator: “nn”))
}

.frame(minWidth: 600, minHeight: 200, alignment: .center)
.onDrop(of: [“public.file-url”], delegate: dropDelegate)

.background(alignment: .center) {
if fileInfo.isEmpty {
Image(systemName: “doc.badge.plus”)
.resizable()
.frame(width: 150.0, height: 150.0)
.symbolRenderingMode(.multicolor)
}
}
}
}

#Preview {
ContentView()
}

Drop Delegate

import SwiftUI

struct DroperaDropDelegate: DropDelegate {
@Binding var fileInfo: [String]

func validateDrop(info: DropInfo) -> Bool {
return info.hasItemsConforming(to: [“public.file-url”])
}

/*
func dropEntered(info: DropInfo) {
NSSound(named: “Tink”)?.play()
}
*/

func performDrop(info: DropInfo) -> Bool {
// NSSound(named: “Sosumi”)?.play()
fileInfo = []
var gotFile = false
for itemProvider in info.itemProviders(for: [“public.file-url”]) {
itemProvider.loadItem(forTypeIdentifier: “public.file-url”, options: nil) { (item, error) in
if let data = item as? Data {
if let url = URL(dataRepresentation: data, relativeTo: nil) {
let theInfo = “File: “ + url.lastPathComponent + “nPath: “ + url.path + “n”
let theSizes = FileInfo().reportSizes(url: url)
DispatchQueue.main.async {
fileInfo.append(theInfo + theSizes)
gotFile = true
}
}
}
}
}
return gotFile
}

/*
func dropUpdated(info: DropInfo) -> DropProposal? {
return nil
}

func dropExited(info: DropInfo) {

}
*/

}

Help View

import SwiftUI

struct HelpView: View {

var text: AttributedString {
var text = AttributedString(“empty”)
let strUrl = Bundle.main.url(forResource: “Help”, 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 {
HelpView()
}

End of code supplement.