UIWebView.loading returns false - ios

With swift using the following code:
super.viewDidLoad()
let webView = UIWebView(frame: self.view.bounds)
view.addSubview(webView)
let URL = NSURL(string: "http://www.google.com")
webView.loadRequest(NSURLRequest(URL: URL!))
println(webView.loading)
It prints false and the screen is blank. How is this resolved?

This is perfectly normal behaviour. The UIWebView does not actually start loading content until the UI event, in this case viewDidLoad, has finished executing. So checking it immediately returns false because it has not started just yet.
If you want want to track the success or failure of the UIWebView you should implement the UIWebViewDelegate in your view controller. That way you get callbacks when the request has finished loading or if it has failed.

I'm uncertain exactly on the internals of how UIWebView loads its data or what exactly happens when you call loadRequest, but contrary to my expectations, nothing seems to actually happen until the method which called loadRequest has returned.
Consider the following code:
#IBAction func buttonPress(sender: UIButton) {
let webview = UIWebView(frame: self.view.bounds)
view.addSubview(webview)
let url = NSURL(string: "http://www.google.com")
webview.delegate = self
webview.loadRequest(NSURLRequest(URL: url!))
println("buttonPress: webview.loading? \(webview.loading)")
}
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
println("webview asking for permission to start loading")
return true
}
func webViewDidStartLoad(webView: UIWebView) {
println("webview did start loading")
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError) {
println("webview did fail load with error: \(error)")
}
func webViewDidFinishLoad(webView: UIWebView) {
println("webview did finish load!")
}
Here, the println in the buttonPress method always executes before any of the other methods. In fact, seemingly no matter what sort of code we put after the loadRequest call, it all executes before the web view even asks shouldStartLoadingWithRequest:.
webview.loadRequest(NSURLRequest(URL: url!))
for _ in 1...10000 {
println("buttonPress: webview.loading? \(webview.loading)")
}
Ten thousand iterations, and yet nothing starts for the webview until after buttonPress method returns.
Meanwhile, webview.loading will only return true between webViewDidStartLoad and one of the two ways the load can stop (failure/success) (webView(webView:didFailLoadWithError:) or webViewDidFinishLoad()).
IF you implement the UIWebViewDelegate protocol and set the web view's delegate, you can implement these methods to keep track of the loading process. If, for whatever reason, your web view isn't loading the URL, implementing webView(webView:didFailLoadWithError:) is the only way to get any sort of diagnostic informatin to determine what failed with the load.

Related

Sending message to WKWebView throws error

I am using WKWebView to load HTML in the popup of my Safari App Extension. I am trying to send a message to this page using webView.evaluateJavaScript("myFunction()") but it fails with error message EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0).
I thought the page isn't loaded in the webView at first and hence throws this error but that is not the case here. The page loads completely but I get this error for some reason. Here is my code.
#IBOutlet var webView: WKWebView!
func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("myFunction()", completionHandler: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
webView.configuration.userContentController.add(self, name: "popup")
webView.configuration.userContentController.add(self, name: "print")
webView.navigationDelegate = self
view.addSubview(webView!)
self.view = webView
if let url = Bundle.main.url(forResource: "MyPopup", withExtension: "html") {
webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
}
}
I tried checking error inside the completionHandler but it doesn't go there. Any Ideas?
I believe you need to use main thread to execute JS in the webView. Try wrapping the call to webView.evaluateJavaScript() in DispatchQueue.main.async { }.

Is it possible to check whether WKWebView has a specific text on it in Swift?

I am working on a project which is to show a website in a web view, the website is designed keeping iPhone in context and has only one URL where all the checks are done on server. I had a screen which has some text, for e.g. "Age". For this particular page, I want to add a tab bar button for sharing the application.
You should use evaluateJavaScript with the code in this answer, which returns all the text from the current page. After that, you can use contains to get whether the particular page contains the text you're looking for.
Don't forget to import WebKit and conform your class to WKNavigationDelegate.
func loadWebView() {
let webView = WKWebView()
webView.navigationDelegate = self
view.addSubview(webView)
let urlRequest = URLRequest(url: URL(string: "http://example.com")!)
webView.load(urlRequest)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.body.innerText") { result, error in
if let resultString = result as? String,
resultString.contains("Age") {
//site contains the text "Age"
}
}
}
}

UIWebView offline error in Swift

I am loading a webpage into my app using UIWebView and following code:
let url = NSURL (string: "http://www.myurl.com");
let requestObj = NSURLRequest(URL: url!);
myWebView.loadRequest(requestObj);
I would like to hide webView if request failed for any reason, for example because of no access to internet. Is there a way to do it?
Use the provided delegate methods of UIWebView
func webViewDidFinishLoad(webView: UIWebView) {
print("webview did finish load!")
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError) {
print("webview did fail load with error: \(error)")
}
Note: To use this method you need implement UIWebViewDelegate in your ViewController and set it with the webView outlet.
myWebView.delegate = self

UIWebview Does NOT complete Load page with "page NOT found" error when URL does not exist

In my iphone app I've got to load a mobile website to a webview (that contain in a separate viewcontroller). All good and working fine.
I need to exit from webview when reach to specific set of URL's. The problem is some of these url's does not exis and therefore page does not finish load (Even with page not found error message to detect current url. Just hangs)
Would like to know if I have to enable any setting in the webView to allow load pages that does not really exist (With page not found error).
OR
Is this possible to know which URL going to load next in
func webViewDidStartLoad(webView: UIWebView)
override func viewDidLoad()
{
super.viewDidLoad()
myWebview.delegate = self
var returnUrlAppendedPaymmentLink = "www.existing_url.com"
let requestURL = NSURL(string: returnUrlAppendedPaymmentLink)
let request = NSURLRequest(URL: requestURL!)
myWebview.loadRequest(request)
}
func webViewDidFinishLoad(webView: UIWebView)
{
var currentUrl = webView.request?.URL?.absoluteString ?? ""
if (currentUrl == "www.special_url.com")
{
self.navigationController?.popViewControllerAnimated(true)
}
}
To intercept specific URLs, use the shouldStartLoadWithRequest delegate method of UIWebView.
You can check the URL of the request in this method to see if this is your "special" URL, do your handling for this case and return false so the web-view won't load it.

How to show image while page is loading in swift?

I'm beginner in swift and Xcode and want to know how to make an image appears while page finish loading in UIWebView,like when you enter a new website,image start appear on screen in webview
You can use any loader meanwhile the website loads, like MBProgressHUD or any other progress bar.
And if you are willing to show an custom image over a screen while loading then you can handle that in following delegate methods:
say you have take any custom image or View called loadingView
func webView(webView: UIWebView!, didFailLoadWithError error: NSError!) {
**loadingView**.viewWithTag(1)?.hidden = true
print("Webview fail with error \(error)");
}
**func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {**
return true;
}
func webViewDidStartLoad(webView: UIWebView!) {
**loadingView**.viewWithTag(1)?.hidden = false
print("Webview started Loading")
}
func webViewDidFinishLoad(webView: UIWebView!) {
**loadingView**.viewWithTag(1)?.hidden = true
print("Webview did finish load")
}
Hope this will help you.

Resources