iOS开发 怎么实现js调取oc中的方法

2024-11-20 10:35:56
推荐回答(1个)
回答1:

我们要做的有如下几件事情:

首先:通过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里面的方法的。