I've been working on a simple app that makes a webview of a website where students can take exams.
So basically the problem I have is that when students are done, they have to click on a button that will send the answers. A popup will appear to make them confirm. .png Except that it doesn't show up. Nothing happens when the button is pushed. It works flawlessly on Safari and I've noticed that it works on the deprecated webview (UIWebview) but I've been trying to make it work on WKWebView.
I'm definitely no swift expert so I apologize if the answer is easy. I've been trying to find some answers about my problem but I'm not sure how to implement it.
Thank you in advance for any help,
import UIKit
import WebKit
class webViewController: UIViewController {
@IBOutlet weak var webview: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let lien = "***"
if let url = URL(string: lien) {
let request = URLRequest(url: url)
_ = webview.load(request);
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I've been working on a simple app that makes a webview of a website where students can take exams.
So basically the problem I have is that when students are done, they have to click on a button that will send the answers. A popup will appear to make them confirm. https://i.sstatic.net/5GhB8.png Except that it doesn't show up. Nothing happens when the button is pushed. It works flawlessly on Safari and I've noticed that it works on the deprecated webview (UIWebview) but I've been trying to make it work on WKWebView.
I'm definitely no swift expert so I apologize if the answer is easy. I've been trying to find some answers about my problem but I'm not sure how to implement it.
Thank you in advance for any help,
import UIKit
import WebKit
class webViewController: UIViewController {
@IBOutlet weak var webview: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let lien = "***"
if let url = URL(string: lien) {
let request = URLRequest(url: url)
_ = webview.load(request);
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Share
Improve this question
edited Jul 9, 2018 at 7:27
Notsu
asked Jul 4, 2018 at 9:48
NotsuNotsu
1031 gold badge1 silver badge5 bronze badges
5
- can you add the code please? without code its hard to fix – Karthick Ramesh Commented Jul 4, 2018 at 10:21
- I've added the code – Notsu Commented Jul 4, 2018 at 12:30
- Did you use Constraints when you'd been adding the WKWebView? – Bogdan Novikov Commented Jul 4, 2018 at 12:43
- I think you need to have a look at stackoverflow.com/questions/26898941/… – Karthick Ramesh Commented Jul 4, 2018 at 12:52
- I did use Constraints in every position. I've read that topic, do I just need to implement those 3 functions? – Notsu Commented Jul 4, 2018 at 13:01
4 Answers
Reset to default 5I also faced similar issue, mine was popup for connecting facebook won't show in WKWebView but works fine on safari browser.
This code was causing the issue.
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
//This condition was causing the problem while trying to get popup
if (!navigationAction.targetFrame.isMainFrame) {
[webView loadRequest:navigationAction.request];
}
return nil;
}
I changed it to following code and it worked
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
if (navigationAction.targetFrame == nil) {
NSURL *tempURL = navigationAction.request.URL;
NSURLComponents *URLComponents = [[NSURLComponents alloc] init];
URLComponents.scheme = [tempURL scheme];
URLComponents.host = [tempURL host];
URLComponents.path = [tempURL path];
if ([URLComponents.URL.absoluteString isEqualToString:@"https://example.com/Account/ExternalLogin"]) {
WKWebView *webViewtemp = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
webViewtemp.UIDelegate = self;
webViewtemp.navigationDelegate = self;
[self.view addSubview:webViewtemp];
return webViewtemp;
} else {
[webView loadRequest:navigationAction.request];
}
}
return nil;
}
Swift version:
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
let tempURL = navigationAction.request.url
var components = URLComponents()
components.scheme = tempURL?.scheme
components.host = tempURL?.host
components.path = (tempURL?.path)!
if components.url?.absoluteString == "https://example.com/Account/ExternalLogin" {
let webViewtemp = WKWebView(frame: self.view.bounds, configuration: configuration)
webViewtemp.uiDelegate = self
webViewtemp.navigationDelegate = self
self.view.addSubview(webViewtemp)
return webViewtemp
} else {
webView.load(navigationAction.request)
}
}
return nil
}
Hope this helps you
My solution was implementing the WKUIDelegate
and adding the functions for the different scenarios (alerts) that the web view may present:
extension WKWebViewController: WKUIDelegate {
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK button"), style: .default, handler: { (action) in
completionHandler()
}))
present(alertController, animated: true, completion: nil)
}
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK button"), style: .default, handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: "Cancel button"), style: .default, handler: { (action) in
completionHandler(false)
}))
present(alertController, animated: true, completion: nil)
}
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .actionSheet)
alertController.addTextField { (textField) in
textField.text = defaultText
}
alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK button"), style: .default, handler: { (action) in
if let text = alertController.textFields?.first?.text {
completionHandler(text)
} else {
completionHandler(defaultText)
}
}))
alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: "Cancel button"), style: .default, handler: { (action) in
completionHandler(nil)
}))
present(alertController, animated: true, completion: nil)
}
}
I tried the other way round and it worked for me. Here is the code: Create a instance of WebView
fileprivate var webView: WKWebView?
Initialize instance and make assign it to view.
override func loadView() {
webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
webView?.uiDelegate = self
webView?.navigationDelegate = self
view = webView
}
Thereafter, just add the following delegate method:
func webView(_: WKWebView, createWebViewWith _: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures _: WKWindowFeatures) -> WKWebView? {
self.webView?.load(navigationAction.request)
return nil
}
Voila! Everything will work same as UIWebView
.
Note: You won't be able to tap few links on the WebSite, because they would be HTTP instead of HTTPS. WKWebView by default blocks all HTTP requests which aren't secure.
To bypass, just add NSExceptionAllowsInsecureHTTPLoads
as true
in info.plist
file.
When web view demands the new popup window than UIDelegate of WKWebView will come in picture.
Follow these steps to show POP-Up view in WKWebView
Take a another web-view
private var popupWebView: WKWebView?
Assign the uiDelegate of your main web-view to self
webView?.uiDelegate = self
Confirm the WKUIDelegate of to your controller
extension PaisaPalVC: WKUIDelegate { func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { popupWebView = WKWebView(frame: view.bounds, configuration: configuration) popupWebView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] popupWebView?.navigationDelegate = self popupWebView?.uiDelegate = self if let newWebview = popupWebView { view.addSubview(newWebview) } return popupWebView ?? nil } func webViewDidClose(_ webView: WKWebView) { webView.removeFromSuperview() popupWebView = nil } }
Hope this helps you