In my Swift iOS app, I want to download some dynamic HTML pages from a remote server, save them in the document directory, and display those pages from document directory.
I was using this to load the page:
var appWebView:WKWebView?
...
appWebView!.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: htmlPath)))
Everything works on the simulator, but when I moved to real phones, it just showed a blank page. I then connected to the app using Safari, and found it complained with "Failed to load resource".
I then tried to first read the content of the page at htmlPath
, then use
appWebView!.loadHTMLString()
to load the page. It works when the HTML page is simple. But if the HTML references something else, i.e. a JavaScript file also in the document directory (with an absolute path like <script src="file:////var/mobile/Containers/Data/Application/762035C9-2BF2-4CDD-B5B1-574A0E2B0728/Documents/xxxxx.js">
), it will fail to load.
Does anyone know why this happens, and how to resolve the issue?
More info:
- XCode version: 7.3.1
- Deployment Target: 8.1 (I tried to use 9.3 too, but that didn't help.)
This works nicely with file URL or remote URL, and whether file is in the bundle or in documents:
This solution helped me:
Swift 4 Method
This method allows WKWebView to properly read your hierarchy of directories and sub-directories for linked CSS/JS files. You do NOT need to change your HTML, CSS or JS code.
Updated for Xcode 9.3
Step 1
Import the folder of local web files anywhere into your project. Make sure that you:
Step 2
Go to the View Controller with the WKWebView and add the following code to the
viewDidLoad
method:index
– the name of the file to load (without the.html
extension)website
– the name of your web folder (index.html
should be at the root of this directory)Conclusion
The overall code should look something like this:
If any of you have further questions about this method or the code, I'll do my best to answer. :)
Check that ticket: iOS: How to load local files (not in the bundle) in a WKWebView?
This is a simplified version of what I have used to load local files in a project of mine (iOS 10, Swift 3). I have just updated my code (7.5.2017) after testing it out again on iOS 10.3.1 and iPhone 7+ as requested by Raghuram and Fox5150 in the comments.
I just created a completely new project and this is the folder structure:
Update 19.04.2018: Added a new feature to download a .zip with HTML, CSS, JS files, unzip it in /Documents/ (Alamofire + Zip) and then load those files into the webView. You can find it in the GitHub sample project as well. Again, feel free to fork & star! :)
Update 08.02.2018: finally added a GitHub sample project, which also includes a local JavaScript file. Feel free to fork & star! :)
Version 1 with webView.loadFileURL()
ViewController.swift
Version 2 with webView.loadHTMLString()
ViewController.swift
Gotchas to look out for:
css/styles.css
because iOS will flatten your file structure and styles.css will be on the same level as index.html so write<link rel="stylesheet" type="text/css" href="styles.css">
insteadGiven the 2 versions and the gotchas here are my html/css files from the project:
web/index.html
web/css/styles.css
If somebody wants a GitHub sample project, tell me in the comments section and I'll upload it.
This works well (Swift 3, Xcode 8):