Load local web files & resources in WKWebView
Updated for Swift 4, Xcode 9.3
This methods allows WKWebView to properly read your hierarchy of directories and sub-directories for linked CSS, JS and most other files. You do NOT need to change your HTML, CSS or JS code.
Solution (Quick)
- Add the web folder to your project (File > Add Files to Project)
- Copy items if needed
- Create folder references *
- Add to targets (that are applicable)
Add the following code to the
viewDidLoad
and personalize it to your needs:let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
Solution (In-Depth)
Step 1
Import the folder of local web files anywhere into your project. Make sure that you:
☑️ Copy items if needed
☑️ Create folder references (not "Create groups")
☑️ Add to targets
Step 2
Go to the View Controller with the WKWebView and add the following code to the viewDidLoad
method:
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
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:
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.uiDelegate = self
webView.navigationDelegate = self
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "Website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
}
}
If any of you have further questions about this method or the code, I'll do my best to answer!
How to load local html file into UIWebView with swift4.2
In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView.
import WebKit
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let localFilePath = Bundle.main.url(forResource: "document_terms_of_use", withExtension: "html")
let request = URLRequest(url: localFilePath!)
webView.load(request as URLRequest)
}
Cannot load a local html file into a WKWebView on device only (works on simulator)
OK I have found "why" it was not working. I changed this:
[self.webView loadFileURL:URL allowingReadAccessToURL:URL];
to this:
[self.webView loadFileURL:URL.absoluteURL allowingReadAccessToURL:rootAppURL];
with rootAppURL
being:
NSString *rootappPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www"];
NSURL *rootAppURL = [NSURL fileURLWithPath:rootappPath isDirectory:YES];
And it now works on ios < 13
What's the difference between UIWebView and WKWebView when loading local resources
A couple points:
- Apple recommends that you use
WKWebview
for iOS 8 and later. I would avoid writing new code withUIWebView
.
In apps that run in iOS 8 and later, use the
WKWebView
class instead of usingUIWebView
. Additionally, consider setting theWKPreferences
propertyjavaScriptEnabled
tofalse
if you render files that are not supposed to run JavaScript.
- Apple has been trying to move away from path and instead wants to use URI even for local files. They recommend that you NOT use
/path/to/file.png
and usefile:///path/to/file.png
instead.
As to why one URL works and the other does not, let's make a minimal example:
let realPath = "/path/to/file.png"
let url = URL(string: realPath) // /path/to/file.png
let fileUrl = URL(fileURLWithPath: realPath) // file:///path/to/file.png
url
does not provide the scheme (a.k.a protocol). It should only be used in conjunction with another URL to give the absolute address of the resource you are trying to reach.UIWebView
supports it for backwards-compatibility reasons but Apple decided to start clean withWKWebView
.fileURL
has a scheme (file://
) that tells the resource is located on the local file system. Other common schemes arehttp
,https
,ftp
, etc. It's a complete address to a resource so both views know how to resolve it.
How to load the html file with pdf on iOS WKWebView
Let me answer my own question.
I have used WKWebViewLocal library for creating a localhost server.
Now, this will create access the local files via host name. Using this approach apps' memory utilization has been optimized a lot (Only because of WKWebView).
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"swift_tutorial" ofType:@"pdf"];
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"viewer" ofType:@"html" inDirectory:@"PDFJS/web"];
NSString *finalPath = [NSString stringWithFormat:@"http://localhost:8080%@?file=%@#page=1",htmlPath, filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:finalPath]];
[self.webView loadRequest:request];
now, the finalpath will be
http://localhost:8080/~~~~~~~/PDFJS/web/viewer.html?file=/Users/~~~~~~/swift_tutorial.pdf#page=1
Related Topics
Change Bundle Identifier in Xcode When Submitting My First App in iOS
Uitableview Disable Swipe to Delete, But Still Have Delete in Edit Mode
Xcode Unit Testing with Cocoapods
Uicollectionview's Cellforitematindexpath Is Not Being Called
When to Use Uicollectionview Instead of Uitableview
Sending Push Notifications to iOS from Pwa
Set Uitableview Content Inset Permanently
Toplayoutguide in Child View Controller
How to Change "Initwithnibname" in Storyboard
iOS App Submission and Beta Review Process
Afnetworking: Handle Error Globally and Repeat Request
How to Get Distance of Object from iPhone Camera Using Image Exif Meta Data
Launch a Local Notification at a Specific Time in iOS
In-App Purchase in Swift with a Single Product
iOS 8 - Screen Blank After Dismissing View Controller with Custom Presentation
How to Ask User for Camera Access After They Have Already Denied It on iOS