iOS我爱编程

iOS 跟JS交互 loadRequest JS调用不到OC的解

2016-04-18  本文已影响896人  6129b93b59e2

目前客户端的展示方式有两种,一种是native(本地)一种是H5
这又涉及到了交互,交互有好多方式(我知道了只有3种,一种是截取URL也就是URL协议,另一种是双方定义伪协议,另一种是webJavaScriptBridge)

交互分几种需求

1.本地调用JS

    [self.ebyWeb stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"Action.Login('%@')",[KitTools DataTOjsonString:dic

![Upload 屏幕快照 2017-08-04 下午6.39.37.png failed. Please try again.]

![Upload 屏幕快照 2017-08-04 下午6.43.06.png failed. Please try again.]
]]];

2.JS调用本地

    JSContext *context = [self  valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
   context[@"fakeopen"] = ^ {
    NSString * title =  [self stringByEvaluatingJavaScriptFromString:@"document.title"];
    self.backBlock(20,title);
};

这里面有个坑, 例如你现在有这样的一个需求,JS加载完视图之后要修改你的返回事件,也就是你的leftBarButtonItem的Action 但是问题来了

当你的webview 页面加载出来的时候 JS调用了你,你能截取到,然后你他没有新推出视图,而是在本VC中的继续 loadRequest ,还是webView的视图加载完了 JS调用本地(你就截获不到了)卧槽,真他么的奇葩 不要问我为什么,我也不会。
解决方法

  - (void)webViewDidFinishLoad:(UIWebView *)webView;

这个方法中 写入调用js 的代码,这样做的目的是,既然我抓不到,我去获取下你要做什么,这时候就要js配合你了
js 代码

   function ReturnCoat(){
   if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){
        backAction('bridgeapi://more');
    }
    else{
        bridgeApi.backAction('bridgeapi://more');
    }  
}
ReturnCoat();  

ReturnCoat:(他是一个oc 要调用js 的一个函数)
backAction() 这个是js 调用oc 的函数(注意了,backAction 不能再JS中声明)
这样就解决了二次reloadRequest JS调用不到oc了

  1. URL 截取
  - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

{
    NSString *uRLString = [[request URL] absoluteString];

    if ([uRLString rangeOfString:@"login="].length) {
        
        self.backBlock(16,uRLString) ;
        return NO ;
    }
    return YES ;

}

2 webJavaScriptBridge

https://github.com/marcuswestin/WebViewJavascriptBridge

这里有中文教程

http://www.cocoachina.com/ios/20150629/12248.html

3定义伪协议
首先看一下这个js代码 js里面有按钮触发方法有ios.appContentImages
首先 appContentImages 是js里面的方法
ios你可以理解为web要监听的对象

屏幕快照 2017-08-04 下午6.39.37.png

在看 OC代码
首先系统有JSExport这个类


屏幕快照 2017-08-04 下午6.43.06.png

oc 里面 你需要实现这个方法

JSContext *jsContext = [self->web_ valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
__weak typeof (self) weakSelf = self;
jsContext[@"ios"] = weakSelf;

来解释下 为很么需要把

jsContext[@"ios"] = weakSelf;

来看这张图


屏幕快照 2017-08-04 下午6.49.53.png

此时的

   jsContext[@"ios"]   就等于  ViewController
屏幕快照 2017-08-04 下午6.51.04.png

然后写 协议 让 ViewController 遵循JSObjcDelegate

  @protocol JSObjcDelegate <JSExport>

  - (void)appContent:(NSString *)aa Images:(NSString *)message2 ;

  @end

你就会发现 此时就变成了

  [ViewController appContent:@"nihao"  Images:@['a','2']]

如果你认真看,你会发现 js里面定义的方法是 appContentImages 而你要写 - (void)appContent:(NSString *)aa Images:(NSString *)message2 ; 这个呢 ?

是因为你如果想用这种方式来跟js做多参数交互,需要把js的方法拆开.

上一篇下一篇

猜你喜欢

热点阅读