UIWebView
HTML
Local Images
iOS Development
Mobile App Development

Using HTML and Local Images Within UIWebView

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

UIWebView is legacy technology, but older iOS codebases still sometimes need to load bundled HTML that references bundled images. The important detail is the base URL: local image paths only resolve correctly when the HTML is loaded relative to the folder that contains those assets. Without that base path, the HTML may render while every image stays broken.

Load Local HTML with a Correct Base URL

If your HTML and images live inside the app bundle, keep them in a predictable folder structure such as:

text
1Bundle/
2  web/
3    index.html
4    images/
5      logo.png

Then load the HTML string and point the base URL at the same bundle folder:

swift
1import UIKit
2
3let webView = UIWebView(frame: .zero)
4
5let folderURL = Bundle.main.bundleURL.appendingPathComponent("web")
6let htmlURL = folderURL.appendingPathComponent("index.html")
7
8let html = try String(contentsOf: htmlURL, encoding: .utf8)
9webView.loadHTMLString(html, baseURL: folderURL)

If index.html contains a relative image path such as images/logo.png, the web view can now resolve it against folderURL.

Example HTML That Uses a Local Image

Your bundled HTML might look like this:

html
1<!doctype html>
2<html>
3  <body>
4    <h1>Welcome</h1>
5    <img src="images/logo.png" width="120" />
6  </body>
7</html>

Because the image uses a relative path, it depends entirely on the base URL you pass from Swift or Objective-C. If the base URL is nil or points somewhere else, the image reference breaks.

Loading an HTML File Directly

Another option is to create a file URL and load a request:

swift
1import UIKit
2
3let htmlURL = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "web")!
4let request = URLRequest(url: htmlURL)
5
6let webView = UIWebView(frame: .zero)
7webView.loadRequest(request)

This can work for simple local content, but when relative assets become tricky, loadHTMLString(_:baseURL:) gives you more explicit control over how image paths are resolved.

Why Relative Paths Usually Beat Absolute Bundle Strings

You can generate full file URLs for each image and inject them into the HTML, but that is usually more brittle than keeping the HTML self-contained with relative paths. Relative references make the content portable inside the bundle and easier to preview or test outside the app.

The pattern is simple:

  • keep HTML and assets in the same bundle subtree
  • use relative paths in the HTML
  • pass the containing folder as baseURL

That is the core fix in most "HTML loads, images do not" cases.

Legacy Note: Prefer WKWebView in Modern Code

If you are writing new code, use WKWebView instead of UIWebView. The same local-file principle still applies: local HTML and local images resolve best when the base folder is explicit. The article title is about UIWebView, but the underlying asset-resolution pattern is still relevant when maintaining legacy screens or porting them forward.

Common Pitfalls

One common mistake is loading the HTML string with baseURL: nil. The HTML content may appear, but all relative image paths fail because the web view has no folder context.

Another mistake is putting the images in one bundle directory and the HTML in another while still using short relative paths that assume a shared root.

Developers also sometimes hardcode absolute file strings into the HTML. That makes the content harder to maintain and easier to break when bundle structure changes.

Finally, remember that UIWebView itself is legacy. If you are touching this area in a modern app, consider whether the right fix is to move the screen to WKWebView.

Summary

  • Bundled HTML can reference bundled images correctly when you provide the right base URL.
  • Keep HTML and image assets in a consistent bundle folder structure.
  • Use relative image paths inside the HTML file.
  • 'loadHTMLString(_:baseURL:) is often the most explicit way to control local asset resolution.'
  • For new code, prefer WKWebView, but the local-file loading pattern is the same idea.

Course illustration
Course illustration

All Rights Reserved.