I am using WKWebView for my WebViewController in my app and I spot one problem with one URL
"http://www.viator.com/tours/San-Francisco/San-Francisco-Vista-Grande-Helicopter-Tour/d651-3538VISTAGRANDE?eap=brand-subbrand-75523&aid=vba75523en" there is no navigation through the web site when I tap some other event page nothing happens. Does anyone have any ideas about how to deal with that?
If you're talking about links opening in a new window, indeed, they don't create a new navigation action. But you can still intercept them, and load the request manually.
If your webview does not have a custom uiDelegate already, assign it to your view controller or something else, and then do something like this:
extension SomeViewController: WKUIDelegate {
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
// Intercept target=_blank links
guard
navigationAction.targetFrame == nil,
let url = navigationAction.request.url else {
return nil
}
let request = URLRequest(url: url)
webView.load(request)
return nil
}
}
Related
so I can't seem to figure out a way to perform some tasks before loading a url in ios webview.
Like in android we can use shouldOverrideUrlLoading.
#Override
public boolean shouldOverrideUrlLoading(final WebView view, String url) {
///sometask
}
but I can't find a function that does something like this in ios.
Say a user clicked on a href tag inside the webview that takes it to different page, how do I know what link that tag takes the user to? before changing the page.
Basically I want to check what url the webpage is about to load and perform extra steps according to that url.
You can use WKNavigationDelegate
set navigationDelegate in viewDidLoad
self.webView?.navigationDelegate = self
Observe URL in below navigationDelegate Method.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
DispatchQueue.main.async {
if let urlString = navigationAction.request.url?.absoluteString{
print(urlString)
}
}
decisionHandler(.allow)
}
I am trying to prevent users from being able to navigate to different pages on a website by using WKNavigationDelegate and implementing the function below:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if let urlStr = navigationAction.request.url?.absoluteString {
if urlStr == "https://random.ca/#/profile" {
decisionHandler(.cancel)
return
}
}
decisionHandler(.allow)
}
This function seems to only be called when I first load the home page of the website and when I navigate to other pages inside of this site it is not triggered and so I cannot prevent the user from navigating to those pages.
Any advice would be greatly appreciated.
I found something
Just before calling webView.load()
add this
webView.isUserInteractionEnabled = false
check this Disable links in WKWebView? for more details
I am trying to catch a button click in my web view. Button "action" if I can say so, triggers certain url... I am not really able to catch this moment through WKNavigationDelegate. webview is set like this:
lazy var advertWebKitView: WKWebView = {
let webConfiguration = WKWebViewConfiguration()
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
webConfiguration.preferences = preferences
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.navigationDelegate = self
webView.uiDelegate = self
webView.translatesAutoresizingMaskIntoConstraints = false
return webView
}()
I am trying to catch that button click like this:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
decisionHandler(.allow)
guard let urlAsString = navigationAction.request.url?.absoluteString.lowercased() else {
return
}
if urlAsString.range(of: "...") != nil {
}
}
but this method doesn't trigger when button is clicked.
On android, it works and its done like this:
#Override
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
if (url.equals("...")) {
finish();
}
//...
super.doUpdateVisitedHistory(view, url, isReload);
}
what would be equal method and a way to track navigation correctly through wkwebview?
EDIT:
if there is some info needed about the webpage structure or so, please ask for details and I will add that too. I just didn't know which info may be relevant or helpful.
The button html looks like this:
<a class="lc-button lc-button--light" href="/close">OK</a>
Also one interesting thing is, that I have tried to use my code on other sites and navigation delegate methods were triggered correctly. Which leads me that problem is with our site and its html code or something about how the page is loaded after button is clicked, maybe...
I am using this myself and it works, it is slightly different than what you are trying until now but the right equivalent to the Android method.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if let requestURL = navigationAction.request.url, requestURL.pathComponents.contains("...") {
//Do your things
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
Use RedirectTo instead of LinkTo in react router for redirecting to /close
First set delegate in viewDidLoad,
self.webView.navigationDelegate = self
You can catch where your button is navigating you to by implementing
WKNavigationDelegate function, didFinish navigation
extension YourViewController: WKNavigationDelegate{
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if let currentURL = webView.url{
if self.urlString == currentURL.absoluteString{
print(self.urlString)
}
}
}
}
I developed simple web browser with WKWebView in Swift.
When I click Youtube link, Youtube app is auto launched.
I hope to play Youtube video inside my web browser.
I don't need to launch Youtube app.
Please help me.
Here are my sample code.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let webViewConfiguration = WKWebViewConfiguration()
webViewConfiguration.allowsInlineMediaPlayback = true
wkWebView.configuration.allowsInlineMediaPlayback = true
wkWebView.navigationDelegate = self
let myURL = URL(string: "https://www.google.com")
let youtubeRequest = URLRequest(url: myURL!)
wkWebView.load(youtubeRequest)
}
Yes, you can do this.
First you need to set up a WKNavigationDelegate in your webview, then in webview:decidePolicyFor method cancel any link activated youtube requests, and force it to load within your webview.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated && navigationAction.request.url?.host?.hasSuffix("youtube.com") {
decisionHandler(.cancel)
DispatchQueue.main.async {
webView.load(navigationAction.request)
}
} else {
decisionHandler(.allow)
}
}
Unfortunately you can't do that programatically. Following are the steps to achieve something like you want manually.
Open youtube app from Home screen
Tap on your profile picture on the upper right corner.
Go to Settings and tap on Google app Settings
Check the Safari Option.
There is a social link button inside WKWebView. When I click on the button nothing happens.
Could you please tell me how to open the link by clicking on the button?
Thanks in advance.
what link u want to open change "facebook","twitter" and you can add more links also
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url ,UIApplication.shared.canOpenURL(url) {
// let urlString = try! String(contentsOf: url)
if (url.absoluteString.range(of: "facebook.com") != nil || url.absoluteString.range(of: "twitter.com") != nil){
//UIApplication.shared.open(url)
print("Redirected to browser. No need to open it locally")
decisionHandler(.cancel)
}else{
print("Open it locally")
decisionHandler(.allow)
}
}
You need a on click listener.
You can use WKWebView to display interactive web content in your app. Ideal for displaying HTML markup, styled text content, or complete web pages. After that, you need to handle the Social button you're calling and the data submitted if any...
Responding To WKWebView Events With WKNavigationDelegate
A WKWebView web view has two main delegate protocols and properties:
navigationDelegate of type WKNavigationDelegate, which responds to
navigation events
uiDelegate of type WKUIDelegate, which responds to user
interaction events
Of these two delegate protocols, the WKNavigationDelegate is probably used most frequently. So, let’s hook into some page navigation events! We’ll do so with these delegate functions:
webView(_:didStartProvisionalNavigation:)
webView(_:didCommit:)
webView(_:didFinish:)
webView(_:didFail:withError:)
webView(_:didFailProvisionalNavigation:withError:)
First, let’s adopt the protocol and set the webView delegate. Here’s how:
Add the WKNavigationDelegate protocol to your view controller’s class declaration, like: class WebViewController: UIViewController, WKNavigationDelegate
Set the navigationDelegate property of webView to self, before loading the web request, like: webView?.navigationDelegate = self
Next, implement the five delegate functions described earlier. Set their function bodies to print(#function), so we can see the order in which the functions are called.
Like this:
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
{
print(#function)
}