频道栏目
首页 > 资讯 > 其他 > 正文

OC与JS交互方法(一)拦截URL

17-04-27        来源:[db:作者]  
收藏   我要投稿

原理:利用webview的代理方法(shouldStartLoadWithRequest),拦截即将加载的URL,再通过scheme区分点击事件类型。

先看看html页面的JS代码

function loadURL(url) {

var iFrame;

iFrame = document.createElement("iframe");

iFrame.setAttribute("src", url);

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;

}

function scanClick() {

alert(arr);

//页面响应点击事件后使用iFrame的scr加载url,会被uiwebview的代理方法拦截

loadURL("haleyAction://scanClick");

}

function shareClick() {

loadURL("haleyAction://shareClick?title=测试分享的标题&content=测试分享的内容&url=http://www.baidu.com");

}

function locationClick() {

loadURL("haleyAction://getLocation");

}

function setLocation(location) {

//stringByEvaluatingJavaScriptFromString是一个同步方法,会等待js 方法执行完成,而弹出的alert 也会阻塞界面等待用户响应,所以他们可能会造成死锁。导致alert 卡死界面。如果回调的JS 是一个耗时的操作,那么建议将耗时的操作也放入setTimeout的function 中

asyncAlert(location);

document.getElementById("returnValue").value = location;

}

function asyncAlert(content) {

setTimeout(function(){

alert(content);

},1);

}

JS搞定了,那么下一步就是OC的操作了

主要用到-stringByEvaluatingJavaScriptFromString和webview的代理方法:-shouldStartLoadWithRequest

-stringByEvaluatingJavaScriptFromString——这个方法传入的就是JavaScript代码,直接在UIWebView上面执行js方法。

WKWebview中拦截URL的方法

与uiwebview不同之处:

初始化多了个configuration参数。 WKWebView的代理有两个navigationDelegate和UIDelegate。我们要拦截URL,就要通过navigationDelegate的一个代理方法来实现。如果在HTML中要使用alert等弹窗,就必须得实现UIDelegate的相应代理方法。 WKWebView的代理有两个navigationDelegate和UIDelegate。我们要拦截URL,就要通过navigationDelegate的一个代理方法来实现。如果在HTML中要使用alert等弹窗,就必须得实现UIDelegate的相应代理方法

初始化wkwebview方法

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];

configuration.userContentController = [WKUserContentController new];

WKPreferences *preferences = [WKPreferences new];

preferences.javaScriptCanOpenWindowsAutomatically = YES;

preferences.minimumFontSize = 30.0;

configuration.preferences = preferences;

self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];

NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];

NSURL *fileURL = [NSURL fileURLWithPath:urlStr];

[self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];

self.webView.navigationDelegate = self;

[self.view addSubview:self.webView];

拦截URL

使用WKNavigationDelegate中的代理方法,拦截自定义的URL来实现JS调用OC方法:

#pragma mark - WKNavigationDelegate

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler//如果实现了这个代理方法,就必须得调用decisionHandler这个block

{

NSURL *URL = navigationAction.request.URL;

NSString *scheme = [URL scheme];

//uiwebview和wk都需要统一的scheme;

if ([scheme isEqualToString:@"scheme"]) {

[self handleCustomAction:URL];

//WKNavigationActionPolicyCancel代表取消加载等于是return NO;

decisionHandler(WKNavigationActionPolicyCancel);

return;

}

//WKNavigationActionPolicyAllow代表允许加载;

decisionHandler(WKNavigationActionPolicyAllow);

}

调用JS:

WKWebView 提供了一个新的方法evaluateJavaScript:completionHandler:,实现OC 调用JS 等场景。功能与stringByEvaluatingJavaScriptFromString类似。

WKWebView中使用alert:

在上面提到,如果在WKWebView中使用alert、confirm 等弹窗,就得实现WKWebView的WKUIDelegate中相应的代理方法。

例如,我在JS中要显示alert 弹窗,就必须实现如下代理方法,否则alert 并不会弹出。

pragma mark - WKUIDelegate

(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler

{

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:message preferredStyle:UIAlertControllerStyleAlert];

[alert addAction:[UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

//这个block 一定得调用,至于在哪里调用,倒是无所谓,我们也可以写在方法实现的第一行,或者最后一行

completionHandler();

}]];

[self presentViewController:alert animated:YES completion:nil];

}

 

相关TAG标签
上一篇:Android查看某个App功能是Native实现还是Webview实现
下一篇:AndroidStudio 编译C/C++文件生成SO文件
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站