在工作中会遇到web页面和iOS原生应用的交互问题,通常会选择用JavaScriptCore,拦截或者WebViewJavaScriptBridge框架来解决,今天只说说JavaScriptCore。
1.web端代码如下
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="margin-top: 100px">
<h1>native与JavaScript交互</h1>
</div>
<div>
<!-- 登录 -->
<input type="button" value="login" onclick="gotoLogin()">
</div>
<div>
<!-- 选择相册 -->
<input type="button" value="CallCamera" onclick="XCS.callCamera(method='imageCallback')">
</div>
<div>
<!-- 拦截 -->
<input type="button" value="Alert" onclick="showAlert()">
</div>
<script type="text/javascript">
// 登录
function gotoLogin(){
var userInfo = JSON.stringify({
"userName": "18099990000",
"password": "123456"
})
XCS.gotoLoginCallback(userInfo,'loginCallback')
}
// 登录结果回调
function loginCallback(result){
alert(result)
}
// 选择图片回调
function imageCallback(images) {
alert(images);
}
// 弹框
function showAlert(){
XCS.showAlertCallback('title','message')
}
function message(){
alert('success')
}
</script>
</body>
</html>
2.通过注入模型的方式交互
定义一个遵守JSExport协议的协议,定义一个模型
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <JavaScriptCore/JavaScriptCore.h>
// JSExport是一个协议
@protocol JSObjDelegate <JSExport>
// 登录
- (void)gotoLogin:(NSString *)userInfo callback:(NSString *)name;
// 调相册
- (void)callCamera:(NSString *)callback;
// 弹框
- (void)showAlert:(NSString *)title callback:(NSString *)name;
@end
NS_ASSUME_NONNULL_BEGIN
@interface JSBridgeModel : NSObject<JSObjDelegate>
// JS执行上下文
@property (nonatomic, weak) JSContext *jsContext;
@property (nonatomic, weak) UIWebView *webView;
@end
NS_ASSUME_NONNULL_END
实现协议方法
#import "JSBridgeModel.h"
@implementation JSBridgeModel
- (void)gotoLogin:(NSString *)userInfo callback:(NSString *)name{
// 。。。 处理相应的事件,然后回调
[self jsCallbackWithMethod:name argument:@[@"hello"]];
}
- (void)callCamera:(NSString *)callback{
// 。。。 处理相应的事件,然后回调
[self jsCallbackWithMethod:callback argument:@[@"image"]];
}
- (void)showAlert:(NSString *)title callback:(NSString *)name{
// 。。。 处理相应的事件,然后回调
[self jsCallbackWithMethod:name argument:@[]];
}
// 回调
- (void)jsCallbackWithMethod:(NSString *)methodName argument:(NSArray *)arguments{
JSValue *callback = self.jsContext[methodName];
[callback callWithArguments:arguments];
}
@end
3.ViewController中在webview加载完成的代理中,给JS注入模型
-(void)webViewDidFinishLoad:(UIWebView *)webView{
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
JSBridgeModel *jbModel = [[JSBridgeModel alloc] init];
self.jsContext[@"XCS"] = jbModel;
jbModel.jsContext = self.jsContext;
jbModel.webView = self.webView;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"error:%@", exceptionValue);
};
}
网友评论