iOS原生应用与Web页面元素交互方式有很多,JavaScriptCore、拦截协议、第三方框架WebViewJavaScriptBridge、iOS8之后的WKWebView等;
简要记录下之前开发用到的两种方式:
- 拦截页面加载,从 UIWebVIew 的 shouldStartLoadWithRequest 方法中拦截RequestURL 判断加载项,代码简要:
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *urlStr = [[request URL] absoluteString];
// 加载的url 关键词需要同后台约定
NSRange range_keyWord = [urlStr rangeOfString:@"opengood://"];
if (range_keyWord.length > 0) {
[self doSomeThing];
}
return YES;
}
- iOS7之后推出的 JavaScriptCore 框架,交互起来hin方便
需要注意的是JS调用的方法名等需要同前端的同事沟通好,最好由前端提供给你。
浅显的说,这个方式等同于将当前ViewController 注入到web的context中,不同webClick都能够有不同的JS方法与VC上面的代理方法相对应,
例:
Web端
javaScript控件的点击事件约定触发 ‘task.openNewWeb(‘urlStr’)’
“task”这个东西在web源码中并没有什么实际意义 它只相当于iOS端的某个viewController的占位符号
iOS端代码:
#import <JavaScriptCore/JavaScriptCore.h>
UIWebView 代理方法中将当前控制器动态注入js中
- (void)webViewDidStartLoad:(UIWebView *)webView {
//首先创建JSContext 对象(此处通过当前webView的键获取到jscontext)
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 控制器self 填充web中预留的占位符‘task’
self.context[@"task"] = self;
// 这时候javaScript控件的点击事件约定触发 'task.openNewWeb('urlStr')'
// 那么在OC语法中相当于 [self openNewWeb:urlStr];
self.context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"异常信息:%@", exceptionValue);
};
}