iOS原生与VUE的交互

iOS原生调用VUE页面相互传值

最近公司的项目涉及到了混合开发,需要用VUE写一部分界面,为了更好的交互体验页面的转跳还是用的原生的导航,这就需要本地和JS的数据交互.

一.VUE部分

(关于VUE环境的相关配置请移步至VUE搭建)
本地测试:将VUE的项目运行(npm run dev)起来之后其实就是生成的一个网址,IP就是自己电脑的IP,根据设定好的端口就可以在手机端访问了.
简单的介绍一下VUE的页面实现(VUE的知识自己刚开始学的有错误的地方还请指出QQ:836825312)一个页面基本上是有三部分组成:
1.html 这部分主要是负责显示控件就是那个lablel啊button这些.
2.CSS 这部分主要是负责控制这些控件的样式,如果设置一下字体的颜色、大小.
3.JS 这部分主要负责实现数据交互.

二.APP部分

因为现在基本上都用WKWebview所以这里接不介绍UIWebView的使用方法了.

大体的流程分为两块

1.OC原生设置webView的相关—->发送数据给VUE—–>VUE收到数据—–>返回数据给OC
2.VUE直接传值给OC

1.WKWebView的相关设置

1
2
3
4
5
6
WKWebview的使用方法  
//1.包含头文件
#import <WebKit/WebKit.h>

//2.需要遵循的代理
<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//3.创建webView  
- (void)initWebView{

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
WKUserContentController *userController = [[WKUserContentController alloc] init];
config.preferences.javaScriptEnabled = YES;//这里是设置是否可以跟JS交互默认是NO
config.userContentController = userController;
[userController addScriptMessageHandler:self name:@"JSSendMessageToOC"];//这里设置接收VUE的方法可以添加多个,方法名是在VUE里面定义的
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) configuration:config];//这里可以把WebView设置成全局变量
webView.UIDelegate = self;
webView.navigationDelegate = self;
webView.allowsBackForwardNavigationGestures = YES;
[self.view addSubView: webView];
[webView.navigationDelegate loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.9.196:8081/#/learn"]]];//加载自己需要的地址
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//4.实现代理方法,这个方法就是JS调用本地时回调的方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
//message中包含了js中所有的信息
//有两个重要的属性,一个是name,进行区分判断具体响应某个方法
//body中就是js传过来的参数
if ([message.name isEqualToString:@"JSSendMessageToOC"]) {
NSLog(@"接收到JS发来的数据%@",message.body);
}
}
//这里需要VUE的对应代码
created() {
//Vue的方法给原生调用,则需要把方法挂在Window下面
window.getDataFromNative = this.getDataFromNative;
// this.onLoad();
},

//接收native的数据
getDataFromNative(params) {
//params: 原生调用Vue时传值(params)给Vue
console.log("得到原生传值结果:" + params);
this.onLoad();
return params; //回调给原生,可写可不写
},
1
2
3
4
5
6
7
8
9
//5.关于VUE的弹窗就是那个Alert需要单独设置不然你会发现在浏览器调试的时候显示但是在APP里面的无法正常显示的,这个是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) {
completionHandler();//这里这个方法一定要调用不然程序会崩溃
}]];
[self presentViewController:alert animated:YES completion:nil];
}

2.OC传值给JS

webview都设置好了,加载出来数据之后就可以传值了

1
2
3
4
5
6
//这里类似于网络请求你发一个数据给VUE然后它返回一个数据给你
NSString *toVueSting = msg;
NSString *jsStr = [NSString stringWithFormat:@"getDataFromNative('%@')",toVueSting];//getDataFromNative这个方法名还是需要跟VUE里面设置的一样
[self->_webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable d, NSError * _Nullable error) {
NSLog(@"VUE返回的数据%@",d);//回调值
}];

3.JS传值给OC

这里需要说明一下,这里其实就是js传值给本地就包含iOS和安卓,所以写VUE的时候要加个判断,根据系统来响应.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  var u = navigator.userAgent;
//android终端
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
//ios终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
if(!isiOS){
$App.getDataFromNative(
vue给android传值
"传一个字符串"
);
}else {
window.webkit.messageHandlers. getDataFromNative.postMessage(
{"obj":"传一个对象"}
);
}

到这里基本的功能就可以实现了.