真的只需要5分钟,现在开始计时!
第1分钟
首先澄清一下标题:
- 标题中的JavaScript指:在html页面中嵌入的JS函数;
- 标题中的iOS指:在iOS App原生代码中编写的代码;
然后,了解一点基础知识,请记住以下两点:
- JSContext 这个对象是实现 JS 调用 iOS 的关键对象;
- JSContext 需要结合UIWebView使用,所以这篇教程仅包括使用UIWebView的场景;
第2分钟
记住以下两个相互调用方法:
- JS 调用 iOS
JSContext是实现JS调用OC的关键;
JSContext *content = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
content[@"call_iOS"] = ^() {
//在JS的函数中调用native中的call_iOS(虚拟出来的方法),在这里回调;重点看下js中的调用call_iOS的写法
};
- iOS调用JS
UIWebView的stringByEvaluatingJavaScriptFromString方法是实现iOS调用JS的关键,下面的例子将调用JS中的showTitleMessage方法,并传入一个参数
NSString *functionString = [NSString stringWithFormat:@"showTitleMessage('%@')",@"oc调用了js的内容"];
[self.webView stringByEvaluatingJavaScriptFromString:functionString];
第3分钟开始
Show Me The Code, 请用3分钟的时间阅读代码,理解一下;
test_1.html
<html>
<head>
<meta charset="UTF-8"/>
<title>iOS上webView与JS交互的之oc调用js的demo</title>
<script>
function show()
{
alert('js调用了oc的代码');
}
function showTitle()
{
alert(document.title);
}
function showTitleMessage(message)
{
alert(message);
}
function sum()
{
return 1 + 1;
}
function btnClick()
{
if (/android/i.test(navigator.userAgent)){
// todo : android
window.android.startFunction(share);
} else if (/ipad|iphone|iPod|iOS|mac/i.test(navigator.userAgent)){
// todo : ios call_iOS并不是iOS native中的真实的方法,而是与JSContext相关的一个block
call_iOS("hello world");
alert('js调用了oc的代码');
}
}
//IOS
function startFunction() {
if (/android/i.test(navigator.userAgent)){
// todo : android
window.android.startFunction("hello world");
} else if (/ipad|iphone|iPod|iOS|mac/i.test(navigator.userAgent)){
// todo : ios
test(share);
alert('js调用了oc的代码');
}
}
</script>
</head>
<!--网页具体内容-->
<body>
<br>下面是网页</br><br/>
<button style = "background: yellow; height: 150px; width: 350px;" onclick = "btnClick();">点击按钮js调用oc</button>
<br/><br/><br/><br/><br/>
<input type="button" value="Share" onClick="startFunction();">点击调用原生代码并传递参数</a>
</body>
</html>
ViewController.m
#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
@interface ViewController ()<UIWebViewDelegate>
@property (nonatomic) UIWebView *webView;
@property (nonnull,strong) UIButton *btn;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self makeWeb];
}
-(void)makeWeb
{
self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
self.webView.backgroundColor = [UIColor whiteColor];
self.webView.delegate = self;
[self.view addSubview:self.webView];
NSString *webPath = [[NSBundle mainBundle] pathForResource:@"test_1" ofType:@"html"];
NSURL *webURL = [NSURL fileURLWithPath:webPath];
NSURLRequest *URLRequest = [[NSURLRequest alloc] initWithURL:webURL];
[self.webView loadRequest:URLRequest];
/**
JS调用native
*/
JSContext *content = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
content[@"call_iOS"] = ^() {
NSLog(@"js调用oc---------begin--------");
NSArray *thisArr = [JSContext currentArguments];
for (JSValue *jsValue in thisArr) {
NSLog(@"=======%@",jsValue);
}
//JSValue *this = [JSContext currentThis];
//NSLog(@"this: %@",this);
NSLog(@"js调用oc---------The End-------");
};
content.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
//比如把js中的方法名改掉,OC找不到相应方法,这里就会打印异常信息
NSLog(@"异常信息:%@", exceptionValue);
};
content[@"test"] =^(id obj ,id obj1,id obj2){
//obj,obj1,obj2 这3个参数可以不写,也可以继续写obj3,obj4....
NSArray *thisArr = [JSContext currentArguments];
for (JSValue *jsValue in thisArr) {
NSLog(@"=======%@",jsValue);
}
};
/**
native 调用 JS
*/
UIButton *buttonCallJs = [UIButton buttonWithType:UIButtonTypeCustom];
buttonCallJs.frame = CGRectMake(10, self.view.bounds.size.height - 100,self.view.bounds.size.width-20, 40);
buttonCallJs.backgroundColor = [UIColor blackColor];
[buttonCallJs setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[buttonCallJs setTitle:@"native调用JS" forState:UIControlStateNormal];
[buttonCallJs addTarget:self action:@selector(callJS:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:buttonCallJs];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/**
navtive 调用 js的方法;
showTitleMessage 是js中的方法名称;
*/
- (void)callJS:(id)sender{
NSString *functionString = [NSString stringWithFormat:@"showTitleMessage('%@')",@"oc调用了js的内容"];
[self.webView stringByEvaluatingJavaScriptFromString:functionString];
}
@end
后记:WKWebView 是新一代的WebView,实现JS/iOS互相调用的方式与在UIWebView中的方式有所区别,注意区别;
网友评论