iOS 常用第三方库

UIWebView 如何获取网页加载进度

2016-04-22  本文已影响2073人  dadage456

当UIWebView加载网页时,可能引起多次请求(有重定向、或包含iframe引起多次请求,并多次执行UIWebView 委托事件)

根据NJKWebViewProgress开源库的分析,获取UIWebView的加载进度主要根据以下几点:

  1. 请求开始时,初始化进度值。
  2. 加载请求过程,计算进度值。
  3. 加载完成,结束进度。

一、请求开始时,初始化进度值

UIWebview加载一个网页时,在webView:shouldStartLoadWithRequest:navigationType委托方法中,初始化进度值。

初始化进度值的条件:

  //判断该请求是否为跳转位置链接
  BOOL isFragmentJump = NO;
    if (request.URL.fragment) {
        NSString *nonFragmentURL = [request.URL.absoluteString stringByReplacingOccurrencesOfString:[@"#" stringByAppendingString:request.URL.fragment] withString:@""];
        isFragmentJump = [nonFragmentURL isEqualToString:webView.request.URL.absoluteString];
    }

    //判断该请求是否为主请求链接
    BOOL isTopLevelNavigation = [request.mainDocumentURL isEqual:request.URL];

    //判断该请求是http、https、file协议
    BOOL isHTTPOrLocalFile = [request.URL.scheme isEqualToString:@"http"] || [request.URL.scheme isEqualToString:@"https"] || [request.URL.scheme isEqualToString:@"file"];

    if (!isFragmentJump && isHTTPOrLocalFile && isTopLevelNavigation) {
       //满足条件,初始化计算进度数据
        _maxLoadCount = _loadingCount = 0;
        [self setProgress:0.0];
    }

二、加载请求过程,计算进度值
  1. 通过webViewDidStartLoad委托方法,计算请求的次数totalCount.

  2. 通过webViewDidFinishLoad:webView:didFailLoadWithError:委托方法,计算完成请求的次数completeCount,并根据“总的请求次数-totalCount”“完成的请求次数-completeCount”计算出进度值。

  3. 进度值的计算方法(重点)

- (void)incrementProgress
{
    float progress = self.progress;
    float maxProgress = NJKInteractiveProgressValue;// 0.9f
    float remainPercent = (float)_loadingCount / (float)_maxLoadCount;
    float increment = (maxProgress - progress) * remainPercent;
    progress += increment;
    progress = fmin(progress, maxProgress);
    [self setProgress:progress];
}

三、加载完成,结束进度

如何确定加载完成

    NSString *readyState = [webView stringByEvaluatingJavaScriptFromString:@"document.readyState"];

    BOOL interactive = [readyState isEqualToString:@"interactive"];
    if (interactive) {
        NSString *waitForCompleteJS = [NSString stringWithFormat:@"window.addEventListener('load',function() { var iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = '%@://%@%@'; document.body.appendChild(iframe);  }, false);", webView.request.mainDocumentURL.scheme, webView.request.mainDocumentURL.host, completeRPCURLPath];
        [webView stringByEvaluatingJavaScriptFromString:waitForCompleteJS];
    }
    
    BOOL complete = [readyState isEqualToString:@"complete"];
    if (complete) {
        [self completeProgress];
    }
上一篇 下一篇

猜你喜欢

热点阅读