美文网首页iOS 常用第三方库
UIWebView 如何获取网页加载进度

UIWebView 如何获取网页加载进度

作者: dadage456 | 来源:发表于2016-04-22 15:29 被阅读2073次

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

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

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

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

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

初始化进度值的条件:

  • 判断该请求是主请求
  • 判断该请求是http、https、file协议
  • 判断该请求不是跳转位置请求
  //判断该请求是否为跳转位置链接
  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];
}

三、加载完成,结束进度

如何确定加载完成

  • webViewDidFinishLoad:webView:didFailLoadWithError:委托方法中,获取“document.readyState”为“complete”
  • webView:didFailLoadWithError:委托方法中,error不为空
  • 获取“document.readyState”为“interactive”的情况下,用js创建一个隐藏的iframe包含自定义的url。在webView:shouldStartLoadWithRequest:navigationType:委托方法中,识别该自定义的请求url,结束进度加载。
    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];
    }

相关文章

网友评论

  • 横爬介士:请问有源码么?有些地方看的不是特别懂
    dadage456:@横爬介士 NJKWebViewProgress 到 github.com上就会搜到源码。。。

    你能说一下那些地方不是特别懂。。。

本文标题:UIWebView 如何获取网页加载进度

本文链接:https://www.haomeiwen.com/subject/rprxrttx.html