WKWebView和UIWebView及其四种交互
来源:互联网 发布:希拉里 邮件门 岛 知乎 编辑:程序博客网 时间:2024/05/29 17:02
**
UIWebView
官方文档翻译
**
继承关系:NSObject→UIResponder→UIView-→UIWebView
遵循:NSCoding NSObject UIAppearance UIAppearanceContainer UICoordinateSpace UIDynamicItem UIScrollViewDelegate UITraitEnvironment
你可以使用UIWebView类嵌入网页内容在您的应用程序。这样做,您只需创建一个UIWebView对象,将它附加到一个窗口,并发送一个请求来加载网页内容。你也可以使用这个类来搬回和网页历史的前进,你甚至可以以编程方式设置的一些网页内容的性质。
注:
在iOS 8及以后的运行应用程序,建议您使用WKwebview代替使用UIWebView。此外,如果你使用不能运行的JavaScript文件,应该设置WKpreferences属性 javascriptenabled为NO。
使用loadhtmlstring:baseURL:开始加载本地HTML文件,loadRequest的方法:开始加载的Web内容的方法。使用stopLoading方法停止加载,loading 属性是去发现是否有一个Web视图是在加载过程中。
如果你允许用户通过网页历史向前向后移动了,那么你可以使用goForward和goBack方法做完按钮的动作。使用canGoBack和canGoForward属性禁用的按钮时当用户不能在一个方向移动。
默认情况下,一个webview会自动将出现在网络内容中的电话号码转换为电话号码。当电话链接被点击时,手机应用将进行拨号。设置detectsphonenumbers属性为NO 关闭此默认行为。
当网页内容显示时,你也可以使用scalesPageToFit属性去设置网页内容的比例。此后,用户可以使用手势改变尺度。
如果你想跟踪Web内容加载设置代表性对象符合UIWebviewdelegate协议等。
重点:
你不应该嵌入UIWebView或UITableView对象到UIScrollView对象里。如果你这样做,意外的行为可能会导致因为触摸事件的对象可以混淆和错误处理。
一般的处理方式是直接在html中调用JS或者CSS,或者是最近比较流行的query mobile ,都可以直接调用系统的API,执行操作。
WKWebView
苹果在iOS8中加入的用来替代UIWebView的控件。比UIWebView加载块一倍的控件,内存方面却比它少一半,但是相对的缓存处理方面会稍微差一点。
整理下优缺点如下:
优点:
将浏览器内核渲染进程提取出 App,由系统进行统一管理,这减少了相当一部分的性能损失。
js 可以直接使用已经事先注入 js runtime 的 js 接口给 Native 层传值,不必再通过苦逼的 iframe 制造页面刷新再解析自定义协议的奇怪方式。
支持高达 60 fps 的滚动刷新率,内置了手势探测。
缺点:
MK对缓存和Cookie操作没有UIWebView那么方便。(调用的API没有那么显著的用途。)
MK从iOS8才开始支持,也就是说在我们同时对iOS7支持的情况下,如果为了减少代码量及适配等方面因素,一样会选择UIWebView。
鉴于 UIWebView的钟爱,浅谈一下其缓存机制
1、NSURLRequestUseProtocolCachePolicy NSURLRequest默认的cache policy,使用Protocol协议定义。
2、NSURLRequestReloadIgnoringCacheData 忽略缓存直接从原始地址下载。
3、NSURLRequestReturnCacheDataElseLoad 只有在cache中不存在data时才从原始地址下载。
4、NSURLRequestReturnCacheDataDontLoad 只使用cache数据,如果不存在cache,请求失败;用于没有建立网络连接离线模式;
5、NSURLRequestReloadIgnoringLocalAndRemoteCacheData:忽略本地和远程的缓存数据,直接从原始地址下载,与NSURLRequestReloadIgnoringCacheData类似。
6、NSURLRequestReloadRevalidatingCacheData:验证本地数据与远程数据是否相同,如果不同则下载远程数据,否则使用本地数据。
**
OC与H5的交互
**
当然我们在用到webview的时候会经常用到交互类的,实际即为WEB端和iOS手势的结合,而带来的一些数据的交换。
方法一、用来监听当前web的协议方法
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
此方法用于,web加载新的网络请求,监听并得到webview的一些信息
方法二、调用JS执行语句,在点击之后直接执行对应JS语句。
另个就是直接调用JS语句(学一些比较基本的JS语句还是很有必要的)
[webview stringByEvaluatingJavaScriptFromString:@”JS方法”]; //添加到head标签中
然后当前web就会直接执行那个JS方法
还有一种就是JS调OC的方法
其实和第一种类似,在html里面约定好,你给传一个方法名(其实只是约定的一个string)然后我再根据方法
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
来判断是否调用了,然后直接执行相应的方法。
方法三、比较实用的H5调用OC自定义方法。无需使用代理方法**
其实还是有一种H5直接调用OC的方法的。此方法很好的解决了H5和iOS上架应用的交互问题.
现在要求web中遇到404的情况,直接在H5中判断到然后调用OC自定义方法。执行操作。
//H5调用的OC方法- (void)jsValue{ //获取H5中的JS上下文 JSContext *context = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //JS方法中约定的一个方法名 NSString *overtime = @"logee"; //执行H5调用的方法后,iOS执行的方法。执行方法名对应的代码块。 context[overtime] = ^() { NSURL *url = [[NSURL alloc]initWithString:URL_LOGIN]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [webview loadRequest:request]; NSArray *args = [JSContext currentArguments]; for (JSValue *jsVal in args) { NSLog(@"%11111@", jsVal); } JSValue *this = [JSContext currentThis]; NSLog(@"jsValue:%@",this); }; //执行H5调用的方法后,iOS执行的方法。 context[@"overTime"] = ^(){ NSURL *url = [[NSURL alloc]initWithString:@"https://www.baidu.com"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [webview loadRequest:request]; };}
H5中的index.html代码部分
<html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="description" content=""> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <script type="text/javascript" src="index.js"></script> </head> <button id="hallo" onclick="buttonClick()"> 点击button</button> </body> </html>
我们在JS代码中要写的index.js
点击Button执行的操作。
function buttonClick() { overTime("hello world"); }
产生的效果就是点击Button,然后执行了OC代码块
注意:最好不要使用以下代码获取状态码
在使用过程中容易产生重复发送表单。
#pragma mark - #pragma mark - UIWebView Delegate Methods - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { static BOOL isRequestWeb = YES; if (isRequestWeb) { NSHTTPURLResponse *response = nil; //重新发送了数据请求,重复表单。 NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; if (response.statusCode == 404) { // code for 404 return NO; } else if (response.statusCode == 403) { // code for 403 return NO; } [webView loadData:data MIMEType:@"text/html" textEncodingName:nil baseURL:[request URL]]; isRequestWeb = NO; return NO; } return YES; }
方法四、 使用三方库WebViewJavascriptBridge ,iOS 8之后使用WKwebview,所以也是也有很多使用的
是WKWebViewJavascriptBridge。
一般我们都保留两个版本,支持iOS 8以上,webview 基本就背放弃了,所以这样也就简单介绍下WKWebViewJavascriptBridge的使用。具体的demo可以下载阅读。
下面是OC的代码也是他的官网demo
首先下载WKWebViewJavascriptBridge 导入项目中,加入头文件
import "WKWebViewJavascriptBridge.h"
if (_bridge) { return; } WKWebView* webView = [[NSClassFromString(@"WKWebView") alloc] initWithFrame:self.view.bounds]; webView.navigationDelegate = self; [self.view addSubview:webView];//wk的类方法,相当于注册,里面就一个返回值默认false,调用后直接返回yes [WKWebViewJavascriptBridge enableLogging]; //相当于将 _bridge对象绑定到这个webview中。 _bridge = [WKWebViewJavascriptBridge bridgeForWebView:webView]; //设置WKwebview的代理 WKNavigationDelegate ,看原文件就知道了。 [_bridge setWebViewDelegate:self]; /** * 注册回调 * * @param data JS传给前端的数据 * @param responseCallback * * @ testObjcCallback 就是handlerName,是和前端约定好的, * */ [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { //objc 回调的数据,也就是JS传给objc的数据 NSLog(@"JS发送给objc的数据:%@", data); //回调的响应,就是前端接收到数据后,然后可将有用的数据返回给JS responseCallback(@"需要回调给js的数据"); }];
//JS 给约定的js方法testJavascriptHandler" 发送数据 [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }];
// 此方法为了将data 数据放送给js - (void)callHandler:(id)sender { id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { NSLog(@"testJavascriptHandler responded: %@", response); }];}
- WKWebView和UIWebView及其四种交互
- UIWebView和WKWebView的使用及js交互
- UIWebView和WKWebView的使用及js交互
- UIWebView和WKWebView的使用及js交互
- UIWebView和WKWebView
- Swift UIWebView 和 WKWebView
- WKWebView和UIWebView
- WKWebView 和UIWebView
- UIWEBVIEW和WKWebView学习
- IOS UIWebView (API+JS交互)、WKWebView
- UIWebView、WKWebView与js的交互
- OC 与 JS 交互 (UIWebView & WKWebView)
- WKWebView和UIWebView加载本地html和JS交互各种坑解决办法
- UIWebview和WKWebview的使用 js交互 本地加载 网络加载
- android webview & ios uiwebview和wkwebview的交互以及本地缓存
- WKWebView详解&WKWebVieW和JS交互
- UIWebView---UIWebView和JavaScript交互
- WKWebView OC和JS交互
- 《Natural Language Processing》斯坦福视频学习笔记——2.text processing
- WPF-10:绑定时注意UpdateSourceTrigger
- BGP 地址族分析 - Address-family
- 中文和unicode互转
- 虚拟现实(VR)和增强现实(AR)背后的核心技术是什么?
- WKWebView和UIWebView及其四种交互
- Hello World
- objective-C学习 KVC
- Android笔记(10) - Animation详解
- mysql优化-数据库结构
- 【图像基础】尺度空间:尺度的选择[经验之谈]
- poj 2406Power Strings(KMP入门)
- 异常类
- 叶子结点