How to load an external HTML file in an iOS app

Updated (22/10/2021): Since the time of writing this, Apple has addressed the issue discussed below. This workaround should no longer be needed for newer iOS versions but we will leave this live for reference for older versions.

Daily Keyframes are byte-sized tips from our engineers. We hope they help you remove roadblocks so you can focus on building.

When Apple announced, in iOS 14.3, that WKWebView would have support for navigator.mediaDevices.getUserMedia, we were ecstatic. It meant that iOS applications which relied on a webview could now use audio and video devices, a crucial element for an audio or video call. We were so excited, in fact, that we built Party Line.

However, in the course of development we quickly realized there was a known bug. navigator.mediaDevices.getUserMedia would only work if the HTML file in question was loaded via http(s) origins. If you were loading a local HTML file (using file://), getUserMedia would be denied. Luckily this has been fixed, but those fixes can take time to land, and even longer for users to upgrade to the latest OS version.

So what can be done to get around this today?

The easiest thing to do is host your file somewhere that serves it via https (might as well keep it secure, while you’re at it). If you already have a server for your static assets, simply add it there and you’re good to go. If you don’t, and you want an easy solution, Netlify is a great modern platform for static file deployments (among other things) and even has a drag and drop feature. For Party Line, our iOS HTML file is deployed alongside our React web app, which makes it publicly accessible at

To use it in our iOS app, we reference it in Client.swift with the following code:

    private static var pageURL: URL {
        URL(string: "")!

And then load it in Client.swift with the following code:

let pageURL = Self.pageURL
self.webView.load(URLRequest(url: pageURL))

And that’s it!

If you want to read more about this, check out our html file, and these related tickets:

And if you’re curious about what we built, head over to the repo or read the blog post.

Never miss a story

Get the latest direct to your inbox.