OC与JS互相调用
近期项目中要用到html5来实现。涉及到OC调用JS,以及JS调用OC的方法。这里把遇到的问题以及实现方法介绍一下。
// // ViewController.h // OC_And_JS // // Created by 张杰 on 15/7/9. // Copyright © 2015年 张杰. All rights reserved. // #import <UIKit/UIKit.h> @interface ViewController : UIViewController <UIWebViewDelegate> @property (weak, nonatomic) IBOutlet UIButton *oc_call_js_no_params; @property (weak, nonatomic) IBOutlet UIButton *oc_call_js_has_params; @property (weak, nonatomic) IBOutlet UIWebView *mWebView; @property (weak, nonatomic) IBOutlet UILabel *js_call_oc_show; - (IBAction)ocCallJsNoParams:(id)sender; - (IBAction)ocCallJsHasParams:(id)sender; @end
// // ViewController.m // OC_And_JS // // Created by 张杰 on 15/7/9. // Copyright © 2015年 张杰. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _mWebView.delegate = self; //打开URL NSString *path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; [self.mWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath: path]]]; } - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ NSString *urlstr = request.URL.absoluteString; NSRange range = [urlstr rangeOfString:@"ios://jwzhangjie"]; if (range.length!=0) { _js_call_oc_show.text = [NSString stringWithFormat:@"请訪问地址:%@", urlstr]; } return YES; } -(void)webView:(nonnull UIWebView *)webView didFailLoadWithError:(nullable NSError *)error{ NSLog(@"载入失败"); } -(void)webViewDidStartLoad:(nonnull UIWebView *)webView{ NSLog(@"開始载入"); } -(void)webViewDidFinishLoad:(nonnull UIWebView *)webView{ NSLog(@"開始结束"); // 对于调用js的时候最好这种方法里面或者之后 } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)ocCallJsNoParams:(id)sender { NSString *js = [NSString stringWithFormat:@"ocCallJsNoParamsFunction();"]; [self.mWebView stringByEvaluatingJavaScriptFromString:js]; } - (IBAction)ocCallJsHasParams:(id)sender { NSString *js = [NSString stringWithFormat:@"ocCallJsHasParamsFunction('%@','%@');",@"jwzhangjie",@"http://jwzhangjie.cn"]; [self.mWebView stringByEvaluatingJavaScriptFromString:js]; } @end
function ocCallJsNoParamsFunction() { alert("OC调用JS中的无參方法"); var e = document.getElementById("js_shouw_text"); e.options.add(new Option("OC调用JS中的无參方法", 2)); } function ocCallJsHasParamsFunction(name, url) { alert(name+"的博客地址为:"+url); var e = document.getElementById("js_shouw_text"); e.options.add(new Option("OC调用JS中的有參方法", 2)); }
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>OC与JS互相调用</title> </head> <body> <div > <select id="js_shouw_text"> <option> 展示OC调用JS无參数 </option> </select> </div> <div> <BR/> <input type="button" value="JS调用OC方法" onclick="js_call_oc()"/> </div> <!-- 这里要清楚,尽管test.js跟index.html不同及文件夹,实际安装到程序里面后。是在同级文件夹的,所以这里src不能加文件夹,相同css也是一样的 --> <script type="text/javascript" src="test.js" charset="UTF-8"></script> <script type="text/javascript"> function js_call_oc() { var iFrame; iFrame = document.createElement("iframe"); iFrame.setAttribute("src", "ios://jwzhangjie"); iFrame.setAttribute("style", "display:none;"); iFrame.setAttribute("height", "0px"); iFrame.setAttribute("width", "0px"); iFrame.setAttribute("frameborder", "0"); document.body.appendChild(iFrame); // 发起请求后这个iFrame就没用了,所以把它从dom上移除掉 iFrame.parentNode.removeChild(iFrame); iFrame = null; } </script> </body> </html>
规避1:对于OC去调用JS内容最好在webViewDidFinishLoad方法里或者之后
规避2:在html里面引用js或者css的时候src不要带有路径,由于安装后文件都在同级文件夹以下
规避3:OC调用JS的规范
NSString *js = [NSString stringWithFormat:@"ocCallJsHasParamsFunction('%@','%@');",@"jwzhangjie",@"http://jwzhangjie.cn"]; [self.mWebView stringByEvaluatingJavaScriptFromString:js];规避4:JS调用OC。这里通过html里面发送一个请求,然后在ios中使用shouldStartLoadWithRequest拦截请求。依据请求url的不同进行处理。
function js_call_oc() { var iFrame; iFrame = document.createElement("iframe"); iFrame.setAttribute("src", "ios://jwzhangjie"); iFrame.setAttribute("style", "display:none;"); iFrame.setAttribute("height", "0px"); iFrame.setAttribute("width", "0px"); iFrame.setAttribute("frameborder", "0"); document.body.appendChild(iFrame); // 发起请求后这个iFrame就没用了。所以把它从dom上移除掉 iFrame.parentNode.removeChild(iFrame); iFrame = null; }
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ NSString *urlstr = request.URL.absoluteString; NSRange range = [urlstr rangeOfString:@"ios://jwzhangjie"]; if (range.length!=0) { _js_call_oc_show.text = [NSString stringWithFormat:@"请訪问地址:%@", urlstr]; } return YES; }
源代码地址:
http://jwzhangjie.cn/forum.php?mod=viewthread&tid=3&page=1&extra=#pid3