7

I have been using webView delegate successfully from long time. But recently I faced strange issue with this delegate. In my current project I am trying to access my router from webview. I am passing username and password inside URL only. Below is load request code.

[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://uname:password@192.168.1.1"]]];

This calls webView delegate method (webViewDidFinishLoad and webViewDidStartLoad) 5 times. Is it expected? When I pass simple URL like google.com it works as expected. But with username and password why these delegate methods are called 5 times?

If this behaviour is correct then I need to know why it calls 5 times only. The reason is, in my program - I am calling performSegueWithIdentifier in webViewDidFinishLoad method and in present form it calls segue 5 times. For workaround I can maintain count and will call performSegueWithIdentifier on 5th count only.

Thanks

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Ashish
  • 169
  • 2
  • 10

3 Answers3

15

webViewDidStartLoad/webViewDidFinishLoad are called once per HTML frame. Your content likely has multiple frames in it.

See UIWebViewDelegate docs.

webViewDidStartLoad: Sent after a web view starts loading a frame.

TomSwift
  • 39,369
  • 12
  • 121
  • 149
  • Thanks TomSwift. My web page has 4 frames. Here is more info about html frames - http://www.w3.org/TR/html401/present/frames.html – Ashish Jun 13 '13 at 16:04
6

This Methods works for me... :)

#pragma mark UI Web View Delegate
NSInteger webViewLoads;
//a web view starts loading
- (void)webViewDidStartLoad:(UIWebView *)webView{
    webViewLoads++;
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    [SVProgressHUD showWithStatus:@"Loading..." maskType:SVProgressHUDMaskTypeBlack];
}

//web view finishes loading
- (void)webViewDidFinishLoad:(UIWebView *)webView{
    webViewLoads--;
    [self performSelector:@selector(webViewFinishLoadWithCondition) withObject:nil afterDelay:0.5];
}

//web view handling error
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    webViewLoads--;
        NSLog(@"Web View Did Fail Load With Error : %@",error);
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        [SVProgressHUD dismiss];
}

-(void)webViewFinishLoadWithCondition{
    if(webViewLoads==0){
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        [SVProgressHUD dismiss];
    }
}
Community
  • 1
  • 1
marvin
  • 69
  • 1
  • 1
0

As webViewDidStartLoad/webViewDidFinishLoad are called once per HTML frame, Use an integer to find when the last frame load is finished,

In detail :

  • Increment the integer in webViewDidStartLoad
  • Decrement the integer in webViewDidFinishLoad
  • In webViewDidFinishLoad check when integer is zero, Which means all the frames of web page are loaded, Now call the selector

This is an explanation of @marvin's answer



Best approach:

Check for isLoading in webViewDidFinishLoad and isLoading is false, do what ever u want

-(void)webViewDidFinishLoad:(UIWebView *)webview  
{
   if (!webview.isLoading)
   {
       // webview is done loading content.

       // `performSegueWithIdentifier` / Your code Here

   }
}
Saif
  • 2,678
  • 2
  • 22
  • 38