UIWebView中的JS和OC的互调
html的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<html> <head> <meta xmlns= "http://www.w3.org/1999/xhtml" http-equiv= "Content-Type" content= "text/html; charset=utf-8" /> <title>这是一个示例html文件</title> <script Type= 'text/javascript' > function clickme() { alert( '点击按钮了XXX!' ); } </script> </head> <body> <h1>欢迎欢迎!</h1> <!-- 自定义协议与OC进行交互,提示一定要有 /// --> <a href= "myfunc:///showMessage:/晚上请你吃饭:D" >你猜</a> <hr /> <a href= "http://m.baidu.com" >百度一下,你就知道!</a> </body> </html> |
1。OC中调用html的代码
要执行html中的js,需要加载完成网页之后再执行,
1
|
UIWebViewDelegate协议 |
1
2
3
4
5
6
7
8
9
|
@protocol UIWebViewDelegate <NSObject> @optional - ( BOOL )webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; - ( void )webViewDidStartLoad:(UIWebView *)webView; - ( void )webViewDidFinishLoad:(UIWebView *)webView; - ( void )webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error; @end |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
- ( void )viewDidLoad { [super viewDidLoad]; [self loadHTMLFile]; } - ( void )loadHTMLFile { NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@ "demo.html" withExtension:nil]; [self.webView loadRequest:[NSURLRequest requestWithURL:fileURL]]; } /** 要执行 html 中的 js,需要在加载完成之后再执行 stringByEvaluatingJavaScriptFromString 方法,是 WebView 中,唯一一个调用 js 的方法 - string 开头,返回 NSString* */ #pragma mark - UIWebViewDelegate - ( void )webViewDidFinishLoad:(UIWebView *)webView { // js的弹窗是阻塞式的! // [webView stringByEvaluatingJavaScriptFromString:@"clickme();"]; NSString *title = [webView stringByEvaluatingJavaScriptFromString:@ "document.title" ]; NSLog(@ "%@" , title); } |
1
2
3
4
5
6
7
8
|
/** 应用场景:QQ好友发送文件-直接浏览文件! */ - ( void )loadLocalFile { NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@ "iOS 7 Programming Cookbook.pdf" withExtension:nil]; [self.webView loadRequest:[NSURLRequest requestWithURL:fileURL]]; } |
2.HTML中调用OC的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
/** 提示:如果 OC 的代理方法要求返回 BOOL,程序直接返回 YES,通常一切正常,NO就是不工作! 参数 1. webView 2. request:加载页面的请求 3. navigationType: 浏览的类型,例如:在新窗口中打开链接 */ - ( BOOL )webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSLog(@ "%@" , request.URL.scheme); // 如果能够拦截到 myfunc:// 协议头,就可以知道是自定义协议调用 oc 方法 // scheme 协议头 if ([request.URL.scheme isEqualToString:@ "myfunc" ]) { NSLog(@ "自定义协议,准备调用 OC 的方法 %@" , request.URL); // 需要拦截方法名 & 参数 NSLog(@ "%@" , request.URL.pathComponents); // 1. 方法名 NSString *methodName = request.URL.pathComponents[1]; // 2. 参数 NSString *param = request.URL.pathComponents[2]; // 3. 调用方法 - SEL // UIButton *btn = nil; // [btn addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside]; SEL func = NSSelectorFromString(methodName); // 之所以会有警告,是因为苹果认为这种方式不安全! // 判断 self 是否响应方法 if ([self respondsToSelector:func]) { // clang 编译器 警告 压栈,保存当前编译状态 #pragma clang diagnostic push // 忽略 pefromSelector 的风险警告 #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [self performSelector:func withObject:param]; // 让编译器出栈,恢复之前保存的状态 #pragma clang diagnostic pop } else { NSLog(@ "方法名错误" ); } return NO; } return YES; } |
转自:http://my.oschina.net/u/1590735/blog/493722?fromerr=bS9RAInT