From 5ddecf117bd5d10487f84733767d0cc3f025c78f Mon Sep 17 00:00:00 2001 From: Kristofer Date: Thu, 15 Aug 2024 05:57:53 -0400 Subject: [PATCH] adds .webloc support Adds .webloc support for dropping a web url from browser into a .stapled file. Launching works as well without mods. --- Stapler/StaplerApp.swift | 85 ++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/Stapler/StaplerApp.swift b/Stapler/StaplerApp.swift index 4cbf0f2..b35df4b 100644 --- a/Stapler/StaplerApp.swift +++ b/Stapler/StaplerApp.swift @@ -218,7 +218,7 @@ class StaplerViewModel: ObservableObject { return false } - func handleError(_ error: Error) { + func handleError(_ error: Error) { DispatchQueue.main.async { self.errorMessage = error.localizedDescription } @@ -300,29 +300,66 @@ struct ContentView: View { } .frame(minWidth: 300, minHeight: 200) .focused($isViewFocused) - .onDrop(of: [.fileURL], isTargeted: nil) { providers in - let wasEmpty = viewModel.document.aliases.isEmpty - for provider in providers { - _ = provider.loadObject(ofClass: URL.self) { url, error in - if let error = error { - viewModel.handleError(error) - } else if let url = url { - DispatchQueue.main.async { - do { - let newAlias = try AliasItem(url: url) - viewModel.addAlias(newAlias) - if wasEmpty { - updateDocument() - } else { - document.aliases = viewModel.document.aliases - } - } catch { - viewModel.handleError(error) - } - } - } - } - } + .onDrop(of: [.url, .urlBookmarkData], isTargeted: nil) { providers in + let wasEmpty = viewModel.document.aliases.isEmpty + for provider in providers { + _ = provider.loadObject(ofClass: URL.self) { url, error in + if let error = error { + viewModel.handleError(error) + } else if let url = url { + DispatchQueue.main.async { + do { + let newAlias = try AliasItem(url: url) + viewModel.addAlias(newAlias) + if wasEmpty { + updateDocument() + } else { + document.aliases = viewModel.document.aliases + } + } catch { + viewModel.handleError(error) + } + } + } + } + } + // If there are no items conforming to the specified types, check for file promise receivers in the pasteboard + let pasteboard = NSPasteboard(name: .drag) + guard let filePromises = pasteboard.readObjects(forClasses: [NSFilePromiseReceiver.self], options: nil), + let receiver = filePromises.first as? NSFilePromiseReceiver else { + return false + } + + // Process the first file promise receiver + let queue = OperationQueue() + receiver.receivePromisedFiles(atDestination: FileManager.default.temporaryDirectory, //URL.temporaryDirectory, + operationQueue: queue) { (url, error) in + if let error = error { + print("Error loading dropped item from pasteboard: \(error.localizedDescription)") + } else { + DispatchQueue.main.async { + // url is a .webloc + let data = try? Data.init(contentsOf: url) as Data + // turn webloc contents (xml) into plist dict + let dict = try! PropertyListSerialization.propertyList(from:data ?? Data(), options: [], format: nil) as! [String:Any] + let urlString = dict["URL"] as! String + let newUrl = URL(string: urlString) + do { + let newAlias = try AliasItem(url: url) + viewModel.addAlias(newAlias) + if wasEmpty { + updateDocument() + } else { + document.aliases = viewModel.document.aliases + } + } catch { + viewModel.handleError(error) + } + + } + } + } + return true } .alert(isPresented: $showingErrorAlert) {