1、提要
在项目开发中,使用H5与原生控件交互已成为一种趋势,iOS中常用UIWebView
和WKWebView
加载网页,截获JS并调用原生方法有多种方式,本文介绍我用到的一种。
2、WKWebView代理方法
WKWebView
中可以用如下的代理方法截获request
:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
2.1 前提
要截取有效的request
需与后台约定,一般可以用以下方式:
// JS端定义:
window.location = 'iOSApp://login?account=Admin&password=test';
2.2 拦截JS
// iOS端在代理方法中拦截并取出协议头
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
NSString *scheme = request.URL.scheme;
if ([scheme isEqualToString:@"iOSApp"]) {
// 可使用以下方式取出需要截取的参数或值
NSString * passwordStr = request.URL.absoluteString;
NSRange range = [passwordStr rangeOfString:@"password ="]; // 得到Range
passwordStr = [passwordStr substringFromIndex:(range.location + range.length)]; // 截取范围内的字符串,当然,用这种方式只能是取得在URL最后的值,如果本例中要取得`account `,则需要再判断长度
if (passwordStr.length) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"原生弹窗-密码" message:passwordStr delegate:nil cancelButtonTitle:@"好" otherButtonTitles:nil, nil];
[alert show];
}
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
3、注意
如果在WKWebView
中添加了移除观察者或销毁代理的操作,那么最好是写在dealloc
方法里,防止控制器跳转后代理方法失效,以致pop
后调用不到decidePolicyForNavigationAction
-(void)dealloc{
[self.wkWebView setNavigationDelegate:nil];
[self.wkWebView setUIDelegate:nil];
}