真的只需要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中的方式有所區別,注意區別;