Restricting the domain/url of a WKWebView - ios

I'm trying to include an online form in my application using a UIWebView, and I noticed that once the user finishes the form, s/he can navigate to different addresses. Is there any way I can restrict the domain/url access of a webkit?
(This used to be possible using UIWebView example: https://stackoverflow.com/questions/7673116/restrict-uiwebview-to-certain-pages‌ but it's now deprecated)

WKWebView can utilize the WKNavigationDelegate to restrict navigation.
func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.URL {
if url == permittedUrl {
decisionHandler(.allow)
} else {
decisionHandler(.cancel)
}
}
}

Related

how do I perform tasks before loading a webview url in ios?

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)
}

Prevent WKWebView From Being Able To Navigate To Specific Pages On A Website (Swift 5)

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

swift force viewController change from within webkit function

I have a viewController showing a webkit view.
If the user browses to a certain type of link, then I want to move from that viewController to a new one, which can parse that specific type of url and display results (rather than moving to a new page)
However, as I understand it, in order to check the url links to see it's of the right kind then I need to use the function
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
but this only gives me the ability to write a bit of code to look at the URL link, and return a decision on whether to proceed to it or not, rather than what I want to do which is look at the URL link and then effectively segue to a completely new viewController to parse it.
Any ideas on how I should construct please?
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Swift.Void)
{
if(navigationAction.navigationType == .other)
{
if navigationAction.request.url != nil
{
// Put your condition check on url.
// Create your view controller instance from storyboard. Pass the url to it and navigate.
}
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}

WKWebView not loading content from iframe on a webpage

I have a WKWebView where a user goes through several pages to reach a page which contains a video from lesson.ly.
The problem is that the video will not show up at all within the webview, there is just a blank gap in the page where the video would be. However, if I open chrome on iOS, it loads just fine.
I've pinpointed the issue by debugging the HTML code. Here is a screen shot of the HTML on the webview:
And Here's a picture of the HTML on Chrome for Mac:
If you noticed, there is nothing within the iframe for the webview. I have no idea why it's not loading the data. I have enabled 'Allows Arbitrary Loads' for App Transport Security to no avail.
Any help appreciated, thanks.
Alternatively, instead of allowing specific URLs, you can check if request in question is targeting main frame or not:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Swift.Void) {
// Allow navigation for requests loading external web content resources.
guard navigationAction.targetFrame?.isMainFrame != false else {
decisionHandler(.allow)
return
}
...
}
Figured out the problem. It was all in the delegate method webView:decidePolicyForNavigationAction:decisionHandler: and because the Lessonly videos come from a different source (fast.wistia.net) I had to add that url expliclity.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
guard let requestURL = navigationAction.request.url?.absoluteString else { return }
if requestURL.tc_contains("mydomain.lesson.ly") || requestURL.tc_contains("fast.wistia.net"){
decisionHandler(.allow)
}
else {
decisionHandler(.cancel)
}
}

Wrapper with WKWebView - Load ALL links within WKWebView

WKWebView allows you to open external links (those different from base url) via Safari.However, sometimes you want to open ALL links within WKWebView itself.For instance, say you have a base url "https://trader.finmarkets.com" but you have a link "https://secure.transactions.finmarkets.com"that you also want to open within the WKWebView without using UIApplication.shared.open(url) which will open externally.
The question is : How do I wrap my website to open all links on the WKWebview?(of-course except email and telephone numbers)Thanks.
You could try something like this:
func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .LinkActivated {
if let newURL = navigationAction.request.URL &&
UIApplication.sharedApplication().canOpenURL(newURL) &&
UIApplication.sharedApplication().openURL(newURL) {
print(newURL)
print("User clicked on link. Open it internally.")
decisionHandler(.Allow)
} else {
print("Cannot open URL")
}
} else {
print("Not a user click")
}
}
You may need to fiddle with this a little to get it to work perfectly, but I think it might be along the lines you're looking for.

Resources