Search code examples
iosswiftwkwebviewgcdwebserver

Why is my XWebView served index.html using the file scheme and how do I change it?


I'm using a WKWebView to serve the index.html of a single page web app (ember) like this:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let webview = WKWebView(
            frame: view.frame, 
            configuration: WKWebViewConfiguration()
        )
        view.addSubview(webview)

        let root = NSBundle.mainBundle().resourceURL!
        let url = root.URLByAppendingPathComponent("dist/index.html")
        webview.loadFileURL(url, allowingReadAccessToURL: root)

Which works just fine to load the index file. But the index file is requesting it's links and resources using the file scheme? If I inspect the app with Safari as it runs in the inspector I see this error for all local resources:

[Error] Failed to load resource: ... file:///dist/assets/css/vendor.css

Which in the index.html looks like:

<link rel="stylesheet" href="./dist/assets/vendor.css">

What I want is for resource requests to go to my GCDWebServer that I set up like this:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    var webServer: GCDWebServer?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        self.webServer = GCDWebServer()
        self.webServer!.addGETHandlerForBasePath("/",
            directoryPath: NSBundle.mainBundle().bundlePath,            
            indexFilename: nil,
            cacheAge: 3600,
            allowRangeRequests: true
        )
        self.webServer!.startWithPort(8080, bonjourName: "GCD Web Server")
        print("GCD Server running at: \(self.webServer!.serverURL)")
        return true

And I have added the dist folder to the bundle in Xcode.

What am I missing here?


Solution

  • That's just how HTML works. HREFs that aren't absolute are relative to wherever the referencing page came from. So if you have images/foo.png on file:///dir/index.html, the browser will request file:///dir/images/foo.png.

    If you need the browser to fetch the resources from a different location, you'll need to use absolute URLs in your HTML (e.g. http://localhost:8080/whatever).