iOS开发技术收集 -- 完整应用及开发技巧篇iOS点滴在iOS开发的道路上越走越远

关于UIWebView中OC与JavaScript交互

2015-10-26  本文已影响1763人  码痞

为什么要交互?

在实际项目中往往会使用到页面中内嵌wap页的情况,这样做能减少开发工作量,且只要修改wap页就能同步改变iOS端页面的内容,很方便。虽然iOS

实际工程中常希望在点击wap页面内容时不使用wap页本身的跳转,而是跳转到项目中的另一个页面,就需要在JS中调用iOS端中类似以下的方法进行跳转或执行一些其他操作

  [self.navigationController pushViewController:ViewController animated:YES];

有时也有可能通过iOS端的方法来调用JS中的方法来实现一些功能
所以就需要实现在JS和iOS端之间进行 交配 交互

在iOS8中新增的WKWebView框架带有Nitro JavaScript引擎,正在逐步取代WebView框架,为了向下适配iOS7的用户所以工程里还是用了UIWebView。


相关的iOS原生方法

1.UIWebView的代理方法
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;

在WebView中的wap页将要载入内容时得到通知触发,返回NO则阻止加载内容,


2.运用JavaScriptCore框架进行交互

 //获取当前的JS环境
 JSContext* context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//----------------------------------------------------------------------------------------------------------------
//用block定义要被JS调用的方法
NSNumber* (^do_something)(void) = ^(void){
    BOOL singleDog = [programmer isSingle];
    int someData = singleDog?1:-1; 
    return [NSNumber numberWithInt:someData];//数据类型应为Number,此时即为OC向JS传值
};
//在JS中添加了一个方法指针 do_something
context[@"do_something"] = do_something;

该方法常在以下UIWebView的代理方法中使用,在页面加载完毕时向JS中添加
- (void)webViewDidFinishLoad:(UIWebView *)webView

 [myWebView stringByEvaluatingJavaScriptFromString:@"JS中的方法"];

暂时不会写JS,具体例子请参考这里


第三方框架 WebViewJavascriptBridge

该框架的主要使用方法是在iOS端中先创建一个WebViewJavascriptBridge对象,并运用该对象实现交互

首先要在JS中添加如下方法

function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
    callback(WebViewJavascriptBridge)
} else {
    document.addEventListener('WebViewJavascriptBridgeReady', function() {
                              callback(WebViewJavascriptBridge)
                              }, false)       
}

 connectWebViewJavascriptBridge(function(bridge) {
 //注意,你的bridge函数都应写在这里面
 }

 //例如
function doSomething(){
connectWebViewJavascriptBridge(function(bridge) {
   bridge.init(function(message, yourCallback) {
      log('ObjC called testJavascriptHandler with', message)

       var responseData = { 'Javascript Says':'Right back atcha!' }
       log('JS responding with', responseData)
       responseCallback(responseData)
       })
    }
 }
OC调用JS方法

1.调用JS中bridge.init的方法

  //OC
  [_bridge send:@"The message sent from ObjC to JS" responseCallback:^(id response) {
    NSLog(@"sendMessage got response: %@", response);//这里的response是js方法中的data
}];


 //对应调用js中的方法
 bridge.init(function(message, yourCallback) {
    log('ObjC called testJavascriptHandler with', message)

    var responseData = { 'Javascript Says':'Right back atcha!' }
    log('JS responding with', responseData)
    responseCallback(responseData)
 })

2.调用JS中bridge.registerHandler方法,该方法可以注册方法名,通过注册名确认调用方法

 //OC
 [_bridge callHandler:@"注册名" data:data responseCallback:^(id response) {
    NSLog(@"testJavascriptHandler responded: %@", response);
}];

 //对应调用的js中的方法
 bridge.registerHandler('注册名', function(data, responseCallback) {
        log('ObjC called testJavascriptHandler with', data)

        var responseData = { 'Javascript Says':'Right back atcha!' }
        log('JS responding with', responseData)
        responseCallback(responseData)
    })
JS端调用OC端方法

1.调用OC中创建bridge对象时定义时的方法

 //JS中
   bridge.send(data,function(response){
     log('这里是回调方法',response) //回调方法
   })



//对应调用的OC中bridge初始化中设置的block方法
_bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {
    //do something...        
    NSLog(@"ObjC received message from JS: %@", data);//从js获得的参数
    responseCallback(@"Response");//Response to js
}];

2.通过方法名调用OC中bridge的注册方法

 //JS中
 bridge.callHandler('注册名', {'foo': 'bar'}, function(response) {
     log('JS got response', response)
 })

 //对应调用的OC中的bridge注册的方法
[_bridge registerHandler:@"注册名" handler:^(id data, WVJBResponseCallback responseCallback) {
    NSLog(@"testObjcCallback called: %@", data);//从js获取的参数

    responseCallback(@"Response");//
}];

参考资料:
WebViewJavascriptBridge源码分析
UIWebView与JS的深度交互

上一篇下一篇

猜你喜欢

热点阅读