WKWebView not loading URLs served by localhost on iOS
Asked Answered
C

1

7

I have an iOS application that is attempting to run a HTTP web server in a thread, with a UI that consists of a single WKWebView pointed at that web server (i.e., an "Electron"-style app). However, I cannot get the WKWeView to display - or even to request - the content being served by the web server.

If I programatically make a HTTP request on the webserver, the application logs show a request being made, and the response payload contains the content I expect.

However, if I try to load http://127.0.0.1:8000 (or any other port) in the WKWebView, no web content is loaded. The web server doesn't even show a request being made.

If I point the webview at a HTTPS URL (e.g., https://google.com/), it displays the expected content.

If I point the webview at a HTTP URL (e.g., http://neverssl.com/), it displays the expected content.

I have a navigation delegate installed on the WKWebView; it shows that a provisional navigation has begun, but no other load progress delegate methods are invoked.

There are no other errors or progress indicators in the application's log. After about 30 seconds, I get the log message:

[ProcessSuspension] 0x1321c7eb0 - TimedActivity::activityTimedOut:

and after about another 30 seconds, I get:

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

Based on the error code, this appears to be a timeout. However, no request is being made on the web server, so it's not the web server timing out.

If I use the same server and WKWebView code on macOS, setting the WKWebView's url to http://127.0.0.1:8000 makes a request on the internal web server, and the page is displayed.

All my searches around this problem suggest the problem is related to app permissions - but I have set all the keys that I can find that might relate to this problem in my application's 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>

(AFAICT, most of these shouldn't be needed, but I've included them anyway to rule out permissions as the source of the problem).

What ideas on what is going on here? Or even ideas on how to diagnose what might be going on?

Cowberry answered 16/10, 2022 at 15:20 Comment(4)
Do you run the server in a detached queue ? As the WKWebView and the server must run at the same time, WKWebView in main thread and webserver in another.Clock
Yes - the web server is running in a completely separate thread. I can make programmatic web requests in the main thread, and those requests don’t block the web server.Cowberry
Shouldn’t it be <key>127.0.0.1:80</key>? Try adding portFrail
@LawrenceGimenez its not working. Its actually need to disable the access control check from the WKWebView, but it seems not well documented how to do it.Royceroyd
C
1

For the sake of posterity - I found the answer to this. The problem was that my app was using some customisations of the iOS event loop, which was causing events (including network events) queued from the non-main thread to not be processed until events occur on the main thread, flushing the event loop.

The "manual" fix was to have a button in the GUI; even if the button is attached to nothing, the events generated by the button were sufficient to flush the event queue, and cause the network events from the background thread to load.

The permanent fix was this PR to Rubicon, which was released in Rubicon 0.4.4.

Cowberry answered 18/5, 2023 at 22:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.