How can i know web view is loading completed - iphone

i have web view in that i am loading pdf file .
pdf file has 2 mb size so it tacking time. i want to add indicator .
for that how can i know my file is loaded in web view ? ...

UIWebViewDelegate
in particular:
- (void)webViewDidFinishLoad:(UIWebView *)webView

James P has the right answer (^'ed), but here is the code to show and hide the indicator.
After you've registered with the UIWebViewDelegate...
- (void)webViewDidStartLoad:(UIWebView *)webView {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// Other stuff...
}
And then
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// Other stuff...
}
Also you probably want to check for failures and hide the activity indicator there as well...
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// Other stuff...
}

first Add the delegate "UIWebViewDelegate", then you can use the below methods.
– webView:shouldStartLoadWithRequest:navigationType:
– webViewDidStartLoad:
– webViewDidFinishLoad:
– webView:didFailLoadWithError:

You could pull your PDF down using ASIHTTPRequest, which would let you set up a progress bar showing real progress, and then feed it to your UIWebView once it's downloaded.
EDIT: ASIHTTPRequest is a free third-party library that provides a MUCH improved interface to iOS HTTP client functions. LOTS of code samples and instructions here: http://allseeing-i.com/ASIHTTPRequest/How-to-use

Related

prevent to refresh a web page

I have a problem : I have a simple application with a menu and a link that goes to the web page. The web page is: "soundcloud" it is a site that generates music. for example, if I put on a play music and I return to the menu of my application, the music is still running when I return to the web page, the music is still here but the page is returned to zero. and I want to prevent this. sorry for my english I'm french –
Cordialy
Davy
EDIT: This is assuming that the page is contained in a UIWebView within your app. If it's a link that opens in Safari, I don't believe you are going to be able to block navigation in Safari...but in your own web view you can.
Set the controlling class (whichever view controller contains your web view) as a UIWebView delegate. Then, when you implement the delegate protocol:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{ //If you want to block ANY navigation
return NO;
//If you want to block refreshes but allow other navigation
if (navigationType == UIWebViewNavigationTypeReload) return NO;
{
Inspired by #Reid Belton's answer
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//to prevent reloading html if it is already loaded
if( isHTMLLoaded)
{
return NO;
}else{
isHTMLLoaded = YES;
return YES;
}
}

how to hide progressview when webview load

hi I want to ask a simple question how I can hide or disable progress bar when UIWebView load, I add ProgressBar as subview of webview . I did it by using this way in the method below, but it can't help me because every site take different time to load because of their content size so kindly tell me how I can hide or remove the ProgressBar when any site load in webview
- (void)makeMyProgressBarMoving {
float actual = [threadProgressView progress];
if (actual < 1) {
threadProgressView.progress = actual + 0.2;
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(makeMyProgressBarMoving) userInfo:nil repeats:NO];
}
else
{
threadProgressView.hidden = YES;
threadValueLabel.hidden = YES;
}
}
First add delegate to UIWebView
For adding progress bar :-
Web view delegate method :-
- (void)webViewDidStartLoad:(UIWebView *)webView
{
threadProgressView.hidden = NO;
}
For Removing progress bar :-
Web view delegate method :-
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
threadProgressView.hidden = YES;
}
Hope this helps you
Check your webview is loaded completly or not.
if(!yourWebView.loading)
{
[yourProgress removeFromSuperView];
}
loading
A Boolean value indicating whether the receiver is done loading
content. (read-only) #property(nonatomic, readonly, getter=isLoading) BOOL loading >
Discussion
If YES, the receiver is still loading content; otherwise, NO.
Availability
Available in iOS 2.0 and later.
or
You can implement the webViewDidFinishLoad delegate method of UIWebView.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[yourProgress removeFromSuperView];
}
webViewDidFinishLoad:
Sent after a web view finishes loading a frame.
- (void)webViewDidFinishLoad:(UIWebView *)webView
Parameters
webView
The web view has finished loading.
Availability
Available in iOS 2.0 and later.
Refer UIWebViewDelegate,UIWebView for more details

UIWebView, determine if page has loaded

I would like to know when my WebView has finished loading a page. Im quite new to this and I wonder if you have any suggestions. I need to create a "Loading screen" while the page is loading. This is my basic code:
- (void)viewDidLoad {
NSString *urlAddress = #"http://google.se";
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlAddress];
//URL Requst Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[webView loadRequest:requestObj];
}
Thanks!
There are two different callbacks when the view finishes loading, successful load and failed load. They are both part of the the UIWebViewDelegate protocol.
Implement it and set yourself as the delegate for your web view. Then implement
- (void)webViewDidFinishLoad:(UIWebView *)webView
to know when the loading has finished, so that you can remove your loading screen, and implement
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
to know if it failed so that you can show and appropriate message to the user instead of an infinite loading screen.
Have a look at the UIWebViewDelegate Protocoll. If you set your delegate, you receive messages like – webViewDidFinishLoad:
that's what you want, isn't it?
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:str]];
}

iPhone UIWebView - Open new UIWebView Controller from a hyperlink

I have an embedded website that has many links but the webview window is fairly small to allow for a larger image above the list to be zoomed in and out. I need the webview to respond to hyperlinks into a new controller view with a second embedded UIWebView if at all possible.
The UIWebView has a delegate wich allows you to respond to certain events, e.g. a request to load new content. Just implement the following in your delegate-class
-(bool) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//You might need to set up a interceptLinks-Bool since you don't want to intercept the initial loading of the content
if (self.interceptLinks) {
NSURL *url = request.URL;
//This launches your custom ViewController, replace it with your initialization-code
[YourBrowserViewController openBrowserWithUrl:url];
return NO;
}
//No need to intercept the initial request to fill the WebView
else {
self.interceptLinks = YES;
return YES;
}
}

UIWebView - How to identify the "last" webViewDidFinishLoad message?

The webViewDidFinishLoad message seems to be sent each time any object in the page has been loaded. Is there a way to determine that all loading of content is done?
I'm guessing that iframes cause the webViewDidStartLoad / webViewDidFinishLoad pair.
The [webView isLoading] check mentioned as an answer didn't work for me; it returned false even after the first of two webViewDidFinishLoad calls. Instead, I keep track of the loading as follows:
- (void)webViewDidStartLoad:(UIWebView *)webView {
webViewLoads_++;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
webViewLoads_--;
if (webViewLoads_ > 0) {
return;
}
…
}
- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error {
webViewLoads_--;
}
(Note this will only work if the start / finished pairs don't come serially, but in my experience so far that hasn't happened.)
Check this one, it will definitely work for you:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if ([[webView stringByEvaluatingJavaScriptFromString:#"document.readyState"] isEqualToString:#"complete"]) {
// UIWebView object has fully loaded.
}
}
Interesting, I wouldn't have thought it would work like that. Although I'm sure there are other ways to do it (is there a way to extract the URL from the webViewDidFinishLoad message so that you can see which one is the main page finishing loading?), the main thing I can think of is using the estimatedProgress to check the progress of the page and fire off whatever you want to do when it's 100% finished loading, which is what I do in my app. Google "iphone webview estimatedprogress" and click the first link for a guide I wrote on how to do this.
Update:
Please use phopkins' answer below instead of mine! Using private APIs in your apps is a bad idea and you will probably get rejected, and his solution is the right one.
Another way to monitor load progress with less control is to observe the WebViewProgressEstimateChangedNotification, WebViewProgressFinishedNotification, and WebViewProgressStartedNotification notifications. For example, you could observe these notifications to implement a simple progress indicator in your application. You update the progress indicator by invoking the estimatedProgress method to get an estimate of the amount of content that is currently loaded.
from http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html
You can also use this short Category I wrote that adds blocks into UIWebView and also lets you choose between default UIWebView behavior (getting notified after each object load), or the "expected" behavior (getting notified only when the page has fully loaded).
https://github.com/freak4pc/UIWebView-Blocks
I needed to capture a variable from the page which was not fully loaded yet.
This worked for me:
- (void) webViewDidFinishLoad:(UIWebView *)webView {
NSString *valueID = [webView stringByEvaluatingJavaScriptFromString:#"document.valueID;"];
if([valueID isEqualToString:#""]){
[webView reload];
return;
}
//page loaded
}
All of the options did not really work for my use case. I used phopkins example slightly modified. I found that if the HTML loaded into the webview contained an image that would be a separate request that happened serially so we have to account for that and I did that with a timer. Not the best solution but it seems to work.:
- (void)webViewActuallyFinished {
_webViewLoads--;
if (_webViewLoads > 0) {
return;
}
//Actually done loading
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
_webViewLoads++;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(webViewActuallyFinished) userInfo:nil repeats:NO];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
_webViewLoads--;
}
hi it may be a bit far back already but i hope this helps.
i just used a notification when it enters the webViewDidFinishLoad method so that i can capture one instance of the method and then i'll detect the notification and do my logic from there.
hope this helps. it does not capture the last called instance of the webViewDidFinishLoad method, but allows you to do something once it has been called and not be repeated calls to that particular method (eg. showing a button) too.
*********EDIT*********
i did a test and managed to test it out. it actually works and the method called from the notification will be called after the full page has been loaded.
alternatively, i think you can do a counter on the delegate method webViewDidStartLoad and also on webViewDidFinishLoad to make sure that they are the same before you run your codes. this though, is an ugly hack as we will never know how many times it will be called unless like me, you are loading a html feed and can add a JavaScript to check how many elements there are on the page that you are loading. i'm just sharing some of the methods i have tried to solve this. hope it helps.
feedback is encouraged. thanks!
Here's what I use to show a spinner while DOM loads, built on top of #Vinod's answer.
Note that between webViewDidStartLoad and webViewDidFinishLoad the readyState is completed from the previous request (if any), that's why the polling should begin after webViewDidFinishLoad.
readyState possible values are loading, interactive or completed (and maybe nil ?)
- (void)webViewDidStartLoad:(UIWebView *)webView {
[self spinnerOn];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self startDOMCompletionPolling];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
[self startDOMCompletionPolling];
}
- (void)startDOMCompletionPolling {
if (self.domCompletionListener) {
[self.domCompletionListener invalidate];
}
self.domCompletionListener = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(checkDOMCompletion) userInfo:nil repeats:YES];
}
- (void)checkDOMCompletion {
NSString *readyState = [self.webView stringByEvaluatingJavaScriptFromString:#"document.readyState"];
if (readyState != nil) {
if (readyState.length > 0) {
if ([readyState isEqualToString:#"loading"]) { //keep polling
return;
}
}
}
//'completed', 'interactive', nil, others -> hide spinner
[self.domCompletionListener invalidate];
[self spinnerOff];
}
The way I do it is this:
- (void)webViewDidFinishLoad:(UIWebView *)webview {
if (webview.loading)
return;
// now really done loading code goes next
[logic]
}