Is it possible to start an event when an UIWebView (Iphone) has finished loading the URL.
How can I find out, the current URL of the UIWebView?
Yes, that's possible. Use the UIWebViewDelegate protocol and implement the following method in your delegate:
- (void)webViewDidFinishLoad:(UIWebView *)webView
If you want the URL, you can get the last request using the property request:
webView.request.URL
None of the found solutions worked for me.
Then I found this example which at least works much better than any other solution I found on Google/StackOverflow.
uiwebview-load-completion-tracker
Very simple method:
Step 1: Set delegate UIWebViewDelegate in header file.
Step 2: Add following webViewDidFinishLoad method to get current URL of webview
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(#"Current URL = %#",webView.request.URL);
//-- Add further custom actions if needed
}
Pascal's answer for the "getting the URL" part is fine.
However!
From UIWebViewDelegate's documentation, from Apple:
"webViewDidFinishLoad: Sent after a web view finishes loading a frame."
Frame != Page.
webViewDidFinishLoad is called when the page is "done loading". It can also be called many times before then. Page loads from Amazon.com can generate a dozen calls to webViewDidFinishLoad.
If you control the page source, then you can make a load test for it, and it will work, for that case. If you only care about getting called "after the page is done loading", then webViewDidFinishLoad is adequate.
For arbitrary pages, with arbitrary JavaScript, loading ad banners in perpetuity, or autoscrolling banners, or implementing a video game, the very idea of a page being "done loading" is wrongheaded.
Related
I have a UIWebView in my view controller and have set its delegate to the view controller via code (i.e. not through IB). I have also setup the appropriate delegate methods: shouldStartLoadWithRequest, webViewDidStartLoad, webViewDidFinishLoad and didFailLoadWithError.
In my view controller's viewDidLoad method I load an appropriate URL with this code:
[self.webView loadRequest:reqURL];
95% of the time everything works great and the page loads in the UIWebView object and displays as expected. Occasionally, however, the page doesn't load.
After stepping through my code I realized that on the times that it doesn't work the shouldStartLoadWithRequest delegate method fires, but webViewDidStartLoad doesn't.
Does anyone have any idea what's going on here? I couldn't find anything on Stack Overflow that specifically addressed this unique issue I'm having and am slowly reaching my breaking point. Thanks in advance!
You should make sure that your shouldStartLoadWithRequest implementation returns YES for all conditions at which you need your webView to load.
Yes, I know UIWebView has didFinishedLoad & didStartLoad delegate.
However, the didFinishedLoad does not mean the full completion. It may be called when one of the items that the UIWebView is finished loading. i.e., UIWebView may call this delegate several times while loading a single page.
So anyway can tell me how to check whether the UIWebView is fully loaded?
Thanks
J
I have poor experience with DOM but after some searching I found that the document.readyState is the great option.
From w3schools:
Definition and Usage
The readyState property returns the (loading) status of the current document.
This property returns one of four values:
uninitialized - Has not started loading yet
loading - Is loading
interactive - Has loaded enough and the user can interact with it
complete - Fully loaded
So I'm using this to know when UIWebView has loaded the document:
- (void)readyState:(NSString *)str
{ NSLog(#"str:%#",str);
if ([str isEqualToString:#"complete"]||[str isEqualToString:#"interactive"]) {
NSLog(#"IT HAS BEEN DONE");
[pageLoadingActivityIndicator stopAnimating];
}
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//other code...
[self readyState:[browserWebView stringByEvaluatingJavaScriptFromString:#"document.readyState"]];
}
http://www.codingventures.com/2008/12/using-uiwebview-to-render-svg-files/
on Javascript communicating back with Objective-C code
Maybe use document location hash.
And add in the webview html body:
<body onload="document.location.hash='myapp:myobject:myfunction';">
I know its a little bit hacky but works. And it can be used in ajax based contents, because its up to you when you want to call your ready method. Or it can be used as a complete communication scheme.
What you can do is, display a network indicator on the view which is visible in the status bar. When your page is being loaded the indicator will continue rotating until and unless the page is completly loaded. When the page completely loads, the indicator will stop rotating and will be invisible.
Just have a look at this example : Network indicator
I have basic web browser implemented using a UIWebView. I've noticed that for some pages, none of the UIWebViewDelegate methods are called.
An example page in which this happens is: http://www.youtube.com/user/google. Here are the steps to reproduce the issue (make sure you insert NSLog calls in your controller's UIWebViewDelegate methods):
Load the above youtube URL into the UIWebView
[notice that here, the UIWebViewDelegate methods do get called when the page loads]
Touch the "Uploads" category on the page
Touch any video in that category
[issue: notice that a new page is loaded, but none of the UIWebView delegates are called]
I know that this is not an issue of UIWebView's delegate not being set properly, since the delegate methods do get invoked when loading other links (e.g. if you try clicking on a link that takes you outside of youtube, you'll notice the delegate methods getting called).
My gut feeling initially was that it might be because the page is loaded using AJAX, which may not invoke the delegate method. But then when I checked the iPhone's Safari, it did not exhibit this problem, so it must be something on my side.
I've also noticed that Three20's TTWebController has the exact same issue as I'm having.
But the problem that arises from this issue is that without the delegate methods called, I'm unable to update the UI to enable/disable the back and forward browsing buttons when new requests are loaded.
And idea why this is happening or how can I work around it to update the UI when a new request is made?
This isn't an iOS bug - the page isn't actually reloading. The UIWebView delegates are triggered following new page requests, but that page doesn't do that.
Look very carefully at what happens in desktop Safari when you click the video link on that page as you describe. Make sure you pay attention to the address bar. The address will change, but critically the page will not reload.
This is all handled by JavaScript, not by reloading the page. Simply put, the page never reloads, so there's no reason for the UIWebView delegates to be called.
If you don't believe me, to conclusively prove this try repeating the steps you describe with JavaScript disabled. You'll notice the page behaves completely differently.
this is not good solution but im using NSTimer for updating status of buttons:
- (BOOL)webView:(UIWebView *)_webview shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (!_timer && [request.URL.absoluteString rangeOfString:#"youtube.com"].length != 0) {
_timer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(checkNavigationStatus)
userInfo:nil
repeats:YES];
}
return YES;
}
//....
//....
//....
- (void)checkNavigationStatus
{
// Check if we can go forward or back
backButton.enabled = self.webView.canGoBack;
forwardButton.enabled = self.webView.canGoForward;
}
Looks like this got fixed in iOS 4.2. It works in iOS 4.2.
I am creating a tabbar application. One of the tabs is for an rss feed, which is a navigation application. but when i click the tab bat button, it is taking a while to load the view of that tab. It is because the application is waiting for the feed to be loaded from the server. Is there any way to load the view before the loading of that feed takes place. As of now, i'm giving the request in the viewDidLoad method. Thats what is creating the problem. To which part shall i move the code so that the view is loaded instantaneously when clicking the tabbar button.
I recommend this great article on this subject on iCodeBlog, it's a very elegant way of doing this. If you submit your rss feed loading as an NSOperation, it will take place nicely in the background without blocking your main thread.
use:
[self performSelector:#selector(performRSS:) withObject:<nil afterDelay:0.3f];
or
[NSThread detachNewThreadSelector:#selector(performRSS:) toTarget:self withObject:nil];
and place RSS feed related code in a separate function named "performRSS".
I also think that the problem is more that you don't use the HTTP request asyncronously (as Apple recommends). See this document. http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
It worked for me in my applications.
hai good afternoon to everyone, I am developing an iPhone web application. In my application I have loaded two web pages in a single UIWebView. After this process has completed, one web page should hide or overlap others whenever they get the user-interaction. However, I don't need this yet. User-interaction also should remain so-far.
You can't have two different webpages in one UIWebView. Instead, you should try to create two UIWebView objects and add them as a subview in a container view.
You can set these UIWebView objects' frame, userInteractionEnabled, hidden properties according to your needs.
Also, you should look at delegate methods of UIWebView. Those delegate methods are called when a page is finished loading or when there is an error exc.
You can read the documentation to learn more about delegate methods:
UIWebViewDelegate documentation