WKWebView 未加载 iOS 上的 localhost 提供的 URL

fre*_*742 7 localhost ios wkwebview

我有一个 iOS 应用程序,它尝试在线程中运行 HTTP Web 服务器,其 UI 由指向该 Web 服务器的单个 WKWebView 组成(即“Electron”风格的应用程序)。但是,我无法让 WKWeView 显示 - 甚至请求-由 Web 服务器提供的内容。

如果我以编程方式在网络服务器上发出 HTTP 请求,应用程序日志将显示正在发出的请求,并且响应负载包含我期望的内容。

http://127.0.0.1:8000但是,如果我尝试在 WKWebView 中加载(或任何其他端口),则不会加载任何 Web 内容。Web 服务器甚至不显示正在发出的请求。

如果我将 webview 指向 HTTPS URL(例如https://google.com/),它会显示预期的内容。

如果我将 webview 指向 HTTP URL(例如http://neverssl.com/),它会显示预期的内容。

我在 WKWebView 上安装了一个导航委托;它表明临时导航已经开始,但没有调用其他加载进度委托方法。

应用程序日志中没有其他错误或进度指示器。大约 30 秒后,我收到日志消息:

[ProcessSuspension] 0x1321c7eb0 - TimedActivity::activityTimedOut:
Run Code Online (Sandbox Code Playgroud)

又过了大约 30 秒,我得到:

2022-10-16 07:54:25.373833-0700 Positron[51762:92124656] [Process] 0x130888218 - [pageProxyID=6, webPageID=7, PID=51772] WebPageProxy::didFailProvisionalLoadForFrame: frameID=3, isMainFrame=1, domain=NSURLErrorDomain, code=-1001, isMainFrame=1
Run Code Online (Sandbox Code Playgroud)

根据错误代码,这似乎是超时。但是,Web 服务器上没有发出任何请求,因此不是 Web 服务器超时。

如果我在 macOS 上使用相同的服务器和 WKWebView 代码,设置 WKWebView 的 urlhttp://127.0.0.1:8000向内部 Web 服务器发出请求,然后显示该页面。

我围绕此问题的所有搜索都表明该问题与应用程序权限有关 - 但我已在应用程序的 Info.plist 中设置了我能找到的可能与此问题相关的所有键:

<dict>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsLocalNetworking</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>127.0.0.1</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>
Run Code Online (Sandbox Code Playgroud)

(AFAICT,其中大部分不需要,但我无论如何都将它们包括在内,以排除权限作为问题根源的可能性)。

对这里发生的事情有什么想法?或者甚至关于如何诊断可能发生的情况的想法?

fre*_*742 1

为了子孙后代 - 我找到了这个问题的答案。问题是我的应用程序正在使用 iOS 事件循环的一些自定义,这导致从非主线程排队的事件(包括网络事件)在主线程上发生事件之前不会被处理,从而刷新事件循环。

“手动”修复是在 GUI 中添加一个按钮;即使按钮没有附加到任何东西,按钮生成的事件也足以刷新事件队列,并导致从后台线程加载网络事件。

永久修复是Rubicon 的 PR,它在 Rubicon 0.4.4 中发布。