精华内容
下载资源
问答
  • 但是测试反应登录后在后台放一段时间,重新打开有一定几率出现白屏。 调试发现打开后,webview显示已经加载完成,只是内容什么都没有。 首先考虑缓存问题,在应用初始化时,清除webview的缓存。 - (void)...

    公司的一个iOS app登录界面是原生开发,登录成功后打开一个webview加载web页面。第二次登录就看是否保存了token,如果有就直接打开webview加载。但是测试反应登录后在后台放一段时间,重新打开有一定几率出现白屏。

    调试发现打开后,webview显示已经加载完成,只是内容什么都没有。

    首先考虑缓存问题,在应用初始化时,清除webview的缓存。

    - (void)cleanWKWebView{
        
        NSArray *types = @[WKWebsiteDataTypeMemoryCache,WKWebsiteDataTypeDiskCache];
        NSSet *websiteDataTypes = [NSSet setWithArray:types];
        NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
        [[WKWebsiteDataStore defaultDataStore]removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
            TYDLog(@"WKWebView清理完成");
        }];
    
    }
    - (void)clearWbCache {
        [[NSURLCache sharedURLCache] removeAllCachedResponses];
        [[NSURLCache sharedURLCache] setDiskCapacity:0];
        [[NSURLCache sharedURLCache] setMemoryCapacity:0];
        
    }

    修改后,发现白屏问题仍旧存在。发现控制台打印

    wkwebview domain = NSURLErrorDomain, code = -999

    原来,当加载一些HTTPS的页面的时候,如果此网站使用的根证书已经内置到了手机中这些HTTPS的链接可以正常的通过验证并正常加载。但是如果使用的证书(一般为自建证书)的根证书并没有内置到手机中,这时是链接是无法正常加载的,必须要做一个权限认证。开始在UIWebView的时候,是把请求存储下来然后使用NSURLConnection去重新发起请求,然后走NSURLConnection的权限认证通道,认证通过后,在使用UIWebView去加载这个请求。在WKWebView中,WKNavigationDelegate中提供了一个权限认证的代理方法,这是权限认证更为便捷。代理方法如下:

    - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
         // 判断服务器采用的验证方法
        if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
             // 如果没有错误的情况下 创建一个凭证,并使用证书
            if (challenge.previousFailureCount == 0) {
                NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
                completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
            }else {
            // 验证失败,取消本次验证
                completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
            }
        }else {
            completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
    
        }
    }

    代理这个方法后,白屏问题就顺利解决了。

    如果是HTTPS 请求,该方法实现获取服务器认证的逻辑,最后返回给服务端。 这个问题常常出现在客户端无法获得安全认证的时候(没有证书,或者是自建证书),比如说https://www.apple.com/cn 是默认的苹果中国的地址,但是 https://www.apple.com.cn 也是可以访问的(会自动跳转到 https://www.apple.com/cn ) ,只是在Safari 的安全认证中通不过,我们需要在代理方法中通过服务端给的验证方式创建一个凭证,然后继续申请访问。比如在Safari 浏览器中第一次访问时就会弹出对话框,点击继续后就可以继续访问。

    展开全文
  • WKWebView加载网页加载不出来问题

    万次阅读 2018-08-01 13:11:34
    网上有很多小伙伴遇到一个问题,WKWebView加载网页加载不出来,白屏等,于是就说WK还不成熟。 不要轻易下结论收WK还不成熟,反正我用着感觉比UIWebView好太多的感脚,白屏只是因为我们没找到白屏的问题而已,而非...

    之前有一个项目一直使用WKWebView,比UIWebView占用性能少很多,而且很流畅。网上有很多小伙伴遇到一个问题,WKWebView加载网页加载不出来,白屏等,于是就说WK还不成熟。

    不要轻易下结论收WK还不成熟,反正我用着感觉比UIWebView好太多的感脚,白屏只是因为我们没找到白屏的问题而已,而非WK的问题。

    一些问题

    代码如下

    _webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com/"]];
    [_webView loadRequest:request];
    [self.view addSubview:_webView];

    如上代码有问题吗?我觉得没一点问题。那么有些小伙伴怎么这样写网页就是加载不出来呢?

    WKWebView加载网络地址“白屏”

    WKWebView加载不出来网页了,UIWebView可以

    还有些人说,我的怎么可以加载啊。

    比如这里:http://www.cocoachina.com/bbs/read.php?tid-1726060-page-2.html

    问题本质

    出现加载不出来本质原因是,如果没在plist文件中设置App Transport Security Settings的话,加载https链接,肯定是加载不出来的,第一次加载不出来,产生了缓存,第二次再去加载也加载不出来了,可以尝试一下就知道了。

    有些小伙伴说我的怎么能加载出来啊,那是因为你设置了App Transport Security Settings,并加载了https链接。或者没设置,第一次加载的是一个http链接地址,就加载出来了。而第一次加载不出来,以后就出不来了,因为WK缓存的问题。

    清除WK的缓存之后再加载就出来了,或者直接把App卸载了,重新run一下就可以了。

    展开全文
  • 无论是做 WebView 性能优化还是异常问题监控与排查,都离不开对WKWebView加载的生命周期与代理方法的剖析。 在 WebKit 源码的调试基础之上, 结合 iOS 端 WKWebView 的 WKNavigationDelegate 代理方法,站在移动端的...

    一、前言

    • 从 WebView 开始加载一条请求,到页面完整呈现这一过程发生了什么?无论是做 WebView 性能优化还是异常问题监控与排查,都离不开对WKWebView加载的生命周期与代理方法的剖析。
    • 在 WebKit 源码的调试基础之上, 结合 iOS 端 WKWebView 的 WKNavigationDelegate 代理方法,站在移动端的视角深入分析 WKWebView 网络请求加载的生命周期流程。
    • WebKit 源码的调试,请参考我之前的博客:iOS之深入解析WKWebView的WebKit源码调试与分析

    二、 WebKit 加载框架

    在这里插入图片描述

    • UIProcess、WebContent、NetworkProces 进程关系分析:
      • NetworkProcess进程:主要负责网络请求加载,所有的网页共享这一进程。与原生网络请求开发一致,NetworkProcess 也是通过封装的 NSURLSession 发起并管理网络请求的。但不同的是,这一过程中有较多的网络进度的回调工作以及各类网络协议管理,比如资源缓存协议、HSTS 协议、cookie 管理协议等。
      • WebContent进程:主要负责页面资源的管理,包含前进后退历史,pageCache,页面资源的解析、渲染。并把该进程中的各类事件通过代理方式通知给 UIProcess。
      • UIProcess进程:主要负责与 WebContent 进行交互,与 APP 在同一进程中,可以进行 WebView 的功能配置,并接收来自 WebContent 进程的各类消息,配合业务代码执行任务的决策,例如是否发起请求,是否接受响应等。

    三、WebKit 加载流程

    • 使用如下方法,从 UIProcess 层通过 loadReqeust 方法发起页面加载请求(此处 request 只能是 get 请求,如果配置为 post 请求,WebKit 内核基于性能考虑,在跨进程传输时,会将 body 数据丢弃,导致异常):
    	[self.webView loadRequest:request];
    
    • 通过跟踪 WebKit 源码,我们提取核心步骤如下:
      • UIProcess 中的 loadRequest 首先会触发 NetworkProcess 进程创建,然后通过进程间通信的方式将 request 发送给 NetworkProcess 进程进行 preconnect 预链接操作,通过网络三次握手建立 TCP 链接,以便加快后续网络资源请求速度。
      • UIProcess 通过进程间通信的方式将 request 发送给 WebContent 进程,WebContent 进程创建 DocumentLoader 加载器加载网络请求,并取消上个页面的所有还在加载的请求,然后通过字典绑定当前页面ID与创建好的 NetworkProcss 进程(便于服务端数据返回时,查找数据回填所对应的页面),最终将请求交付给 NetworkProcess 中的 NSURLSession 进行处理。
      • NetworkProcess 通过 NSURLSession 复用之前 preconnect 预链接,继续进行网络加载,此时等待网络请求返回,网络层会继续将数据通过进程间通信方式传输给 WebContent 进程进行处理,开始流式进行数据解析,一边接收一边处理,进行词法分析、语法分析,并在这一过程中加载解析出来的 js、css、图片、字体等子资源,最终动态的生成(DOM 树与 CSSOM 树合成)渲染树,在这一过程中,每次接受到新数据导致渲染树有变更后,就会触发一次 checkAndDispatchDidReachVisuallyNonEmptyState 方法,检查当前页面是否达到上屏状态,若达到上屏状态就进行上屏渲染。
    • 达到上屏状态的条件如下:
      • 如果返回的 data 是普通文本文字,或返回的数据中包含普通文本文字,那只需要达到非空 200 字节即可以触发上屏渲染;
      • 如果返回的 data 是图片资源类,则判断像素大小 > 32*32,即可触发上屏渲染;
      • 如果不满足以上条件,对于主文档,判断后面是否继续接收数据,如果不继续,则触发上屏渲染;如后续还有数据,则循环上述流程直至触发上屏。渲染完成,整个加载过程结束。
    • WebKit 加载流程如下:

    在这里插入图片描述

    四、WebKit 加载生命周期代理方法

    ① WKNavigationDelegate 方法
    	@protocol WKNavigationDelegate <NSObject>
    	
    	@optional
    	// 请求之前,决定是否要跳转:用户点击网页上的链接,需要打开新页面时,将先调用这个方法。
    	- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler; 
    	
    	// 页面开始加载时调用
    	- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation; 
    	
    	// 接收到响应数据后,决定是否跳转
    	- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler; 
    	
    	// 主机地址被重定向时调用
    	- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation; 
    	
    	// 当开始加载主文档数据失败时调用
    	- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error; 
    	
    	// 当内容开始返回时调用
    	- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation; 
    	
    	// 页面加载完毕时调用
    	- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation; 
    	
    	// 当主文档已committed时,如果发生错误将进行调用
    	- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error; 
    	
    	// 如果需要证书验证,进行验证,一般使用默认证书策略即可 
    	- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler; 
    	
    	// 9.0才能使用,web内容处理中断时会触发,可针对该情况进行reload操作,可解决部分白屏问题 
    	- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0); 
    	
    	@end
    
    ② 深入理解 WKNavigationDelegate 方法
    • WKNavigationDelegate 代理方法的调用流程如下:

    在这里插入图片描述

    • decidePolicyForNavigationAction 剖析
      • 如上文的网页加载流程,当 WebContent 即将创建 DocumentLoader 加载器时,会首先触发 decidePolicyForNavigationAction 代理方法。如果我们选择 cancel,那么浏览内核会完全忽略这一操作,后续也不再继续执行其他操作,可以放心的使用 cancel 取消掉我们不想加载的主文档请求,而无需担忧任何异常。
      • 但当选择 alllow 后,会进入一个稍微复杂的逻辑判断,内核代码首先判断该该链接是否是 universalLink 类型的链接,如果判断是 universalLink 类型的链接,会尝试去调起三方 app,如果能调起,则会 cancel 当前请求,否则才会走到正常的网络加载逻辑(如果需要统计 universalLink 调起情况与或建设屏蔽能力,可以再仔细阅读该处源码)。
    • didStartProvisionalNavigation 理解
      • decidePolicyForNavigationAction 方法中选择 allow 并且判断为非 universalLink 链接后,会立即触发 didStartProvisionalNavigation 方法,表示即将开始加载主文档。这个方法看似只是对 decidePolicyForNavigationAction 方法的确认,但是值得思考的问题是方法名中的 Provisional 究竟是什么意思。
      • 其实,页面开始页面加载后为了更好的区分加载的各阶段,会将网络加载的初始阶段命名为临时状态,此时的页面是不会记入历史的,直到接收到首个数据包,才会对当前页面进行 committed 提交,并触发didCommitNavigation 方法通知 UIProcess 进程该事件,同时将网络 data 提交给 WebContent 进行渲染树生成。可由此引申出下一个问题,即 didFailProvisionalNavigation 与 didFailNavigation 的关系。
    • didFailProvisionalNavigation 与 didFailNavigation 的分别在什么时候执行?它们之间有什么关系?
      • 当 NetworkProcess 进程发生网络错误时,错误首先由 NSURLSession 回调到 WebContent 层。
      • WebContent 会判断当前主文档加载状态,如果处于临时态,则错误会回调给 didFailProvisionalNavigation 方法;如果处于提交态,则错误会回调给 didFailNavigation 方法。

    在这里插入图片描述

    • didFinishNavigation 究竟什么时候执行?与页面上屏是否有关?
      • 在上面的描述中,我们已经理解了 NetworkProcess 层也是使用 NSURLSession 加载主文档的。当 NSURLSession 接收到 finish 事件时,会将该消息通过进程通信方式传递给 WebContent 进程,WebContent 进程再传递给 UIProcess 进程,直到被我们的代理方法响应。
      • 因此 didFinishNavigation 在 NSURLSession 的网络加载结束时就会触发,但因为跨了两次进程通信,因此对比网络层,实际上是有一定的延迟的。与子资源加载和页面上屏无时间先后关系。

    五、Tips

    • 一定要紧密结合三大进程去理解 WebKit 源码,形成基于进程的知识体系。
    • 可以直接修改源码验证猜想。例如在验证触发渲染条件时,可以在源码中禁止网络层 didfinish 事件执行,并自己构造数据返回,验证各类上屏触发条件。
    展开全文
  • wkwebview加载空白问题

    千次阅读 2019-03-31 21:49:30
    代理方法中实现: ...- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisi...

    代理方法中实现:

    // 在收到响应后,决定是否跳转
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    
    
    
    WKNavigationResponsePolicy actionPolicy = WKNavigationResponsePolicyAllow;
    //这句是必须加上的,不然会异常
    decisionHandler(actionPolicy);
    
     }
    // 在发送请求之前,决定是否跳转
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    
    self.title = webView.title;
    
    WKNavigationActionPolicy actionPolicy = WKNavigationActionPolicyAllow;
    
    //这句是必须加上的,不然会异常
    decisionHandler(actionPolicy);
    }
    
    展开全文
  • WKWebView 白屏问题

    万次阅读 2017-01-20 16:43:57
    1、WKWebView 自诩拥有更快的加载速度,更低的内存占用,但实际上 WKWebView 是一个多进程组件,Network Loading 以及 UI Rendering 在其它进程中执行。初次适配 WKWebView 的时候,我们也惊讶于打开 WKWebView 后,...
  • 最近在工作中遇到了WKWebView白屏的问题,所以这篇文章主要给大家介绍了关于iOS中WKWebView白屏问题的分析与解决方法,文中通过示例代码介绍的非常详细,对同样遇到这个问题的朋友具有一定的参考学习价值,需要的...
  • ????????关注后回复“进群”,拉你进程序员交流群????????作者丨童红明来源丨百度App技术1. 前言从 WebView 开始加载一条请求,到页面完整呈现这一过程发生了什么?...
  • 关于WKWebView加载完毕的代理方法

    千次阅读 2016-12-29 23:27:22
    需求:在点击button的时候,当前页面出现loading动画...我的思路:在button action的方法中,只是alloc init一个H5页面,在H5页面加载完毕的代理方法中发出Notification,然后在首页添加监听Notification,push页面. bu
  • iOS WKWebview 白屏检测实现 前言 自ios8推出wkwebview以来,极大改善了网页加载速度... 针对业务场景需求,实现加载白屏检测。考虑采用字节跳动团队提出的webview优化技术方案。在合适的加载时机对当前webview...
  •  针对业务场景需求,实现加载白屏检测。考虑采用字节跳动团队提出的webview优化技术方案。在合适的加载时机对当前webview可视区域截图,并对此快照进行像素点遍历,如果非白屏颜色的像素点超过一定的阈值,认定其为...
  • 如题:iOS开发中使用WKWebView加载本地html页面,html页面$.ajax()无法发出请求?! 加载html的API是 - (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
  • ????????关注后回复“进群”,拉你进程序员交流群????????作者丨童红明来源丨百度App技术1. 前言从 WebView 开始加载一条请求,到页面完整呈现这一过程发生了什么?...
  • 之前项目加载全景图片用的720云全景和krpano,生成后下载到本地用UIWebView加载,今天看到了苹果禁止了UIWebView,就试试WKWebView首先加到项目里的时候记得选择Create folder references,就是变成蓝色文件夹之前...
  • wkwebview 刷新仍然白屏

    千次阅读 2019-02-14 15:23:37
    如果先断网,加载WKWebView后,页面出现空白;然后再连网,点击按钮后不刷新WKWebView,页面还是一片空白。 使用 [weakSelf.wkweb reload]; 方法刷新,急速切换网络会导致wkwebview刷新无效。 使用 [self.wkweb ...
  • IOS WKWebView 白屏问题

    万次阅读 2019-05-14 10:50:38
    WKWebView 是苹果在 WWDC 2014 上推出的新一代 webView 组件,用以替代 UIKit 中笨重难用、内存泄漏的 UIWebView。WKWebView拥有60fps滚动刷新率、和 safari 相同的 JavaScript 引擎等优势。 简单的适配方法...
  • WKWebView白屏处理方案

    2017-09-18 14:40:00
    WKWebView加载下面的测试链接可以稳定重现白屏现象: http://people.mozilla.org/~rnewman/fennec/mem.html 1 这个时候 WKWebView.URL 会变为 nil, 简单的 reload 刷新操作已经失效,对于一些长驻的H5...
  • iOS的WKWebView白屏处理,终极方案

    千次阅读 2019-06-11 15:01:52
    只有H5自己说加载完成了才是真的完成了,H5加载完成后通过JS向OC发送个消息,即可。 JS与OC交互请自行找一下,不做细述。 其余思路 1. 有没有标题。个别时候好用。 2. 有没有WKCompositingView。有时候好用。 3. ...
  • 我们app从ReactNative转H5app,在开发过程中发现一个顽固性问题。...WKWebView是一个多进程组件,Network Loading以及UI Rendering在其它进程中执行。所以UIWebView上当内存占用太大的时候,App Process会crash;而...
  • 主要介绍了iOS11 WKWebView 无法加载内容,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 在根据《IOS开发指南 从helloworld到AppStore上架 第四版》学习的时候,看到第八章『树形导航结构』使用WKWebView进行三级导航展示详情,发现白屏 解决方案 WKWebView根据『WKNavigationDelegate』协议有几个...
  • WKWebView iOS9 加载H5界面失败

    千次阅读 2018-08-28 10:28:45
    前几天看到群里面的小伙伴说碰到一个奇怪的问题, 说 WKWebView 加载H5界面, 在iOS10 ,iOS11上...但是想到WKWebView加载H5,也就几句代码的事情,又能出什么问题. 然后怀疑前端是不是限制iOS运行的版本, 回答也是没有...
  • 1、字体变小解决办法Swiftlet headerString = ""self.wkwebview.loadHTMLString(headerString.appending(html), baseURL: nil)Objective-CNSString *headerString = @"";[strongSelf.contentWebView loadHTMLString:...
  • WKWebview的那些坑之白屏问题

    万次阅读 2017-03-26 21:20:11
    项目中用到WKWebview的童鞋有可能会遇到突然页面白屏问题,这个问题是因为内存不够了webview的进程被程序终止了,那我们如何监听到进程被终止的事件以及做何处理呢? (一)监听WKWebview进程终止 iOS9时系统...
  • (1)iOS8.1 系统,部分网页加载白屏,例如 百度,iOS8.3 似乎没问题 (2)web输入框输入汉字也会出现白屏 通过搜索得到问题根源: WKWebView’s WebProcess runs out-of-process as a 64-bit process on hardware ...

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 334
精华内容 133
关键字:

wkwebview加载白屏