之前一个ios项目中,需要通过UIWebview来打开一个静态页面,并在静态页面中

调用相关object-c代码。

 

一、以前使用js调用object-c的方法

关于如何使用javascript调用object-c中的函数和方法,我搜索了好久

网上所有的方法,基本都指明了一个方向,那就是在UIWebview中载入的js代码中

通过改变document.locations=“”,然后回调UIWebview的

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

函数,在上面这个函数中,通过截取NSURLRequest解析js中传递过来的参数,再根据参数

来选择早已定义好的方法。

有没有别的方法呢? 我找了几个月,没找到!但是有一个转机。

 

我偶然知道了 javascriptCore.framework 这个库

于是事情有了转机。

 

二、在js中直接调用oc的方法

 

废话不多说,现在看看如何在UIWebView的javascript中调用oc的方法

 

 

首先在建立一个UIWebView,代码如下:

#import "webview.h"
#import <javascriptcore javascriptcore.h="">
 
@implementation webview
 
 
-(id)initWithFrame:(CGRect)frame
{
    self=[super initWithFrame:frame];
     
    if( self ){
        self.webview=[[UIWebView alloc]initWithFrame:CGRectMake(0, 310, self.bounds.size.width, 300)];
        self.webview.backgroundColor=[UIColor lightGrayColor];
        NSString *htmlPath=[[NSBundle mainBundle] resourcePath];
        htmlPath=[htmlPath stringByAppendingPathComponent:@"html/index.html"];
        NSURL *localURL=[[NSURL alloc]initFileURLWithPath:htmlPath];
        [self.webview loadRequest:[NSURLRequest requestWithURL:localURL]];
        [self addSubview:self.webview];
 
         JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
         context[@"log"] = ^() {
 
            NSLog(@"+++++++Begin Log+++++++");
            NSArray *args = [JSContext currentArguments];
 
            for (JSValue *jsVal in args) {
                NSLog(@"%@", jsVal);
            }
 
            JSValue *this = [JSContext currentThis];
            NSLog(@"this: %@",this);
            NSLog(@"-------End Log-------");
 
        };
         
 
//        [context evaluateScript:@"log('ider', [7, 21], { hello:'world', js:100 });"];
 
         
    }
    return self;
}

(1)在上述代码中,使用javascriptCore.framework,首先使用UIWebview加载一个静态网页,并

使用

JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

获取该UIWebview的javascript执行环境。

 

 

(2)在该javascript执行环境中,定义一个js函数,注意关键点来了

 

这个函数的执行体完全是 objective-c代码写的,也就是下面:

context[@"jakilllog"] = ^() {
 
        NSLog(@"Begin Log");
        NSArray *args = [JSContext currentArguments];
 
        for (JSValue *jsVal in args) {
            NSLog(@"%@", jsVal);
        }
 
        JSValue *this = [JSContext currentThis];
        NSLog(@"-------End Log-------");
 
    };



(3)试想一下,在定义的webview中,如果使用js执行log这个函数,那么会不会调用上面oc中block段代码呢,答案是肯定的!

下面看看UIWebView 中所加载的 html及其js代码是如何写的

(4)index.html代码

<script type="text/javascript" src="index.js"></script>  点击button

上面html定义了一个button,然后引用index.js,点击button的响应函数为buttonClick()

该函数在index.js中定义,如下

function buttonClick()
{
    jakilllog("hello world");
}



意思是点击这个button,就调用jakilllog()函数,jakilllog()函数显然是我们在oc中实现的一个block段,

就是上述绿色部分的block段。

 

点击button会执行么?答案是肯定的。

下面上图


前端通过一个完整URL调用java下载pdf文件 js调用url_html



下面是执行的结果


前端通过一个完整URL调用java下载pdf文件 js调用url_iOS_02

点击html中的button,能够执行oc中的代码

说明直接从js调用oc的意图达到。