本文主要是介绍iOS之JavaScript与OC的相互调用:WKwebview 的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
#import <WebKit/WebKit.h>
添加代理<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>//创建一个WKWebView的配置对象
WKWebViewConfiguration *configur=[[WKWebViewConfiguration alloc]init];
//设置configur对象的preferences属性的信息
WKPreferences *preferences = [[WKPreferences alloc]init];
configur.preferences=preferences;
//是否允许与js进行交互,默认是YES的,如果设置为NO,js的代码就不起作用了
preferences.javaScriptEnabled =YES;
WKUserContentController *userContentController=[[WKUserContentController alloc]init];
//添加消息处理,注意:self指代的是需要遵守WKScriptMessageHandler协议,结束时需要移除
[userContentController addScriptMessageHandler:self name:@"showSendMsg"];
configur.userContentController=userContentController;//解决跨域问题[configur.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];if (@available(iOS 10.0, *)) {[configur setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];}
WKWebView *wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0,WIDTH , HEIGHT) configuration:configur];
[self.view addSubview:wkWebView];
//设置内边距底部,主要是为了让网页最后的内容不被底部的toolBar挡着
//wkWebView.scrollView.contentInset=UIEdgeInsetsMake(0, 0, 104, 0);
//这句代码是让竖直方向的滚动条显示在正确的位置
wkWebView.scrollView.scrollIndicatorInsets=wkWebView.scrollView.contentInset;wkWebView.UIDelegate=self;
wkWebView.navigationDelegate=self;//加载html字符串
//[wkWebView loadHTMLString:html StrbaseURL:nil];//加载html网页
NSURL *url = [[NSBundle mainBundle] URLForResource:@"suning"withExtension:@"html"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];[wkWebView loadRequest:urlRequest];从web界面中接收到一个jsscript脚本时调用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
//如果传递的参数是json的话//id param =message.body;// NSString *urlString=@"";//if([param isKindOfClass:[NSDictionary class]]){// if([[param allKeys]containsObject:@"func"]){// urlString=[param valueForKey:@"func"];// }// }NSString *coverWebview=message.name;
NSLog(@"js中的方法 ---%@--传递的参数-%@",coverWebview,message.body);
//如果方法名是我们需要的,那么说明是时候调用原生对应的方法了
if([coverWebview isEqualToString:@"showSendMsg"]){[self showSendMsg];
}}-(void)showSendMsg{
NSLog(@"js调用OC方法实现了");}html代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><title>苏宁首页,rem+less布局+媒体查询</title>
</head>
<body><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><h1>dafdfcdsadsad</h1><script type='text/javascript'>function btnClick3() {window.webkit.messageHandlers.showSendMsg.postMessage(['123', 'qqqq'])}btnClick3();</script>
</body>
</html>
js调用oc方法二:采用截获url
//ios13
//WKWebView拦截url进行原生界面跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {// 获取完整url并进行UTF-8转码NSString *strRequest = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];NSLog(@"即将跳转到的那个url---%@",strRequest);if ([strRequest hasSuffix:@"xbs_regist"]||[strRequest hasSuffix:@"xbs_refuse"]) {// 拦截点击链接if([strRequest hasSuffix:@"xbs_regist"]){self.block(YES);}else if([strRequest hasSuffix:@"xbs_refuse"]){self.block(NO);}// 不允许跳转decisionHandler(WKNavigationActionPolicyCancel);}else {// 允许跳转decisionHandler(WKNavigationActionPolicyAllow);}
}
==========参考WKWebView的使用========
http://www.cocoachina.com/articles/498556
http://blog.csdn.net/u011619283/article/details/52352514
http://www.cnblogs.com/jiang-xiao-yan/p/5345893.html
参考:http://www.jb51.net/article/107672.htm
http://www.jianshu.com/p/75f3abd40cc1
http://blog.csdn.net/y550918116j/article/details/50134625
http://blog.csdn.net/hmh007/article/details/53126809(综合包含jscore)
一、WKWebView Framework
WKWebView的14个类与3个协议:
WKBackForwardList:之前访问过的 web页面的列表,可以通过后退和前进动作来访问到。
WKBackForwardListItem: webview 中后退列表里的某一个网页。
WKFrameInfo: 包含一个网页的布局信息。
WKNavigation: 包含一个网页的加载进度信息。
WKNavigationAction:包含可能让网页导航变化的信息,用于判断是否做出导航变化。
WKNavigationResponse:包含可能让网页导航变化的返回内容信息,用于判断是否做出导航变化。
WKPreferences: 概括一个 webview的偏好设置。
WKProcessPool: 表示一个 web内容加载池。
WKUserContentController: 提供使用 JavaScript post信息和注射 script的方法。WKUserContentController可以理解为调度器,
WKScriptMessage: 包含网页发出的信息。WKScriptMessage则是携带的数据。
WKUserScript:表示可以被网页接受的用户脚本。
WKWebViewConfiguration: 初始化 webview的设置。
WKWindowFeatures: 指定加载新网页时的窗口属性。
WKWebsiteDataStore: 包含网页数据存储和查找。
===三个协议====
WKNavigationDelegate:提供了追踪主窗口网页加载过程和判断主窗口和子窗口是否进行页面加载新页面的相关方法。
WKUIDelegate:提供用原生控件显示网页的方法回调。这个协议主要用于WKWebView
处理web界面的三种提示框(警告框、确认框、输入框),
WKScriptMessageHandler: 提供从网页中收消息的回调方法。WKScriptMessageHandler其实就是一个遵循的协议,它能让网页通过JS把消息发送给OC
二、WKWebView中的三个代理方法
1. WKNavigationDelegate
该代理提供的方法,可以用来追踪加载过程(页面开始加载、加载完成、加载失败)、决定是否执行跳转。
//页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
//当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
//页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
//页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
页面跳转的代理方法有三种,分为(收到跳转与决定是否跳转两种)
//接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
//在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
//在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
2. WKUIDelegate
创建一个新的WKWebView
// 创建一个新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
剩下三个代理方法全都是与界面弹出提示框相关的,针对于web界面的三种提示框(警告框、确认框、输入框)分别对应三种代理方法。
//界面弹出警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;
//界面弹出确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
//界面弹出输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *__nullable result))completionHandler;
3. WKScriptMessageHandler
这个协议中包含一个必须实现的方法,这个方法是native与web端交互的关键,它可以直接将接收到的JS脚本转为OC或Swift对象。
//从web界面中接收到一个js脚本时调用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
三、使用WKWebView重写
这里我们和之前的界面做了一点改动,之前OC调用JS的时候是进行弹框处理,这里我在写的时候,很郁闷,方法可以调用过去,但是唯独js的alert方法调用没有效果,所以这里采用了输出到div的形式,并增加了一个clear按钮
WKWebView不支持nib文件,所以这里需要使用代码初始化并加载WebView
======实例1
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.preferences.minimumFontSize = 18;
self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0,self.view.bounds.size.width,self.view.bounds.size.height/2) configuration:config];
[self.view addSubview:self.wkWebView];
NSString *filePath = [[NSBundlemainBundle]pathForResource:@"index"ofType:@"html"];
NSURL *baseURL = [[NSBundlemainBundle]bundleURL];
[self.wkWebView loadHTMLString:[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] baseURL:baseURL];
====实例2
OC端:
//1. JS调用OC添加处理脚本
//添加消息处理,注意:self指代的是需要遵守WKScriptMessageHandler协议,结束时需要移除
[userContentController addScriptMessageHandler:self name:@"showMobile"];
[userContentController addScriptMessageHandler:self name:@"showName"];
[userContentController addScriptMessageHandler:self name:@"showSendMsg"];
//从web界面中接收到一个js脚本时调用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
//name是js中的方法名,body是参数
if ([message.name isEqualToString:@"showMobile"]) {
}
if ([message.name isEqualToString:@"showName"]) {
}
if ([message.name isEqualToString:@"showSendMsg"]) {
}
}
//JS响应方法列表------在JS中实现
function btnClick1() {
window.webkit.messageHandlers.showMobile.postMessage(null)
}
function btnClick2() {
window.webkit.messageHandlers.showName.postMessage('www')
}
function btnClick3() {
window.webkit.messageHandlers.showSendMsg.postMessage(['123', 'qqqq'])
//*************************OC调用JS的方法列表
- (IBAction)btnClick:(UIButton *)sender {
if (!self.wkWebView.loading) {
if (sender.tag == 123) {
[self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id_Nullable response, NSError *_Nullable error) {
NSLog(@"%@ %@",response,error);
}];
}
if (sender.tag == 234) {
[self.wkWebView evaluateJavaScript:@"alertName('小红')" completionHandler:nil];
}
if (sender.tag == 345) {
[self.wkWebView evaluateJavaScript:@"alertSendMsg('18870707070','周末爬山真是件愉快的事情')"completionHandler:nil];
}
} else {
NSLog(@"the view is currently loading content");
}
}
function alertMobile() {
document.getElementById('mobile').innerHTML = 'qqqqq';
}
function alertName(msg) {
document.getElementById('name').innerHTML = 'sffd'
}
function alertSendMsg(num,msg) {
document.getElementById('msg').innerHTML = '这是我的手机号:' + num + ',' + msg + '!!'
}
======实例3
1 WKScriptMessageHandler
1.1 WKScriptMessageHandler协议
WKScriptMessageHandler其实就是一个遵循的协议,它能让网页通过JS把消息发送给OC。其中协议方法。
/*! @abstract Invoked when a script message is received from a webpage.
@param userContentController The user content controller invoking the
delegate method.
@param message The script message received.
*/
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
从协议中我们可以看出这里使用了两个类WKUserContentController和WKScriptMessage。WKUserContentController可以理解为调度器,WKScriptMessage则是携带的数据。
1.2 WKUserContentController
WKUserContentController有两个核心方法,也是它的核心功能。
- (void)addUserScript:(WKUserScript *)userScript;: js注入,即向网页中注入我们的js方法,这是一个非常强大的功能,开发中要慎用。
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;:添加供js调用oc的桥梁。这里的name对应WKScriptMessage中的name,多数情况下我们认为它就是方法名。
1.3 WKScriptMessage
WKScriptMessage就是js通知oc的数据。其中有两个核心属性用的很多。
@property (nonatomic,readonly,copy) NSString *name;:对应- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;添加的name。
@property (nonatomic,readonly,copy)id body;:携带的核心数据。
js调用时只需
window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
这里的name就是我们添加的name,是不是感觉很爽,就是这么简单,下面我们就来具体实现。
======2 JS调用OC
2.1 配置WKUserContentController
要想使用WKUserContentController为web页面添加桥梁,只需配置到WKWebViewConfiguration即可。
下面改造webView方法。
#pragma mark - get方法
- (WKWebView *)webView {
if (_webView ==nil) {
// js配置
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
[userContentController addScriptMessageHandler:self name:@"jsCallOC"];
// WKWebView的配置
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = userContentController;
// 显示WKWebView
_webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
_webView.UIDelegate = self;//设置WKUIDelegate代理
[self.view addSubview:_webView];
}
return _webView;
}
2.2 实现WKScriptMessageHandler
在当前页面引入WKScriptMessageHandler,并实现WKScriptMessageHandler协议即可。
@interface YJBaseVC () <WKScriptMessageHandler>
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"方法名:%@", message.name);
NSLog(@"参数:%@", message.body);
// 方法名
NSString *methods = [NSString stringWithFormat:@"%@:", message.name];
SEL selector = NSSelectorFromString(methods);
// 调用方法
if ([self respondsToSelector:selector]) {
[self performSelector:selector withObject:message.body];
} else {
NSLog(@"未实行方法:%@", methods);
}
}
2.3 改造index.html页面
修改index.html的onClickButton()方法。
// 点击确定按钮
function onClickButton() {
// 复杂数据
var list = [1,2,3];
var dict = {"name":"qqqq","qq":"222"};
alert(dict);
// JS通知WKWebView
window.webkit.messageHandlers.jsCallOC.postMessage(dict);
}
这里我们为了测试效果传入了一个复杂的字典数据,而且字典中还有数组。input.value代表用户输入的数据。
这里使用了window.webkit.messageHandlers.jsCallOC.postMessage(dict);通知oc,jsCallOC这个属性就是前面我们通过WKUserContentController注入的。
2.4 测试交互
我们在viewDidLoad使用index.html页面完成测试。
- (void)viewDidLoad {
[super viewDidLoad];
// [self loadWebView]; //加载测试
NSURL *url = [[NSBundle mainBundle] URLForResource:@"index"withExtension:@"html"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:urlRequest];//加载页面
}
=======WKUserScript预先注入一段js,在特定时刻加载js=======
4 WKUserScript JS注入
4.1 WKUserScript核心方法
在WebKit框架中,我们还可以预先添加JS方法,供其他人员调用。WKUserScript就是帮助我们完成JS注入的类,它能帮助我们在页面填充前或js填充完成后调用。核心方法。
/*! @abstract Returns an initialized user script that can be added to a@linkWKUserContentController @/link.
@param source The script source.
@param injectionTime When the script should be injected.
@param forMainFrameOnly Whether the script should be injected into all frames or just the main frame.
*/
- (instancetype)initWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)forMainFrameOnly;
4.2 WKUserScriptInjectionTime枚举
在WKUserScriptInjectionTime枚举中有两个状态。
WKUserScriptInjectionTimeAtDocumentStart:js加载前执行。
WKUserScriptInjectionTimeAtDocumentEnd:js加载后执行。
4.3 js注入
WKUserScript的运行需依托WKUserContentController,接下来我们就为WKWebView注入一个js执行完毕后执行的alert方法。
改造- (WKWebView *)webView方法。
#pragma mark - get方法
- (WKWebView *)webView {
if (_webView ==nil) {
// js配置
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
[userContentController addScriptMessageHandler:self name:@"jsCallOC"];
// js注入,注入一个alert方法,页面加载完毕弹出一个对话框。
NSString *javaScriptSource = @"alert(\"WKUserScript注入js\");";
WKUserScript *userScript = [[WKUserScript alloc] initWithSource:javaScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];// forMainFrameOnly:NO(全局窗口),yes(只限主窗口)
[userContentController addUserScript:userScript];
// WKWebView的配置
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = userContentController;
// 显示WKWebView
_webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
[self.view addSubview:_webView];
}
return _webView;
}
******************************js调用OC====
#import "ViewController.h"
#import <WebKit/WebKit.h>
@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
self.edgesForExtendedLayout=UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets=NO;
self.view.backgroundColor=[UIColorwhiteColor];
NSString *htmlstr=@"<!DOCTYPE html>"
"<html>"
"<head>"
"<meta charset='utf-8'>"
"<title>菜鸟教程(runoob.com)</title>"
"</head>"
"<body>"
"<h1>我的第一个标题</h1>"
"<p>我的第一个段落。</p><script type='text/javascript'>"
"function hideOverlay(){"
//注意postmessage中必须有参数
"window.webkit.messageHandlers.hideOverlayLayout.postMessage('www');"
"document.getElementsByTagName('h1')[0].innerHTML='ddd';"
"}"
"hideOverlay();"
"</script>"
"</body>";
[selfsetTrainTicketWithMKwebHtmlStr:htmlstr];
}
//MKWebview
-(void)setTrainTicketWithMKwebHtmlStr:(NSString *)htmlStr{
// WKWebView *web=[[WKWebView alloc]initWithFrame:CGRectMake(0, 0,WIDTH , HEIGHT-64)];
// self.wkweb=web;
// web.UIDelegate=self;
// web.navigationDelegate=self;
// [self.view addSubview:web];
// [web loadHTMLString:htmlStr baseURL:nil];
//创建一个WKWebView的配置对象
WKWebViewConfiguration *configur = [[WKWebViewConfigurationalloc]init];
//设置configur对象的preferences属性的信息
WKPreferences *preferences = [[WKPreferencesalloc]init];
configur.preferences = preferences;
//是否允许与js进行交互,默认是YES的,如果设置为NO,js的代码就不起作用了
preferences.javaScriptEnabled =YES;
WKUserContentController *userContentController = [[WKUserContentControlleralloc]init];
//添加消息处理,注意:self指代的是需要遵守WKScriptMessageHandler协议,结束时需要移除
[userContentController addScriptMessageHandler:selfname:@"hideOverlayLayout"];
configur.userContentController = userContentController;
WKWebView *wkWebView = [[WKWebViewalloc]initWithFrame:CGRectMake(0, 64,375 , 667-64)configuration:configur];
[self.viewaddSubview:wkWebView];
//设置内边距底部,主要是为了让网页最后的内容不被底部的toolBar挡着
wkWebView.scrollView.contentInset =UIEdgeInsetsMake(0, 0, 104, 0);
//这句代码是让竖直方向的滚动条显示在正确的位置
wkWebView.scrollView.scrollIndicatorInsets = wkWebView.scrollView.contentInset;
wkWebView.UIDelegate =self;
wkWebView.navigationDelegate =self;
[wkWebView loadHTMLString:htmlStrbaseURL:nil];
}
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecifiedWKNavigation *)navigation {
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
//NSLog(@"%@,%@",message.name,message.body);
NSString *coverWebview=message.name;
NSLog(@"js中的方法 ---%@",coverWebview);
//实现方法一
//如果方法名是我们需要的,那么说明是时候调用原生对应的方法了
if([coverWebviewisEqualToString:@"hideOverlayLayout"]){
[self hideOverlayLayout];
}
/*
//实现方法二:
// SEL selector = NSSelectorFromString(coverWebview);
// NSLog(@"js方法执行了");
// //判断当前方法是否存在
// if ([self respondsToSelector:selector]) {
//#pragma clang diagnostic push
//#pragma clang diagnostic ignored"-Warc-performSelector-leaks"
// //写在这个中间的代码,都不会被编译器提示PerformSelector may cause a leak because its selector is unknown类型的警告
// [self performSelector:selector withObject:nil];
//#pragma mark diagnostic pop
//
// }
*/
}
-(void)hideOverlayLayout{
NSLog(@"js调用OC方法实现了");
}
===========WKWebView中的cookie的设置===
WKWebView 的Cookie问题
UIWebView中会自动保存Cookie,如果登录了一次,下次再次进入的时候,会记住登录状态
而在WKWebView中,并不会这样,WKWebView在初始化的时候有一个方法
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
通过这个方法,设置 configuration让WKWebView知道登录状态,configuration可以通过已有的Cookie进行设置,也可以通过保存上一次的configuration进行设置
***实例1
WKWebView * webView = /*set up your webView*/
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/index.html"]];
[request addValue:@"TeskCookieKey1=TeskCookieValue1;TeskCookieKey2=TeskCookieValue2;"forHTTPHeaderField:@"Cookie"];
[webView loadRequest:request];
******实例2
WKUserContentController* userContentController = WKUserContentController.new;
WKUserScript * cookieScript = [[WKUserScriptalloc]
initWithSource:@"document.cookie = 'TeskCookieKey1=TeskCookieValue1';
document.cookie = 'TeskCookieKey2=TeskCookieValue2';"
injectionTime:WKUserScriptInjectionTimeAtDocumentStartforMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];
WKWebViewConfiguration* webViewConfig =WKWebViewConfiguration.new;
webViewConfig.userContentController = userContentController;
WKWebView * webView = [[WKWebView alloc] initWithFrame:CGRectMake(/*set your values*/) configuration:webViewConfig];
**************************JS调用OC之WKWebView + 第三方框架WebViewJavascriptBridge========
参考:https://github.com/Haley-Wong/JS_OC
https://github.com/marcuswestin/WebViewJavascriptBridge下载地址:https://github.com/marcuswestin/WebViewJavascriptBridge
==========1.在即使中要实现的代码:
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) {return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
<!--处理交互 方法名要和ios内定义的对应-->
setupWebViewJavascriptBridge(function(bridge) {
<!--处理 oc调用 js -->
bridge.registerHandler('registerAction', function(data, responseCallback) {
//处理oc给的传参
alert('oc请求js 传值参数是:'+data)
var responseData = { 'result':'handle success' }
//处理完,回调传值给oc
responseCallback(responseData)
})
var callbackButton = document.getElementById('buttons').appendChild(document.createElement('button'))
callbackButton.innerHTML = '点击我,我会调用oc的方法'
callbackButton.onclick = function(e) {
e.preventDefault()
<!--处理 js调用 oc -->
bridge.callHandler('loginAction', {'userId':'zhangsan','name': '章三'}, function(response) {
//处理oc过来的回调
alert('收到oc过来的回调:'+response)
})
}
})
=====2.需要在OC中实现的代码
******OC代码
- pod导入框架
pod 'WebViewJavascriptBridge'
#import "WebViewJavascriptBridge.h"
在 viewDidload 中:
//初始化 WebViewJavascriptBridge
if (_bridge) {return; }
[WebViewJavascriptBridge enableLogging];
_bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
[_bridge setWebViewDelegate:self];
//请求加载html,注意:这里h5加载完,会自动执行一个调用oc的方法
[self loadExamplePage:webView];
//申明js调用oc方法的处理事件,这里写了后,h5那边只要请求了,oc内部就会响应
[self JS2OC];
//模拟操作:2秒后,oc会调用js的方法
//注意:这里厉害的是,我们不需要等待html加载完成,就能处理oc的请求事件;此外,webview的request也可以在这个请求后面执行(可以把上面的[self loadExamplePage:webView]放到[self OC2JS]后面执行,结果是一样的)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 *NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self OC2JS];
});
***********************************************JS 调用 OC
-(void)JS2OC{
/*
含义:JS调用OC
@param registerHandler 要注册的事件名称(比如这里我们为loginAction)
@param handel 回调block函数当后台触发这个事件的时候会执行block里面的代码
*/
[_bridge registerHandler:@"loginAction" handler:^(id data, WVJBResponseCallback responseCallback) {
// data js页面传过来的参数 假设这里是用户名和姓名,字典格式
NSLog(@"JS调用OC,并传值过来");
//利用data参数处理自己的逻辑
NSDictionary *dict = (NSDictionary *)data;
NSString *str = [NSString stringWithFormat:@"用户名:%@ 姓名:%@",dict[@"userId"],dict[@"name"]];
[self renderButtons:str];
// responseCallback给js的回复
responseCallback(@"报告,oc已收到js的请求");
}];
}
***************************************** OC 调用 JS
-(void)OC2JS{
/*
含义:OC调用JS
@param callHandler 商定的事件名称,用来调用网页里面相应的事件实现
@param data id类型,相当于我们函数中的参数,向网页传递函数执行需要的参数
注意,这里callHandler分3种,根据需不需要传参数和需不需要后台返回执行结果来决定用哪个
*/
//---不带回调[_bridge callHandler:@"registerAction" data:@"我是oc请求js的参数"];
//带回调
[_bridge callHandler:@"registerAction" data:@"uid:123 pwd:123" responseCallback:^(id responseData) {
NSLog(@"oc请求js后接受的回调结果:%@",responseData);
}];
}
这篇关于iOS之JavaScript与OC的相互调用:WKwebview 的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!