Sian 发表于 2016-3-17 17:46:32

OC中JavaScriptCore使用的两个问题

1、iOS7及以后的版本中提供了JavaScriptSore框架,极大的方便了OC与JS的交互
2、基本使用参考:http://www.yusian.com/thread-11159-1-1.html
3、使用过程中存在一些问题,这里拿两个最为常见的问题进行分析
4.1、如果没有JS调用时没有该方法,如果捕获异常
A、JS调用OC方法时,如果不存在该方法不会造成程序崩溃,只是没任何反应而已,哪里可以看出来呢?
B、其实JSContext已经提供了一个方法,只是平时没有用,JSContext有条属性/*!
@property
@discussion If a call to an API function results in an uncaught JavaScript exception, the
<code>exceptionHandler</code> block will be invoked. The default implementation for the
exception handler will store the exception to the exception property on
context. As a consequence the default behaviour is for unhandled exceptions
occurring within a callback from JavaScript to be rethrown upon return.
Setting this value to nil will result in all uncaught exceptions thrown from
the API being silently consumed.
*/
@property (copy) void(^exceptionHandler)(JSContext *context, JSValue *exception);C、这条属性就是用来捕获异常的,我们可以直接通过set方法来捕获异常- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    ;
    ;
}
- (JSContext *)JSContext
{
    if (self->_JSContext == nil){
      self->_JSContext = ;
      ;
      [self->_JSContext setExceptionHandler:^(JSContext *context, JSValue *value) {
            context.exception = value;
            SALog(@"JS错误信息****\n%@****", value);
      }];
    }
    return self->_JSContext;
}D、如果调用了不存在的check()方法则输出以下异常信息:2016-03-17 17:39:00.755 fisher __26-_block_invoke-155行:JS错误信息****
TypeError: webView.check is not a function. (In 'webView.check()', 'webView.check' is undefined)****4.2、UIWebView加载的第一个页面JS调用本地方法没有问题,但如果跳转到了一个新的页面后,JS调用本地方法失效?

A、如上例所示,如果我们如果进入了下一个页面,再调用本地方法就会有如下错误信息2016-03-17 17:44:31.465 fisher __26-_block_invoke-152行:JS错误信息****
ReferenceError: Can't find variable: webView****B、从以上代码来看,JSContext是一种懒加载模式,如果使用了JSContext则会初始化并将其以"webView"这个描述注入到全局JS中去,所以加载的第一个页面是好使的,可页面跳转了为什么就不行了?!
C、我们想想网页的加载方式,有JS基础的童鞋应该知道,JS是可以直接写在<head>中以<script></script>标签存在的,或者通过link进来的;
D、我们的注入可以理解成是在页面加载完毕后临时写到这个标签中去的,那么页面刷新了或跳转到新页面了会怎样?
E、答案是当前网页源代码中之前的JS已经没有了,我们注入的那段JS代码被刷新掉了,所以要重新注入!
F、不需要重新创建JSContext对象,只需要执行注入即可,最好是将注入方法写在代理方法中- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    ;
}G、大功造成,不信试试看

A-Hing 发表于 2016-3-27 22:44:42

    ;按这样注入也是不行,有具体的demo提供参考吗?最好友js调用的代码

admin 发表于 2016-3-28 09:32:18

A-Hing 发表于 2016-3-27 22:44
;按这样注入也是不行,有 ...
写错了,应该是;
<html>
        <body>
                <button oncli ck="webView.share()">分享</button>
        </body>
</html>调用- (void)share方法



A-Hing 发表于 2016-3-29 17:10:24

admin 发表于 2016-3-28 09:32
写错了,应该是;


这个会涉及js的加载顺序吧,如果用一个button去出发js调用oc是可以成功的,但如果是没有button的点击事件呢?换成有js的html加载过程中就主动去加载oc方法呢?这种情况要怎么做呢?

admin 发表于 2016-3-29 18:14:04

A-Hing 发表于 2016-3-29 17:10
这个会涉及js的加载顺序吧,如果用一个button去出发js调用oc是可以成功的,但如果是没有button的点击事件 ...

那要看你什么时候注入了,前面执行;
是在方法- (void)webViewDidFinishLoad:(UIWebView *)webView中,说明等页面加载完毕后再注入我们的JS代码,如果在页面加载完毕之前页面就需要调用,那在这里注入是不合适的
但可以在- (void)webViewDidStartLoad:(UIWebView *)webView
这个方法中执行;
即要页面加载之前就注入

A-Hing 发表于 2016-3-30 17:30:47

admin 发表于 2016-3-29 18:14
那要看你什么时候注入了,前面执行

恩恩,受教了,感谢
页: [1]
查看完整版本: OC中JavaScriptCore使用的两个问题