I want to open a local html file on Safari integration on my Swift 3 application.
I know how to do this with an url. This is the code that I use to do that:
let encodedString = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
let svc = SFSafariViewController(url: NSURL(string: encodedString!) as! URL)
self.present(svc, animated: true, completion: nil)
But I am not able to do the same with a local file. I have copied my html file on my project and I can see it on the directories tree but I am not able to make it to work. I have looked at Load local html into UIWebView using swift for reference.
How can I load a local html file into Safari integration?
Thanks in advance!
You can't do it using SFSafariViewController
From Apple Documentation:
1. Choosing the Best Web Viewing Class
If your app lets users view websites from anywhere on the Internet, use the SFSafariViewController class. If your app customizes, interacts with, or controls the display of web content, use the WKWebView class.
2. if you look at declaration of init
convenience init(url URL: URL)
url: The URL to navigate to. The URL must use the http or https scheme.
Using Webkit or WebView
helloAshok.html
<html>
<head>
</head>
<body>
<br />
<h2> Welcome ASHOK</h2>
</body>
</html>
ViewContrller.swift
class ViewController: UIViewController {
#IBOutlet weak var myWebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let localFilePath = Bundle.main.url(forResource: "helloAshok", withExtension: "html")
let request = URLRequest(url: localFilePath!)
myWebView.loadRequest(request)
}
}
Output:
Related
I am using SwiftUI along with UIViewRepresentable to instantiate a WKWebView to display my html content:
WebView
struct WebView : UIViewRepresentable {
let request: URLRequest
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.load(self.request)
}
}
SwiftUI View
let localFilePath = Bundle.main.url(forResource: "EULA for ALP app", withExtension: "html")
VStack{
WebView(request: URLRequest(url: localFilePath!))
}.padding([.leading,.trailing],20)
HTML
When I tap the span nothing happens as if its not registering the hit, I want to use another local HTML file like the one I am using inside the WebView so when the span gets tapped the WebView displays the corresponding file. I would also like to mention that HTML gets displayed correctly just without the href working.
<span href="file://practitionerPolicy.html">Tap Me!</span>
I assume in this case, as this is your internal resources, relative path should work, like
<span href="practitionerPolicy.html">Tap Me!</span>
I have a .html file stored in my project bundle. When I load it in WebView.(UIWebview/WKWebview) the data is loaded but the table structure in it isn't visible. The table borders, columns , rows. The values are just floating . In Chrome browser it opens properly.
let myURL = Bundle.main.url(forResource: "prescription", withExtension: "html")
let myURLRequest:URLRequest = URLRequest(url: myURL!)
webView.loadRequest(myURLRequest)
Chrome browser :
iOS App UIWebView :
The Html page is made responsive to fit in any sizes but I am not able to load in UIWebview properly as Web.
I need to store the file locally because I need to make changes to its values and show on webview.
Found the solution :
If you are applying some local css whose path is there in HTML file.
viz.
Add that css file "myDefault.css" to your xcode project directory.
Convert the HTML to string and replace the path of css in HTML file with your local path. :
Load the content of HTML to UIWebView with base url. (Providing local file path as baseUrl is important)
webView = UIWebView()
let pathToInvoiceHTMLTemplate = Bundle.main.path(forResource: "presc", ofType: "html")
let pathToHTMLCSS = Bundle.main.path(forResource: "myDefault", ofType: "css")
do {
var strHTMLContent = try String(contentsOfFile: pathToInvoiceHTMLTemplate!)
strHTMLContent = strHTMLContent.replacingOccurrences(of: "./assets/stylesheets/myDefault.css", with: pathToHTMLCSS!)
let pdfURL = URL(fileURLWithPath: pathToInvoiceHTMLTemplate!)
webView.loadHTMLString(strHTMLContent, baseURL: pdfURL)
}catch let err{
print(err)
}
When loading local content into the WKWebView, you shoudl use loadHTMLString(_:baseURL:) instead of loadRequest. The first function allows you to provide a base URL, which you will also let point into the bundle - so you clearly need to add all the relevant files to your application bundle.
guard let indexPath = Bundle.main.path(forResource: "index", ofType: "html"),
let content = try String(contentsOfFile: indexPath, encoding: .utf8),
let baseUrl = URL(fileURLWithPath: indexPath) else {
// Error handling
}
webView.loadHTMLString(content, baseURL: baseUrl)
In my project there are plenty of html files which through anchor links are connected to each other.
All of the html files are shown after selected in a UITableView, by an UIWebView. Once loaded the anchor links work and user can go to the chosen html.
Now the problem arises when want to go back, since whatever i do the back button in the navigation bar takes us to the tableView not the previous html.
How can i add a back button and how do i know that at any given time which html is being seen through UIWebView ?
import UIKit
class DisplayViewController: UIViewController, UIWebViewDelegate {
var articleName = “”
#IBOutlet var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
functionOfWebView()
}
func functionOfWebView()
{
let URL = Bundle.main.url(forResource: "\(articleName)", withExtension: "html")
let request = NSURLRequest(url: URL! as URL)
webView.loadRequest(request as URLRequest)
}
You can easily achieve this by linking the webView's "goBack" action to a UIButton.
I assume that you are navigating between the html files in the same webView.
From the storyboard, select the webView and then select "Connections Inspector":
Note that there is "goBack" option in the list of "Received Actions"; Drag from its circle to a button:
Now, instead of popping the current ViewController, the button should do the desired functionality to your case (back to the previous webpage in the webview).
In my case i did a VC's property isInitialWebPageLoaded which reflects whether or not webView is loaded from HTML string or not - which implicates that user did tap link or something else happened.
To get know when it happened VC need to conform to UIWebViewDelegate protocol and implement func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool like that:
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
isInitialWebPageLoaded = navigationType != .linkClicked
return true
}
After that with every back button action is being invoked i simply check:
if webView.canGoBack {
webView.goBack()
} else if isInitialWebPageLoaded == false {
webView.loadHTMLString(yourHTMLString, baseURL: nil)
} else {
navigationController?.popViewController(animated: true)
}
Hope it helped.
You must to add an unique ID in the HTML and later when go back with "goBack" action parse the html finding the ID .
I have an html file and other files that html uses(css,.png) that is saved in the documents directory.How can I load this html file in a UIWebView or wkwebview
using swift?I have found some examples in objective-c but nothing in swift.I don't know anything about objective-c..
let path=getCurrenttHtmlStartPage()
var hContent = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
webView!.loadHTMLString(hContent, baseURL: nil)
webView!.hidden=false
Path is the path in documents folder. /Users/pmdevios/Library/.../Documents/Content/Html/index.html.
With this way the other files inside html aren't showing(images) so I want to do it with another way like this
webView!.loadFileURL(path, allowingReadAccessToURL: path)
With the below code it worked!
let filePath = (folder as NSString).stringByAppendingPathComponent(_currentHtmlStartPage!)
var url:NSURL=NSURL(fileURLWithPath:filePath)
var request:NSURLRequest=NSURLRequest(URL:url)
webView!.loadRequest(request)
folder:string that represents the path in the documents folder
_currentHtmlStartPage:string of file's name (e.g. index.html)
EDIT
Get URL using NSFileManger instance method URLsForDirectory(inDomains:)
Append the file name (myFile.html) to the URL we get back from NSFileManager
Initialize a NSURLRequest object with the URL.
Use the UIWebView or WKWebView class to load the request.
let fileManager = NSFileManager.defaultManager()
var URL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
URL = URL.URLByAppendingPathComponent("myFile.html")
let request = NSURLRequest(URL: fileURL)
webView.loadRequest(request)
Of the top of my head:
if let fileURL = NSBundle.mainBundle().URLForResource("myFile", withExtension: "html") {
let request = NSURLRequest(URL: fileURL)
webView.loadRequest(request)
}
You'll need a flat directory structure in your html and css files because that's how they end up in the app.
I am using Swift and have web-based content (an external webpage) embedded in WebView for my native app. On that webpage, again, which is in-app, I need to make one link open in Safari and not in the App. HTML target _blank code on the webpage doesn’t work (I wish it was that easy), looking for the right code to do it in Swift.
I have used this code for uiwebview:
#IBOutlet var news: UIWebView!
var theURL = "http://"
override func viewDidLoad() {
super.viewDidLoad()
loadWebPage()
}
func loadWebPage(){
let requestURL = NSURL (string: theURL)
let URLrequest = NSURLRequest (URL: requestURL!)
news.loadRequest(URLrequest)
I have used this code for WKNaviagtionDelegate:
func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: ((WKNavigationActionPolicy) -> Void)) {
if (navigationAction.navigationType == WKNavigationType.LinkActivated && !navigationAction.request.URL!.host!.lowercaseString.hasPrefix("http://")) {
UIApplication.sharedApplication().openURL(navigationAction.request.URL!)
decisionHandler(WKNavigationActionPolicy.Cancel)
} else {
decisionHandler(WKNavigationActionPolicy.Allow)
}
Best, Drew
Because you need to create a button that looks like a link.
that should do the trick:
UIApplication.sharedApplication().openURL(NSURL(string: "http://...")!)
If the button is actually on a webpage in WebView... the link is not really controlled by the App unless you manipulate the link in iOS. It looks like the HTML target="_new" tag on the button might work in a later version of iOS. It's a bug in iOS 7 and was fixed in 7.0.3. Try a higher iOS version target for the App with the HTML target tag on the button.
How to open Safari from a WebApp in iOS 7