之前一个ios项目中,需要通过UIWebview来打开一个静态页面,并在静态页面中
调用相关object-c代码。
一、以前使用js调用object-c的方法
关于如何使用javascript调用object-c中的函数和方法,我搜索了好久
网上所有的方法,基本都指明了一个方向,那就是在UIWebview中载入的js代码中
通过改变document.locations=“”,然后回调UIWebview的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
函数,在上面这个函数中,通过截取NSURLRequest解析js中传递过来的参数,再根据参数
来选择早已定义好的方法。
有没有别的方法呢? 我找了几个月,没找到!但是有一个转机。
我偶然知道了 javascriptCore.framework 这个库
于是事情有了转机。
二、在js中直接调用oc的方法
废话不多说,现在看看如何在UIWebView的javascript中调用oc的方法
首先在建立一个UIWebView,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 2 // webview.m 3 // login 4 // 5 // Created by wangdan on 15-3-19. 6 // Copyright (c) 2015年 wangdan. All rights reserved. 7 // 8 9 #import "webview.h" 10 #import <javascriptcore javascriptcore.h=""> 11 12 @implementation webview 13 14 15 -(id)initWithFrame:(CGRect)frame 16 { 17 self=[super initWithFrame:frame]; 18 19 if( self ){ 20 self.webview=[[UIWebView alloc]initWithFrame:CGRectMake(0, 310, self.bounds.size.width, 300)]; 21 self.webview.backgroundColor=[UIColor lightGrayColor]; 22 NSString *htmlPath=[[NSBundle mainBundle] resourcePath]; 23 htmlPath=[htmlPath stringByAppendingPathComponent:@"html/index.html"]; 24 NSURL *localURL=[[NSURL alloc]initFileURLWithPath:htmlPath]; 25 [self.webview loadRequest:[NSURLRequest requestWithURL:localURL]]; 26 [self addSubview:self.webview]; 27 28 JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; 29 context[@"log"] = ^() { 30 31 NSLog(@"+++++++Begin Log+++++++"); 32 NSArray *args = [JSContext currentArguments]; 33 34 for (JSValue *jsVal in args) { 35 NSLog(@"%@", jsVal); 36 } 37 38 JSValue *this = [JSContext currentThis]; 39 NSLog(@"this: %@",this); 40 NSLog(@"-------End Log-------"); 41 42 }; 43 44 45 // [context evaluateScript:@"log('ider', [7, 21], { hello:'world', js:100 });"]; 46 47 48 } 49 return self; 50 } 51 52 53 @end</javascriptcore>
(1)在上述代码中,使用javascriptCore.framework,首先使用UIWebview加载一个静态网页,并
使用
JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
获取该UIWebview的javascript执行环境。
(2)在该javascript执行环境中,定义一个js函数,注意关键点来了
这个函数的执行体完全是 objective-c代码写的,也就是下面:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 context[@"jakilllog"] = ^() { 2 3 NSLog(@"Begin Log"); 4 NSArray *args = [JSContext currentArguments]; 5 6 for (JSValue *jsVal in args) { 7 NSLog(@"%@", jsVal); 8 } 9 10 JSValue *this = [JSContext currentThis]; 11 NSLog(@"-------End Log-------"); 12 13 };
(3)试想一下,在定义的webview中,如果使用js执行log这个函数,那么会不会调用上面oc中block段代码呢,答案是肯定的!
下面看看UIWebView 中所加载的 html及其js代码是如何写的
(4)index.html代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!--// Created by wangdan on 15-3-19.--> <!--// Copyright (c) 2014年 wangdan. All rights reserved.--> <script type="text/javascript" src="index.js"></script>点击button
上面html定义了一个button,然后引用index.js,点击button的响应函数为buttonClick()
该函数在index.js中定义,如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 function buttonClick() 2 { 3 jakilllog("hello world"); 4 }
意思是点击这个button,就调用jakilllog()函数,jakilllog()函数显然是我们在oc中实现的一个block段,
就是上述绿色部分的block段。
点击button会执行么?答案是肯定的。
下面上图
下图是执行的结果
点击html中的button,能够执行oc中的代码
说明直接从js调用oc的意图达到。
转至:http://www.2cto.com/kf/201503/383795.html
这里还有几篇很详细的介绍: