In my macOS app I need to allow the user get a list of absolute local file URLs by selecting them from Finder using copy-and-paste or drag-and-drop. I'll filter them by the extension ".raw" and they should go, I think, in an array of URL. My experience using an app that support this suggests that I should implement both. I do know how to code a file-picker but that's not what I want.
I've been using Dr. Google to search but what I have found doesn't come close to illustrate what I need are too complex for me to understand enough to use as a guide.
Here is an example of one from an on-line tutorial that kind of works as a C&P but it's far from what I need. It also produces this: "CLIENT ERROR: TUINSRemoteViewController does not override -viewServiceDidTerminateWithError: and thus cannot react to catastrophic errors beyond logging them" so it's not really good code.
struct DataChooserView: View {
@State private var username = "@twostraws"
var body: some View {
VStack {
TextField("Username", text: $username)
.textFieldStyle(.roundedBorder)
PasteButton(payloadType: String.self) { strings in
guard let first = strings.first else { return }
username = first
}
.buttonBorderShape(.capsule)
}
.padding()
}
}
I'm inexperienced in Swift/SwiftUI but learning.
After a lot of digging I found that this works for drag & drop.
Need to include:
@Binding var imagePathList: [String] // Debug GOAt
@Binding var imageShortNameList: [String]
@State var url = URL.self
@State var isTargeted = false // ???
I found in de-bugging that imagePathList.count immediately after the drop is processed returns the count - 1, that is the count was not yet updated after the last .append. That was unexpected!
Image(nsImage: nsimg)
.resizable()
.scaledToFill()
.aspectRatio(contentMode: .fit)
.frame(width: 640, height: 480)
.border(.green)
.onDrop(of: [.fileURL], isTargeted: $isTargeted) { providers in
imagePathList.removeAll()
imageShortNameList.removeAll()
for provider in providers {
provider.loadObject(ofClass: URL.self) { url, error in
if let url = url {
if url.isFileURL && url.pathExtension == "raw" {
imagePathList.append(url.absoluteString)
imageShortNameList.append(url.lastPathComponent)
} else {
// Handle non-file URLs (e.g., directories)
print("Invalid URL: \(url)")
}
} else if let error = error {
// Handle any errors that occur during URL loading
print("Error loading URL: \(error.localizedDescription)")
}
}
} // DEBUG BELOW
print("First Image \(imageShortNameList.first ?? "")")
print("Last Image \(imageShortNameList.last ?? "")")
return true
} // attract user attention
.border(isTargeted ? Color.red.opacity(1.0) : Color.clear, width: isTargeted ? 2 : 1)