最近的几个项目中都遇到了iOS原生代码和H5页面相互传递数据的问题. 分别使用了不同的方式.下面简单介绍几种.
原生代码向H5页面写入数据.
请求的URL中带上需要传递进去的参数数据.
例如
NSString *urlString = @"http://www.xxxxxx.com/app/index.html";
在这个字符串后面拼接想要传递的参数格式为baseurl?param1=xxx¶m2=xxx
拼接后
NSString *urlString = @"http://www.xxxxxx.com/app/index.html?param1=xxx¶m2=xxx";
//用它构造URL. 构造request. webView load request
注入js括号里带上参数
参数的具体格式和H5工程师商量
[webView stringByEvaluatingJavaScriptFromString:@"myFunction( 这里写参数 );"];
使用JavaScriptCore框架
#import <JavaScriptCore/JavaScriptCore.h>
首先确保H5页面中代码加载完毕
webViewDidFinishLoad 这个方法执行完毕就表示 webView加载一个页面完毕.
JSContext *context=[self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
NSString *jsonStr = [NSString stringWithFormat:@"window.showOrderResult(%@)",orderId];
[context evaluateScript:jsonStr];
JS向原生代码传递数据.
请求拦截方式.
UIWebViewDelegate这个协议下有一下方法
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//这里获得将要被加载的url. 截取url中的参数获得 url可以随意定义例如
//http://www.baidu.com?param1=asdfasdf¶m=asdf
//下面这个和上面的都可以被识别为一个request. 都会走这个方法.
//test://test?param1=xxxx¶m2=xxxx
NSString *url = request.URL.absoluteString;
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error
{
}
使用JavaScriptCore框架
#import <JavaScriptCore/JavaScriptCore.h>
首先创建一个用于与js交互的类 假设类名"IOS" 这个类遵守协议:
/**
* js调用oc里 main的代码,需要借助这个协议才行
*/
@protocol JSObjectProtocol <JSExport>
@required
#pragma mark -js调用该oc方法,并且将jsonstring打印出来
//print 方法是事先和H5工程师约定好的. H5用js掉这个方法就相当于调用iOS原生代码.
- (void)print:(NSString *)jsonString;
@end
//将ios对象注入H5页面
iOS *ios = [[iOS alloc] init];
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"iOS"] = ios;
//js如此调用上面的print方法
if (window["iOS"] && window["iOS"]["print"])
{
window["iOS"]["print"](JSON.stringify(d));
}