What is the recommended way to programmatically apply proxy to WKWebView

Hi Apple engineers!

We are making an iOS browser and are planing to deliver a feature that allows enterprise customers to use a MAM key to set a PAC file for proxy. It's designed to support unmanaged device so the MDM based solutions like 'Global HTTP Proxy MDM payload' or 'Per-App VPN' simply don't work.

After doing some research we found that with WKWebView, the only framework allowed on iOS for web browsing, there's no API for programmatically setting proxy. The closes API is the WKURLSchemeHandler, but it's for data management not network request interception, in other word it can not be used to handle HTTP/HTTPS request well.

When we go from the web-view level to the app level, it seems there's no API to let an app set proxy for itself at an app-level, the closest API is Per-App VPN but as mentioned above, Per-App VPN is only available for managed device so we can't use that as well.

Eventually we go to the system level, and try to use Network Extension, but there's still obstacles. It seems Network Extension doesn't directly provide a way to write system proxy. In order to archive that, we may have to use Packet Tunnel Provider in destination IP mode and create a local VPN server to loop back the network traffic and do the proxy stuff in that server. In other word, the custom VPN protocol is 'forward directly without encryption'. This approach looks viable as we see some of the network analysis tools use this approach, but still I'd like to ask is this against App Store Review Guidelines?

If the above approach with Network Extension is not against App Store Review Guidelines, I have a further question that, what is the NEProxySettings of NETunnelNetworkSettings for? Is it the proxy which proxies the VPN traffic (in order to hide source IP from VPN provider) or it is the proxy to use after network traffic goes into the virtual private network?

If none of the above is considered recommended, what is the recommended way to programmatically set proxy on WKWebView on an unmanaged device (regardless of where the proxy runs, web-view/app/system)?

we found that with WKWebView … there's no API for programmatically setting proxy.

Correct. This is a long-standing pain point for folks in your situation (r. 20545691).

WKURLSchemeHandler … can not be used to handle HTTP/HTTPS request well.

Correct.

Per-App VPN is only available for managed device so we can't use that as well.

Correct [1].

still I'd like to ask is this against App Store Review Guidelines?

Only App Review can give you definitive answers about will or won’t be allowed on the store. However, I will say that DTS strongly recommends against ‘off label’ use of NE providers. Indeed, Matt just published a technote to that effect: TN3120 Expected use cases for Network Extension packet tunnel providers.

If none of the above is considered recommended, what is the recommended way to programmatically set proxy on WKWebView on an unmanaged device … ?

AFAIK there is no good solution to this problem.

Regardless of what else you do here, I encourage you to file an enhancement request against WKWebView requesting an API for applying proxy settings to just that view.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] On iOS. The story on macOS is more nuanced but that doesn’t help you because you’re targeting iOS.

Thanks Quinn,

We will submit enhancement request, but in the mean time we don't want to just wait and let this business opportunity slip through. We see similar enhancement request pending for years without any major progress. Such limitation only exists on iOS platform, which put us in an awkward position where other platforms has the feature ready but we can't deliver them because iOS doesn't support this scenario.

So we'd like to further investigate on what we can do based on available APIs. Seems Network Extension is the only way to go, can you help explain what the NEProxySettings of NETunnelNetworkSettings is for? More specifically, if a proxy is configured in NEProxySettings, is it used to proxy VPN traffic? Or it is a proxy inside the private network that traffics are sent to after received by the VPN server?

We will submit enhancement request

Thanks. I’d appreciate you posting the bug number here, just for the record.

We see similar enhancement request pending for years without any major progress.

Right. Indeed this very issue is the subject of a long-standing ER )-:

in the mean time we don't want to just wait

That’s understandable but…

Seems Network Extension is the only way to go

I’m sorry but I can’t help you with that. The reason why Matt wrote TN3120 is that we here in DTS see a lot of developers go down this path and then, some time down the road, they hit weird problems that have no solution. Using a packet tunnel provider as a way to get around limitations in WKWebView, and your desire to avoid MDM, is not something we support.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

What is the recommended way to programmatically apply proxy to WKWebView
 
 
Q