Обновление : 13 октября 2018
Кажется, что эта область является довольно новой с WWDC16, но документы устарели.В приложении, основанном на документе / URL, мы хотим перетащить документ - не файл, значок в видоискатель - в виде файла, в другом месте в виде строки и т. Д.
Как мой ранее связанный вопрос - спасибо Willeke это начинается с метода делегата окна, этот пост: Как на самом деле реализовать перетаскивание файлов из вашего приложения на Mac и пример Apple Поддержка перетаскивания файловОбещания мы собираем следующее (будет в моем проекте github SimpleViewer ):
// MARK:- Document Drag File Promise
/// queue used for reading and writing file promises
private lazy var workQueue: OperationQueue = {
let providerQueue = OperationQueue()
providerQueue.qualityOfService = .userInitiated
return providerQueue
}()
/// directory URL used for accepting file promises
private lazy var destinationURL: URL = {
let destinationURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Drops")
try? FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)
return destinationURL
}()
func window(_ window: NSWindow, shouldDragDocumentWith event: NSEvent, from dragImageLocation: NSPoint, with pasteboard: NSPasteboard) -> Bool {
let docButton = window.standardWindowButton(.documentIconButton)?.cell?.controlView
let url = (document as! Document).fileURL
if url?.scheme != "file" {
Swift.print("WindowDelegate -shouldDragDocumentWith(\(String(describing: url))")
let item = MyFilePromiseProvider.init()
item.fileType = kUTTypeData as String
item.delegate = self
item.userInfo = ["document" : document]
pasteboard.writeObjects([item])
}
return true
}
// MARK:- Drag File Promise
public func filePromiseProvider(_ filePromiseProvider: NSFilePromiseProvider, fileNameForType fileType: String) -> String {
let urlString = (document as! Document).fileURL?.lastPathComponent
let fileName = String(format: "%@.webloc", urlString!)
return fileName
}
public func filePromiseProvider(_ filePromiseProvider: NSFilePromiseProvider,
writePromiseTo url: URL,
completionHandler: @escaping (Error?) -> Void) {
let urlString = String(format: """
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>URL</key>
<string>%@</string>
</dict>
</plist>
""", ((document as! Document).fileURL?.absoluteString)!)
Swift.print("WindowDelegate -filePromiseProvider\n \(urlString)")
do {
try urlString.write(to: url, atomically: true, encoding: .utf8)
completionHandler(nil)
} catch let error {
completionHandler(error)
}
}
// MARK: - NSFilePromiseProviderDelegate
/// - Tag: ProvideOperationQueue
func operationQueue(for filePromiseProvider: NSFilePromiseProvider) -> OperationQueue {
return workQueue
}
и наш поставщик обещаний.
public class MyFilePromiseProvider : NSFilePromiseProvider {
public override func writableTypes(for pasteboard: NSPasteboard) -> [String] {
Swift.print("WindowDelegate -writableTypes()")
return [kUTTypeData as String]
}
public override func writingOptions(forType type: String, pasteboard: NSPasteboard) -> NSPasteboard.WritingOptions {
if type == kUTTypeData as String {
Swift.print("MyPromiseProvider -writingOptions()")
return []
}
return super.writingOptions(forType: type, pasteboard: pasteboard)
}
public override func pasteboardPropertyList(forType type: String) -> Any? {
if type == kUTTypeData as String {
let document : Document = (userInfo as! Dictionary)["document"]!
let urlString = String(format: """
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>URL</key>
<string>%@</string>
</dict>
</plist>
""", (document.fileURL?.absoluteString)!)
Swift.print("MyPromiseProvider -pasteboardPropertyList()")
return urlString
}
return super.pasteboardPropertyList(forType: type)
}
public override func namesOfPromisedFilesDropped(atDestination dropDestination: URL) -> [String]? {
return ["names"]
}
}
Трассировка XcodeВывод / debug показывает
WindowDelegate -shouldDragDocumentWith(Optional(https://www.apple.com/)
WindowDelegate -writableTypes()
MyPromiseProvider -writingOptions()
MyPromiseProvider -pasteboardPropertyList()
/
Но Finder отказывается сбросить?При попадании в текстовый приемник - т.е. вывод отладки XCode, я просто получаю "/" - т.е. кажется, что отправленная строка была "file: ///"?
Я ожидаю - но никогда не получаювызываемый, функции делегата окна:
-filePromiseProvider(_, fileType: )
-filePromiseProvider(_, url:, completionHandler: )
Суть этого в том, чтобы иметь в моем провайдере обещаний инструмент делегирования 'shouldDrag', именующий делегата окна через объект userinfo элемента вставки.
То, что я пытаюсь сделать, это написать, где указано, файл .webloc с подробной информацией о нефайловых URL-адресах.
Но я подозреваю, что отказ Finder говорит мне, что я не настроил это правильно?