Hybrid项目—–UIWebView和JS交互

前言

如果需要WKWebView的JS交互描述,请查看本站的另一个文章:

hybrid项目—–WKWebView和JS交互

本文主要记录一下UIWebView和JavaScript之间的交互!!由于iOS8之后,苹果推出了性能更加好的WKWebView,而WKWebView的交互与UIWebView的交互基本不一样!所以站长没有专注详细记录实现过程,只为项目经验及其他已经写好的博客做一个记录!!记录一下自己的认识!!

本文的内容来自:http://www.jianshu.com/p/dbddfc0eaa26

本文的学习过程

1.OC与JS间的直接交互方式!!

2.OC与JS间JavaScriptCore.framework来做交互!!(推荐)

1.OC与JS间的直接交互方式

直接调用,优势就是直接!适用于交互只有一两次的场景使用!!不需要导入框架!只要和H5前端规定好方法名和JS调用的URL名字就可以完成交互!!!

JS调用oc

(不知道Html和JS具体什么情况的同学,找前端过来看看,哈!)

js标签内添加跳转方法,然后在对应的触发位置(例如button)触发此方法。

function firstClick(){
            window.location.href="lalalala://shareClick";
            
        }

js会在UIWebview进行请求加载,这个时候,我们可以使用协议方法进行拦截,拦截后,使用响应的参数和约定的方法名来调用OC的代码!

oc 调用js

oc触发的代码如下:

NSString *textJS = @"showAlert('这里是JS中alert弹出的message 第一种方式')";
[_webView stringByEvaluatingJavaScriptFromString:textJS];

JS端应该写好这个showAlert的方法,如:

function showAlert(message){
         alert(message);
}

OC注入js方法:

//注入方法
    NSString *jsfunction = @"function uiwebviewt(){alert(2);}";
     [webView stringByEvaluatingJavaScriptFromString:jsfunction];

OC注入js对象:

NSString *jsobj = @"var testobjui = {'info':function(){alert('testobjui');}}";
[webView stringByEvaluatingJavaScriptFromString:jsobj];

到这里,直接调用就已经实现了。。。。

 

2.OC与JS间JavaScriptCore.framework来做交互!!(推荐)

我们实际应用的时候,其实会比直接调用的场景复杂得多!!除了互相调用写好的方法,有时候我们需要注入一些方法或者对象!!这个时候,我们需要用到iOS7.0公布使用的JavaScriptCore.framework。

这个框架有两个优势:

1.可以给js直观地植入方法或对象(推荐注入一个对象,对象有属性和方法);

2.编程被对象化。

JS调用OC

核心步骤:

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

这句代码是捕捉到当前webView的上下文,可以想象是html的script便签内环境!!!

使用前,要给项目导入JavaScriptCore.framework库。

web中的js方法

这个JS只是写了secondClick方法,但是,你要注意到,它并没有share方法,而这个share方法就需要我们OC注入进去。

注入前,先介绍几个javascriptcroe重要的类和一个重要的协议(不遵循这个协议,方法不会暴露在JS的context里

JSContext

JS执行的环境,同时也通过JSVirtualMachine管理着所有对象的生命周期,每个JSValue都和JSContext相关联并且强引用context。

JSValue

JS对象在JSVirtualMachine中的一个强引用,其实就是Hybird对象。我们对JS的操作都是通过它。并且每个JSValue都是强引用一个context。同时,OC和JS对象之间的转换也是通过它,相应的类型转换如下:

Objective-C type  |   JavaScript type
 --------------------+---------------------
         nil         |     undefined
        NSNull       |        null
       NSString      |       string
       NSNumber      |   number, boolean
     NSDictionary    |   Object object
       NSArray       |    Array object
        NSDate       |     Date object
       NSBlock (1)   |   Function object (1)
          id (2)     |   Wrapper object (2)
        Class (3)    | Constructor object (3)

JSExport(协议)

如果JS对象想直接调用OC对象里面的方法和属性,那么这个OC对象只要实现这个JSExport协议就可以了。

现在我们来实现OC通过javascriptcore注入JS方法

这个图里,有两步是比较重要的!!

1.获取context,这个是固定的写法!记着就好了!

2.给context的一个键添加一个block,这个block就是你注入的方法,这个键就是你的方法名!

通过JScontext直接调用share方法,从JSValue中取值

 

oc 调用js(调用web已写好的showAlert方法)

JSContext *context = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
 //oc 调用 js
 NSString *textJS = @"showAlert('这里是JS中alert弹出的message')";
[context evaluateScript:textJS];

下面,我们来使用更规范地交互:(核心:JSExport)
上面是方法的直接注入和直接调用,下面我们来通过注入对像 和 调用对象方法

凡是添加了JSExport协议的协议,所规定的方法,变量等 就会对js开放,我们可以通过js调用到

首先在html中创建对象,定义方法

在JS代码里,使用了一个叫TestJSobject的对象, 这个对象有三个方法。

无参方法
 TestJSobject.TestNOParameter();
 有一个参数的方法
 TestJSobject.TestOneParameter(TestJSobject.name);
  有两个参数的方法          
TestJSobject.TestTwoParameterSecondParameter(TestJSobject.name,TestJSobject.age);

现在,我们一步步给JS添加这个对象

1.创建OC类,添加协议,实现协议方法

注意,这里写了一个协议,这个协议必须要继承JSExport,协议的方法会在web的context里面暴露出来!!!

实现协议的方法

2.获取JScontext,注入对象多JSContext,供前端调用

在UIWebView的协议方法 -(void)webViewDidFinishLoad:(UIWebView*)webView 添加以下的代码!!

//js对象调用,创建对象
JSContext *context = [webView    valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
TestJSobject *test = [TestJSobject new];
 context[@"TestJSobject"] = test;

到这里,我们已经成功注入了对像!!!

OC调用JS

 //同样我们也用刚才的方式模拟一下js调用方法
 NSString *jsStr1=@"TestJSobject.TestNOParameter()";
[context evaluateScript:jsStr1];

 

总结

上面讲述了在使用UIWebView时两种JS和OC的交互。1.直接交互!2.通过JavaScriptCore做交互!站长推荐使用第二种方式,更加方便,更加符合我们面向对象的设计思维!!

 

 

发表评论

邮箱地址不会被公开。 必填项已用*标注