55

解决 WKWebView goback执行无效的bug

 5 years ago
source link: http://www.cocoachina.com/ios/20180801/24405.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

目前移动端的开发中会经常使用到加载H5。Apple提供了两种加载WebView的控件,一个是UIWebView,一个是WKWebView。WKWebView 是 Apple WWDC 2014随iOS 8和OS X 出来的,解决UIWebView加载速度慢、占用内存大的问题。之前的开发中我们要适配iOS7,所以未使用。现在项目都适配iOS 8以上了,所以就开始使用WKWebView了。下面是在开发中遇到的一个 goback执行无效 的坑,故记录下来。

1.先在这里贴上运行效果,大家可以先看一下。

URB7Vzu.gif

返回失效bug.gif

zaEjqir.png!web

屏幕快照 2018-05-09 下午3.25.13.png

gif是操作到点击系统导航返回按钮的时候断点走了进去,但是断点去掉后同样停留在了当前的展示的兴业银行的界面了。这也就是 goBack执行,但是并未生效。

2.解决bug步骤

1.进入过WKWebView里面看过的话我们会知道它内部有一个属性是 backForwardList 浏览列表。

FJZbey2.jpg!web

11525851885_.pic_hd.jpg

可以看到这里声明了一个 WKBackForwardList *backForwardList;上面清晰的写出了 The item immediately following the current item, or nil if there isn't one. 这句话的意思是 紧随当前项目的项目,如果没有,则为零 。那么点击进去WKBackForwardList可以看到里面还包含了一个属性backlist,那么就很清楚这个是返回列表了。所以这里在返回点击事件中打印下这个值,看下这个值是否正确。

uaIVvyQ.png!web

到这一步很明显我们是对的,确实我们走到兴业银行界面时,我们是走了3层。

那为什么goback会失效呢?

3.找到原因

之后由公司iOS大神指导后,发现了问题。之前写goback的时候很少会有人点进去看一下goback的返回值。进去后发现goback返回值为 WKNavigation , 所以这里我们尝试打印出这个WKNavigation,看下这个WKNavigation值是什么。下面是打印出来的:

bIf6zyb.jpg!web

21525853471_.pic_hd.jpg

走到这一步我们可以清楚看到走到兴业银行页面返回时,Navigation 为nil了。所以我们大致就定位到问题是在Navigation上面,因为Navigation为nil,所以导致goback执行无效。

4.解决问题

问题已经找到了,那么我们应该如何让他返回到我们指定的页面呢? 这时候我们还是需要去找第二个问题里面我们发现的历史列表。 WKBackForwardList; 这个文件中我们可以进去看下,如图:

ZbiAVnZ.png!web

这里我们可以看到里面有函数是 itemAtIndex ,这个函数是可以获取到我们要跳转到的页面。我们看下他注释的意思 可以知道 0 为当前项,1为下一项 -1为上一项。那么看到这里我们就可以试着去做尝试了首先我们拿到nav。这里我们要使用while来循环这个变量。然后调用指定返回的函数。代码如下:

WKBackForwardListItem *item1 = [self.webView.backForwardList itemAtIndex:-1];
 navigation = [self.webView goToBackForwardListItem:item1];

这里我们运行就可以看到效果可以返回了。但是我们要实现永远返回到上一页如何去做呢。这里我们可以声明一个变量,在while循环时给他进行++,然后通过这个变量我们寻找我们需要返回到的item。然后指定去返回。整体代码如下

WKNavigation *navigation = [self.webView goBack];
    NSInteger offset = 1;
    while (!navigation)
    {
        offset++;
        if (self.webView.backForwardList.backList.count >= offset)
        {
            WKBackForwardListItem *item1 = [self.webView.backForwardList itemAtIndex:-offset];
            navigation = [self.webView goToBackForwardListItem:item1];
        }
        else
        {
            break;
        }
    }

到这一步就已经完美的解决goback执行无效的bug了。这个bug产生在网上查询了下,可能是因为我们看到的跳转,但是内部js并未进行改变,所以产生了这个bug。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK