- OC 調(diào)用 JS
- JS 調(diào)用OC
預備工作
首先要 導入 JavaScriptCore.framework 這個庫,然后用來的類 分別是 JSContext , JSValue , JSExport 。再來一個 test.html 部分代碼
<a href="#" id="test">JS call OC</a>
<style>
a {
display: block;
width: 100px;
height: 50px;
text-align: center;
background: red;
color: #fff;
line-height: 50px;
text-decoration: none;
}
</style>
<script>
document.getElementById('test').onclick = function(){
//這個方法是 用來 測試 JS調(diào)用 OC 的
// IOS_Obj 是什么來的奥帘?what ?
//不要急胸墙,搜索復制粘貼看看细卧,這個類我放在下面也貼出來了
var a = IOS_Obj.getUser();
alert(a);
}
function ocCallJS()
{
alert('OC Call JS');
}
function ocCallJSWithArg(a,b)
{
alert('a:'+ a +' '+'b:'+b);
}
- 有了 html 蚊锹,那么我們 還需要一個 UIWebView
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, self.view.frame.size.height)];
_webView.delegate = self;
[self.view addSubview:_webView];
- 然后加載上這個html
這個html 是放在項目里面 的 也可以是 放在服務器 然后讀取
放在項目里面的讀取方式
NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];
NSString *html = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[_webView loadHTMLString:html baseURL:baseURL];
讀取一個URL 是 這樣讀的
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"你的html 所在的URL"]]];
- 說說這個JSContext 是怎樣獲取的
self.context = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
[JSContext currentContext].exception = exception;
NSLog(@"exception:%@",exception);
};
self.obj = [[IOS_Obj alloc] init];
self.context[@"IOS_Obj"] = self.obj;
//self.context[@"這個值可以自由定義咧虎,自定好了告訴JS 就好"]
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
//為什么這里也要寫一個呢秒咨?
//因為當跳轉到另外一個html 的時候 self.context 里面的對象被清空了
self.context[@"IOS_Obj"] = self.obj;
}
- 再準備兩個按鈕 用來測試
UIButton *firstBtn = [UIButton buttonWithType:UIButtonTypeCustom];
firstBtn.frame = CGRectMake(20, 20, 100, 30);
firstBtn.backgroundColor = [UIColor purpleColor];
[firstBtn addTarget:self action:@selector(firstBtnAction) forControlEvents:UIControlEventTouchUpInside];
[firstBtn setTitle:@"OC Call JS" forState:UIControlStateNormal];
firstBtn.titleLabel.font = [UIFont systemFontOfSize:10];
[self.view addSubview:firstBtn];
UIButton *secondBtn = [UIButton buttonWithType:UIButtonTypeCustom];
secondBtn.frame = CGRectMake(CGRectGetMaxX(firstBtn.frame) + 30, 20, 150, 30);
secondBtn.backgroundColor = [UIColor purpleColor];
[secondBtn addTarget:self action:@selector(secondBtnAciton) forControlEvents:UIControlEventTouchUpInside];
[secondBtn setTitle:@"OC Call JS With Arg" forState:UIControlStateNormal];
secondBtn.titleLabel.font = [UIFont systemFontOfSize:10];
[self.view addSubview:secondBtn];
- JS 調(diào)用OC 還要準備一個類喇辽,一個實現(xiàn)了JSExport 協(xié)議的類
h文件
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
@protocol JSExportForIOS <JSExport>
-(NSString *)getUser;
@end
@interface IOS_Obj : NSObject<JSExportForIOS>
@end
m文件
@implementation IOS_Obj
//請頭回看看上面的 html 里面的代碼
-(NSString *)getUser
{
return @"hello xixi";
}
@end
- 最后看看 之前的Button 里面寫了啥東西
這里面我寫了兩種調(diào)用 OC 調(diào)用JS 的方法,親測有效
-(void) firstBtnAction
{
//方法一
// JSValue *function = [self.context objectForKeyedSubscript:@"ocCallJS"];
// JSValue *result = [function callWithArguments:nil];
//方法二
NSString *alertJS = @"ocCallJS()";
[self.context evaluateScript:alertJS];
}
-(void) secondBtnAciton
{
//方法一
// JSValue *function = [self.context objectForKeyedSubscript:@"ocCallJSWithArg"];
// JSValue *result = [function callWithArguments:[NSArray arrayWithObjects:@"one Arg",@"two Arg", nil]];
//方法二
NSString *alertJS = @"ocCallJSWithArg('one Arg','two Arg')";
[self.context evaluateScript:alertJS];
}
-
最后有圖有真相
js_call_oc
JS_CALL_OC.png
oc_call_js
OC_CALL_JS.png
oc_call_js_with_arg
OC_CALL_JS_with_arg.png
PS: JS調(diào)用OC 的方法: 有時候在加載了html 渲染之后 才能觸發(fā)UIWebView 的 -(void)webViewDidFinishLoad:(UIWebView *)webView 的代理方法雨席,然而我要在這個代理方法里面 設置 JSContext 菩咨,那也只能讓JS 在unload 做一下 延遲100毫秒左右就好。