Что я придумал после моего предложения re: обработчик завершения.
func saveAs(responseHandler: @escaping (URL?) -> Void) {
let savePanel = NSSavePanel()
savePanel.canCreateDirectories = true
savePanel.nameFieldStringValue = self.lastPathComponent
savePanel.directoryURL = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first!
if let keyWindow = NSApp.keyWindow {
savePanel.beginSheetModal(for: keyWindow, completionHandler: { result in
responseHandler( result == .OK ? savePanel.url : nil )
})
}
else
{
NSApp.activate(ignoringOtherApps: true)
let result = savePanel.runModal()
responseHandler( result == .OK ? savePanel.url : nil )
}
}
и назвал так - ответный делегат; пользователь щелкнул ссылку на скачивание (двоичного) файла данных, известного по его UTI, поэтому мы загружаем, а затем возвращаемся к более раннему URL:
guard url.hasDataContent(), let suggestion = response.suggestedFilename else { decisionHandler(.allow); return }
let downloadDir = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first!
let saveURL = downloadDir.appendingPathComponent(suggestion)
saveURL.saveAs(responseHandler: { saveAsURL in
if let saveAsURL = saveAsURL {
self.loadFileAsync(url, to: saveAsURL, completion: { (path, error) in
if let error = error {
NSApp.presentError(error)
}
else
{
if appDelegate.isSandboxed() { _ = appDelegate.storeBookmark(url: saveAsURL, options: [.withSecurityScope]) }
}
})
}
decisionHandler(.cancel)
self.backPress(self)
})
Я думаю, что мне больше нравится старый способ; - )