您的位置:首页 > 移动开发 > IOS开发

iOS开发,javascript直接调用oc代码而非通过改变url回调方式

2016-06-19 22:23 756 查看
之前一个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,代码如下:

[objc] view
plain copy

 





//  

//  webview.m  

//  login  

//  

//  Created by wangdan on 15-3-19.  

//  Copyright (c) 2015年 wangdan. All rights reserved.  

//  

  

#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;  

}  

  

  

@end  

 
(1)在上述代码中,使用javascriptCore.framework,首先使用UIWebview加载一个静态网页,并
使用
JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
获取该UIWebview的javascript执行环境。
 
 
(2)在该javascript执行环境中,定义一个js函数,注意关键点来了
 
这个函数的执行体完全是 objective-c代码写的,也就是下面:

[objc] view
plain copy

 





context[@"jakilllog"] = ^() {  

  

        NSLog(@"Begin Log");  

        NSArray *args = [JSContext currentArguments];  

  

        for (JSValue *jsVal in args) {  

            NSLog(@"%@", jsVal);  

        }  

  

        JSValue *this = [JSContext currentThis];  

        NSLog(@"-------End Log-------");  

  

    };  

[objc] view
plain copy

 





   

[objc] view
plain copy

 





   

(3)试想一下,在定义的webview中,如果使用js执行log这个函数,那么会不会调用上面oc中block段代码呢,答案是肯定的!
下面看看UIWebView 中所加载的 html及其js代码是如何写的
(4)index.html代码
  

[html] view
plain copy

 





<!--//  Created by wangdan on 15-3-19.-->  

<!--//  Copyright (c) 2014年 wangdan. All rights reserved.-->  

  

<!DOCTYPE html>  

  

<html lang="en">  

      

    <head>  

          

         <meta charset="utf-8">  

              

          <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  

            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />      

                  

            <meta name="description" content="">  

                      

            <meta name="viewport" content="width=device-width; initial-scale=1.0">  

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

        

                          

      </head>  

      

    <button id="hallo" onclick="buttonClick()"> 点击button</button>  

  

    </body>  

      

</html>  



[html] view
plain copy

 





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

[html] view
plain copy

 





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

[html] view
plain copy

 





function buttonClick()  

{  

    jakilllog("hello world");  

}  


意思是点击这个button,就调用jakilllog()函数,jakilllog()函数显然是我们在oc中实现的一个block段,
就是上述绿色部分的block段。
 
点击button会执行么?答案是肯定的。
下面上图



 
下图是执行的结果



点击html中的button,能够执行oc中的代码
说明直接从js调用oc的意图达到。

最近有很多朋友问我索要demo那么我把demo的地址上传到csdn
大家下载下来就很方便了。
demo地址

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

原文地址:http://blog.csdn.net/j_akill/article/details/44463301
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息