iOS 跟JS交互 loadRequest JS调用不到OC的解
目前客户端的展示方式有两种,一种是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了
- 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要监听的对象
在看 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的方法拆开.