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

来源:互联网 发布:海康监控数据恢复 编辑:程序博客网 时间:2024/05/16 02:19

之前一个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 plaincopy在CODE上查看代码片派生到我的代码片
  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.     ifself ){  
  20.         self.webview=[[UIWebView alloc]initWithFrame:CGRectMake(0310self.bounds.size.width300)];  
  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  

 

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

使用

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

获取该UIWebview的javascript执行环境。

 

 

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

 

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

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  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.     };  
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1.    
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1.    

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

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

(4)index.html代码

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <!--//  Created by wangdan on 15-3-19.-->  
  2. <!--//  Copyright (c) 2014年 wangdan. All rights reserved.-->  
  3.   
  4. <!DOCTYPE html>  
  5.   
  6. <html lang="en">  
  7.       
  8.     <head>  
  9.           
  10.          <meta charset="utf-8">  
  11.               
  12.           <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  
  13.             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />      
  14.                   
  15.             <meta name="description" content="">  
  16.                       
  17.             <meta name="viewport" content="width=device-width; initial-scale=1.0">  
  18.              <script type="text/javascript" src="index.js"></script>             
  19.         
  20.                           
  21.       </head>  
  22.       
  23.     <button id="hallo" onclick="buttonClick()"> 点击button</button>  
  24.   
  25.     </body>  
  26.       
  27. </html>  

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 上面html定义了一个button,然后引用index.js,点击button的响应函数为buttonClick()  
[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 该函数在index.js中定义,如下  
[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. function buttonClick()  
  2. {  
  3.     jakilllog("hello world");  
  4. }  

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

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

 

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

下面上图

 

下图是执行的结果



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

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

0 0
原创粉丝点击