Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift URL另存为扩展名_Swift_Url_Nssavepanel - Fatal编程技术网

Swift URL另存为扩展名

Swift URL另存为扩展名,swift,url,nssavepanel,Swift,Url,Nssavepanel,当此URL扩展作为面板运行时,它无法返回URL,似乎绕过了完成: func saveAs() -> URL? { let savePanel = NSSavePanel() var saveAsURL : URL? = nil savePanel.canCreateDirectories = true savePanel.nameFieldStringValue = self.lastPathComponent savePanel.director

当此URL扩展作为面板运行时,它无法返回URL,似乎绕过了完成:

func saveAs() -> URL? {
    let savePanel = NSSavePanel()
    var saveAsURL : URL? = nil

    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
            /*if result == .OK {*/ saveAsURL = savePanel.url //}
        })
    }
    else
    {
        NSApp.activate(ignoringOtherApps: true)

        if savePanel.runModal() == .OK {
            saveAsURL = savePanel.url
        }
    }
    Swift.print("saveAsURL => \(saveAsURL.debugDescription)")

    return saveAsURL
}
但作为独立窗口运行,它工作正常。还有另一个相关的答案,但这里的用法是不同的:即

guard let saveAsURL = URL.init(string: "download.dmg").saveAs() else { return }

我假设用户取消将推断处理应该结束。

当你说
.runModal
时,你的代码做了一件非常非常奇怪的事情:它停止并等待用户处理模式对话框(也称为阻塞)。这可以追溯到OSX/Cocoa的早期,是一种行为异常。因此,结果是,当我们到达方法和您的
Swift.print
return
结束时,我们从模式对话框返回,并从中获得了值


但是,正如我所说,这完全是奇怪的。(事实上,我不确定我能想出任何其他类似的Cocoa调用。)
.beginsheetModel
调用行为正常,即在调用后,您的代码继续运行,并在模式表出现之前,以
打印和
返回结束。然后,在模式表中发生的事情与此处的调用代码异步发生,即稍后。因此,您无法从对话框返回任何值,因为您需要一台时间机器来展望未来。这是这类事情的标准模式。

我根据我的建议想到的是:一个完成处理程序

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)
     })

我想我更喜欢老一套;-)

如果术语“asynchronous”对您来说很陌生,您可能想读“Yes”,但引用的答案假定是正确的,否则我就看不出为什么扩展的行为会有所不同?我认为一个可行的解决方案是将saveAs()传递给一个完成处理程序,但我不知道另一个答案是否有效?我在扩展中加入了相同的行为,所以也许completion()是唯一的解决方案?但我还是把这两个搞混了。我不能帮你回答其他问题。我相信我所说的关于你的代码是正确的,只要在你的代码中加入更多的
print
语句,就可以很容易地确认它。是的,你当然是对的,我最初的问题和它的上下文是关于:它作为一个扩展的使用与其他答案的使用,因为它是串联的;然而,两者都表现出所描述的相同行为。我想,在过去,人们更容易理解表格的完整性。