UIWebView 如何获取网页加载进度

当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];
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 3,982评论 2 7
  • IOS之UIWebView的使用 刚接触IOS开发1年多,现在对于 混合式 移动端开发越来越流行,因为开发成本上、...
    学无止境666阅读 45,979评论 5 53
  • OS之UIWebView的使用 刚接触IOS开发1年多,现在对于 混合式 移动端开发越来越流行,因为开发成本上、速...
    知之未道阅读 1,707评论 0 4
  • http://www.cnblogs.com/mddblog/p/5281748.html 一、整体介绍 UIWe...
    F麦子阅读 1,321评论 0 2
  • 亲子日记第六十一天,蕙钰早上起的有点晚,晚上说好早上起来让我给她编辫子,所以时间有点长,去托付就8点了,也...
    AA稳稳阅读 180评论 0 0

友情链接更多精彩内容