通过macOS本机应用程序中的SwiftUI WKWebView调用时,如何使文件打开对话框起作用?

埃萨罗霍

我目前正在运行一个用SwiftUI制作的简单化WkWebView-可以从StackOverflow帖子中瞥见所有建议它打开一个网站。该网站有一个浏览器按钮。如果单击Safari上的浏览器按钮,则会打开Finder窗口。如果我在用Xcode创建的.app中执行相同的操作,则Finder窗口不会打开。

这是我在沙箱中启用的内容:

XCode App沙箱设置

我使用的代码是这样(全部来自ContentView.swift)

import SwiftUI
import WebKit


public struct WebBrowserView {

    private let webView: WKWebView = WKWebView()

    // ...

    public func load(url: URL) {
        webView.load(URLRequest(url: url))
    }

    public class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {

        var parent: WebBrowserView

        init(parent: WebBrowserView) {
            self.parent = parent
        }

        public func webView(_: WKWebView, didFail: WKNavigation!, withError: Error) {
            // ...
        }

        public func webView(_: WKWebView, didFailProvisionalNavigation: WKNavigation!, withError: Error) {
            // ...
        }

        public func webView(_: WKWebView, didFinish: WKNavigation!) {
            // ...
        }

        public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
            // ...
        }

        public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            decisionHandler(.allow)
        }

        public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
            if navigationAction.targetFrame == nil {
                webView.load(navigationAction.request)
            }
            return nil
        }
    }

    public func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
}


#if os(macOS) // macOS Implementation (iOS version omitted for brevity)
extension WebBrowserView: NSViewRepresentable {

    public typealias NSViewType = WKWebView

    public func makeNSView(context: NSViewRepresentableContext<WebBrowserView>) -> WKWebView {

        webView.navigationDelegate = context.coordinator
        webView.uiDelegate = context.coordinator
        return webView
    }

    public func updateNSView(_ nsView: WKWebView, context: NSViewRepresentableContext<WebBrowserView>) {

    }
}
#endif

struct BrowserView: View {

    private let browser = WebBrowserView()

    var body: some View {
        HStack {
            browser
                .onAppear() {
                    self.browser.load(url: URL(string: "http://specificwebsitewithbrowserbutton")!)
                }
        }
        .padding()
    }
}


struct ContentView: View {

    @State private var selection = 1

    var body: some View {
                BrowserView()
                .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

那么,如何为该.app提供足够的权限,以便在我单击网站上的“上传”按钮时打开Finder窗口?

他的脾气

您必须实现以下WKUIDelegate委托方法

   /** @abstract Displays a file upload panel.
     @param webView The web view invoking the delegate method.
     @param parameters Parameters describing the file upload control.
     @param frame Information about the frame whose file upload control initiated this call.
     @param completionHandler The completion handler to call after open panel has been dismissed. Pass the selected URLs if the user chose OK, otherwise nil.

     If you do not implement this method, the web view will behave as if the user selected the Cancel button.
     */
    @available(OSX 10.12, *)
    optional func webView(_ webView: WKWebView, runOpenPanelWith 
                  parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, 
                  completionHandler: @escaping ([URL]?) -> Void)

这是实施示例

func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) {
    let openPanel = NSOpenPanel()
    openPanel.canChooseFiles = true
    openPanel.begin { (result) in
        if result == NSApplication.ModalResponse.OK {
            if let url = openPanel.url {
                completionHandler([url])
            }
        } else if result == NSApplication.ModalResponse.cancel {
            completionHandler(nil)
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在SwiftUI macOS应用程序中模糊背景?

混合应用程序:通过本机(本地)文件在WebView中运行Web应用程序

如何在macOS(不是iOS)上的SwiftUI中以编程方式从后台打开应用程序窗口?

FBSDKLoginManager无法在本机ios应用程序中打开登录对话框

使用AVPlayer在macOS SwiftUI应用程序中播放本地视频文件

通过Phonegap应用程序在iOS上打开本机地图应用程序

Tizen 无法在本机应用程序中写入文件

WKWebView 弹出窗口在 MacOS 应用程序中不起作用

Chocolatey无法安装应用程序,“您如何打开此文件?” 而是打开对话框

如何在Android本机应用程序活动中画圆

如何在本机应用程序中获取数据

在React Native中如何访问本机相机应用程序?

在基于macOS Python的应用程序上如何通过本机GUI最佳地检索sudo密码的方式和位置-(同时保持交互式输出流(stdout))

通过外部应用程序打开松弛对话框

如何仅通过在 macOS 中键入应用程序的名称从终端运行应用程序?

如果安装本机应用程序,则使用Facebook最新的SDK登录,然后在Android中未打开对话框

如何在反应本机应用程序中检测应用程序首次启动?

如何在Linux上的Java应用程序的“打开文件”对话框中显示隐藏文件(。*)?

如何管理VB窗体应用程序中的对话框通过其调用者设置的传递值

Windows 8应用程序的“打开文件”对话框

打开文件对话框时应用程序冻结

如何通过href =“”在移动设备上打开Facebook本机应用程序

如何从终端打开“运行应用程序”对话框?

如何使用Electron显示打开的文件本机对话框?

如何在像皇室冲突 pubg COD 这样的本机应用程序中从设备打开任何随机应用程序?

如何使Symfony 2中的复选框起作用?

在iOS上通过本机Facebook应用程序打开Facebook链接

如何在macOS Catalina中删除系统应用程序?

如何在macOS应用程序中从App注册服务?