我们要做的有如下几件事情:
首先:通过webview加载一个本地html文件
[self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"]isDirectory:NO]]];
其次:我们要在我们的OC代码里面注册JS方法
- (void)h5callApp
{
//获取该UIWebview的javascript执行环境。
JSContext *context = [self.myWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context.exceptionHandler = ^(JSContext *con, JSValue *exception) {
NSLog(@"%@", exception);
con.exception = exception;
};
context[@"h5CallApp"] = ^() {
NSLog(@"+++++++Begin Log+++++++");
NSArray *args = [JSContext currentArguments];
for (JSValue *jsVal in args) {
NSLog(@"%@", jsVal);
}
JSValue *this = [JSContext currentThis];
NSLog(@"this: %@",this);
NSLog(@"-------End Log-------");
};
}
要保证本地的html里面有h5CallApp这个方法哦。
这就是刚刚上述博客里面提到的方法,是不是看上次很简单的样子。
But
我运用到我们项目里面的时候,死活不能调用该方法,why?我厚着脸皮问了我们的帅哥安卓开发,得知他们里面有这一样一行代码
webView.addJavascriptInterface(new JSInvoke(), "test");
看上去第一眼的感觉是不是累似注册了一个东西,可是我找了好多博客我没有找到我们IOS类似的啊,着急啊着急。
意外的意外,伟大的github上面就是资源多,我在上面找到一个EasyJSWebViewSample这样一个开源项目,里面有一句
MyJSInterface* interface = [MyJSInterface new];
[self.myWebView addJavascriptInterfaces:interface WithName:@"MyJSTest"];
是不是感觉和安卓里面的那个注册类似的,没错,太开心了。
最后的最后,你以为结束了,NO!
该Demo里面的html有空的小朋友可以看一下。
由于项目需求我们是3个参数,在该demo里面执行拿到第一个参数,该demo就运行出错,提示我们数组越界了,在这里真的浪费了好多时间,后来发现他们的demo里面调用两个参数的方法在JS里面声明的方法与OC里面真正的实现方法有点差入,比如OC里面定义的方法
- (void) h5CallApp: (NSString*) param And2: (NSString*) param2 And3: (NSString*) param3
在html里面只能写成
MyJSTest.h5CallAppAnd2And3("param1","param2","param3")。
是不是觉得不可思义,最后我整体看了一下代码,里面好像有这一段在注入JS的时候有用到的
inject: function (obj, methods){\\
window[obj] = {};\\
var jsObj = window[obj];\\
\\
for (var i = 0, l = methods.length; i < l; i++){\\
(function (){\\
var method = methods[i];\\
var jsMethod = method.replace(new RegExp(\\":\\", \\"g\\"), \\"\\");\\
jsObj[jsMethod] = function (){\\
return EasyJS.call(obj, method, Array.prototype.slice.call(arguments));\\
};\\
})();\\
}\\
}
这个好像是替换方法的,原谅我的无知啊,我也是没看懂,仅仅是感觉与猜测,勿喷我,我真的怕被喷。
最后的最后,JS的那边的开发肯定是不会为了将IOS与安卓开发做区分写代码的,所以我只能在注入JS完成后加了这么一句
[webView stringByEvaluatingJavaScriptFromString:@"test.h5CallApp=test.h5CallAppAnd2And3;"]
这句话的作用是替换JS里面的方法的。