为什么我无法在 Web 视图中打开 App Store 链接?

Mis*_*ros 4 webview app-store ios swift

我总是收到这个错误:

WebPageProxy::didFailProvisionalLoadForFrame: frameID=3, domain=WebKitErrorDomain, code=102
Run Code Online (Sandbox Code Playgroud)

正常链接可以使用,但 AppStore 链接无法使用

我想要的是打开 AppStore 的链接,但我无法在本地执行此操作,因为该网络是从 Qualtrics 网络加载的。

我尝试添加 navigationAction 函数,但这不起作用,我猜测请求可能需要一些时间,我需要一种以异步方式加载数据的方法,但说实话我真的不知道

import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    let html = """


<a href="https://apps.apple.com/us/app/directorio-notarios-cdmx/id1544000342"> Appstore link dont open</a></span></span><br />

<a href="https://landercorp.mx" rel="noopener"> Normal link </a></span></span><br />
"""

    var loadStatusChanged: ((Bool, Error?) -> Void)? = nil

    func makeCoordinator() -> WebView.Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> WKWebView {
        let view = WKWebView()
        view.navigationDelegate = context.coordinator
        view.loadHTMLString(html, baseURL: nil)
        return view
    }



    func updateUIView(_ uiView: WKWebView, context: Context) {
    }

    class Coordinator: NSObject, WKNavigationDelegate {
        let parent: WebView

        init(_ parent: WebView) {
            self.parent = parent
        }

        
    }
}
 

struct ContentView: View {
    var body: some View {
        WebView()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

Sha*_*ank 7

点击它们时的某些链接可能会激活带有非 HTTP 的 URL 方案的操作/重定向,例如

  • _blank打开一个新选项卡
  • mailto启动邮件应用程序
  • 设备操作系统熟悉的其他一些深度链接技术

我相信应用程序商店链接使用了上述的组合,并且 WKWebView 无法处理非 HTTPs 方案。

你能做的就是监听使用失败的URLWKNavigationDelegate并进行相应的处理

我没有使用 SwiftUI,但我想你可以明白。

使用与您相同的 HTML 和两个链接进行设置

class ViewController: UIViewController, WKNavigationDelegate
{
override func viewDidAppear(_ animated: Bool)
    {
        super.viewDidAppear(animated)
        
        let html = """
        <a href="https://apps.apple.com/us/app/directorio-notarios-cdmx/id1544000342"> Appstore link dont open</a></span></span><br />

        <a href="https://landercorp.mx" rel="noopener"> Normal link </a></span></span><br />
        """
        
        let webview = WKWebView()
        webview.frame = view.bounds
        webview.navigationDelegate = self
        view.addSubview(webview)
        webview.loadHTMLString(html, baseURL: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我实现这些WKNavigationDelegate功能

  1. decidePolicyFor navigationAction (文档链接)甚至允许处理不遵循 HTTPs 方案的 url

  2. 导航失败委托功能 webView didFailProvisionalNavigation并检查 iOS 是否可以处理在新选项卡、邮件、深层链接等中打开,因此在您的情况下它将打开应用程序商店

  3. 您还可以在此WKNavigationDelegate 函数中实现与第 2 点相同的逻辑, 以防万一

// MARK: WKNavigationDelegates

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

func webView(_ webView: WKWebView,
             didFailProvisionalNavigation navigation: WKNavigation!,
             withError error: Error)
{
    manageFailedNavigation(webView,
                           didFail: navigation,
                           withError: error)
}

func webView(_ webView: WKWebView,
             didFail navigation: WKNavigation!,
             withError error: Error)
{
    manageFailedNavigation(webView,
                           didFail: navigation,
                           withError: error)
}

private func manageFailedNavigation(_ webView: WKWebView,
                                    didFail navigation: WKNavigation!,
                                    withError error: Error)
{
    // Check if this failed because of mailto, _blank, deep links etc
    // I have commented out how to check for a specific case like open in a new tab,
    // you can try to handle each case as you wish
    if error.localizedDescription
        == "Redirection to URL with a scheme that is not HTTP(S)"
       //let url = webView.url, url.description.lowercased().range(of: "blank") != nil
    {
        // Convert error to NSError so we can access the url
        let nsError = error as NSError
        
        // Get the url from the error
        // This key could change in future iOS releases
        if let failedURL = nsError.userInfo["NSErrorFailingURLKey"] as? URL
        {
            // Check if the action can be handled by iOS
            if UIApplication.shared.canOpenURL(failedURL)
            {
                // Request iOS to open handle the link
                UIApplication.shared.open(failedURL, options: [:],
                                          completionHandler: nil)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

尝试一下并检查这是否可以解决您的问题。在我这边,两个链接似乎都工作正常:

打开 WKWebview target="_blank" mailto deeplink 新选项卡应用商店链接或在 Web 视图中打开应用商店链接

  • 谢谢你!昨天,我阅读了所有与堆栈溢出相关的问题,但无法找到一些对我有帮助的答案,这不仅是一个明确的答案,而且是一个非常完整的答案 (2认同)