iOS面试-WebView一些知识

这次去小红书面试。问了一些关于webView的内容。由于之前很多东西是用第三方库去实现,而且不是很清楚第三方库的机理,所以面试的时候遇到了一些障碍。现整理一下一些webView的知识。

webView与原生的交互

问我webView与原生的交互是怎么实现的。我说用的是第三方库 WebViewJavascriptBridge 。面试官的意思是这个简单的交互根本不需要重量级的第三方库库实现。
具体WebViewJavascriptBridge怎么实现OC与JS的互相调用,下面链接写的很清楚。
http://www.jianshu.com/p/ca496cb680fe

我们主要是探讨下WebViewJavascriptBridge的运行机理。

Obj-C调用JavaScript:

通过webview的stringByEvaluatingJavaScriptFromString:方法调用JavaScript代码

JavaScript调用Obj-C

通过web view的代理方法shouldStartLoadWithRequest:来接收JavaScript的网络请求从而实现调用。

里面的精髓是WebViewJavascriptBridge.js.txt文件

主要完成了如下工作:

创建了一个用于发送消息的iFrame(通过创建一个隐藏的iframe,并设置它的URL来发出一个请求,从而触发UIWebView的shouldStartLoadWithRequest回调协议)

怎么去缓存webView

这一题当时有点懵逼,因为没有做过webview的缓存。当时想着是怎么直接实现缓存,不知道苹果本来就自带有自己的缓存策略。

接下来是网上看到的手动缓存的方式。
1.首先获取html的数据

NSString * htmlResponseStr=[NSString stringWithContentsOfURL:[NSURL URLWithString:urlStr] encoding:NSUTF8StringEncoding error:Nil];

2.这个的难度是缓存webView的图片数据

//获取web里的所有的img url
- (NSString *)createImgArrayJavaScript{
    NSString *js = @"var imgArray = document.getElementsByTagName('img'); var imgstr = ''; function f(){ for(var i = 0; i < imgArray.length; i++){ imgstr += imgArray[i].src;imgstr += ';';} return imgstr; } f();";
    return js;
}

//返回web img图片的数量
- (NSString *)createGetImgNumJavaScript{
    NSString *js = @"var imgArray = document.getElementsByTagName('img');function f(){ var num=imgArray.length;return num;} f();";
    return js;
}

接下来就是判断是否用自己下载的本地图片

NSString * htmlResponseStr=[NSString stringWithContentsOfURL:[NSURL URLWithString:urlStr] encoding:NSUTF8StringEncoding error:Nil];
    NSString *resourcePath = [ [NSBundle mainBundle] resourcePath];
    [_fileManager createDirectoryAtPath:[resourcePath stringByAppendingString:@"/Caches"] withIntermediateDirectories:YES attributes:nil error:nil];
    NSString * path=[resourcePath stringByAppendingString:[NSString stringWithFormat:@"/Caches/%d.html",[urlStr hash]]];
    [htmlResponseStr writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];

如何做网页的进度条

网页的进度条用的是有名的第三方框架NJKWebViewProgress
下载地址:https://github.com/ninjinkun/NJKWebViewProgress
原理:
webView的请求进度很难做到精准,NJKWebViewProgress巧妙的用了请求数量来。
1.webViewDidStartLoad 是一个请求的开始,所有的请求都要经过它,未加载资源之前,能够得到一个URL 有多少个资源需要加载,使用_loadingCount++ 方式来计数。
2.webViewDidFinishLoad、didFailLoadWithError 是一个请求的结束,每次请求结束 _loadingCount –,并重新计数进度
进度使用 _loadingCount/_maxLoadCount 的方式来计算
2.每次webViewDidFinishLoad、didFailLoadWithError 请求都加入了 waitForCompleteJS 这样的js到web view中,来检测网页是否加载完成。

你可能感兴趣的:(ios)