美文网首页
iOS js交互遇到的问题

iOS js交互遇到的问题

作者: 温柔vs先生 | 来源:发表于2018-12-17 14:10 被阅读0次

    iOS 关于js交互的代码已经很多了,我这里说一下我在开发中遇到的问题:

    首先说一下最近开发过程中APP掉js代码时遇到的坑,看下面代码:

    if (model) {
                // 初始化页面数据
                dispatch_async(dispatch_get_main_queue(), ^{
                    JSValue *temfunction = _jsContext[@"appCallJsInitData"];
    //                [temfunction.context[@"setTimeout"] callWithArguments:@[model]];
                    [temfunction callWithArguments:@[model]];
                });
            }
    
    其中非常重要的两句代码
    1、 [temfunction callWithArguments:@[model]];
    
    2、 [temfunction.context[@"setTimeout"] callWithArguments:@[model]];
    

    第一种写法会在某些特定的时刻造成闪退的现象,网上推荐用第二种写法,但是在iOS12后这种写法会导致h5的界面加载不出来,至今没有找到原因,若以后知道会补充进来

    第二种交互方法
    if (model) {
                // 初始化页面数据
                NSString *jsonStr = [GeneralUtils transformDictionaryToJsonStr:model];
                jsonStr = [GeneralUtils transformSingleSlashToDoubleSlashWithJsonStr:jsonStr];
               
                dispatch_async(dispatch_get_main_queue(), ^{
                    
                    [_myWebView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"appCallJsInitData('%@')",jsonStr]];
                });
      } 
    

    他是通过webview自带的方法stringByEvaluatingJavaScriptFromString来把接口请求到的数据经过处理后的json串进行数据传递,目前项目中采用的是这种写法。但是官方有这样的提示:


    image.png

    译文: stringByEvaluatingJavaScriptFromString:方法同步等待JavaScript评估完成。如果您加载了尚未经过审核的JavaScript代码的Web内容,则调用此方法可能会导致您的应用挂起。最佳实践是采用WKWebView类并使用其evaluateJavaScript:completionHandler:方法。

    第三种交互方法
    if (model) {
                // 初始化页面数据
                NSString *jsonStr = [GeneralUtils transformDictionaryToJsonStr:model];
                jsonStr = [GeneralUtils transformSingleSlashToDoubleSlashWithJsonStr:jsonStr];
                dispatch_async(dispatch_get_main_queue(), ^{
    
                    [_jsContext evaluateScript:[NSString stringWithFormat:@"appCallJsInitData('%@')",jsonStr]];
                });
            }
    

    这种方法没有造成闪退的情况,但是在你连续进行交互时,界面有时并没有加载出来,出现白屏的现象。

    以上是我在js交互中遇到的一些问题,在此记录下来,有待以后补充完善。

    补充:

    2018.12.18:
    在第一种交互方法中,我说 (在iOS12后这种写法会导致h5的界面加载不出来)是不对的,首先我们要知道为什么要加setTimeout,设置setTimeout意味着加了一个延迟的方法,(在js的代码中对象获取值是异步进行的,类似iOS的异步,此时会造成不能保证拿到传递的数据后,对象被创建出来,所以要加一个延迟方法,保证对象都创建完毕,数据能够接受成功。)

    h5代码:
    /**
     * [appCalljsTellBinner app 传输轮播图片信息给js,并实例化]
     * @param  {[type]} arg [description]
     * @return {[type]}     [description]
     */
    function appCalljsTellBinner(arg){
            if(arg.code == "0000" && arg.data && arg.data.list ){
                var data = arg.data;
    //这里的vm可能没有及时创建出来,导致不能接收数据
                vm.carouselList = arg.data.list;
                Vue.nextTick(function () {
                    //顶部,广告位轮播
                    var carousel = new Swiper('#carousel .swiper-container',{
                        /*loop: true,*/
                        autoplay: 3000,
                        autoplayDisableOnInteraction:false,
                        lazyLoading : true,
                        lazyLoadingInPrevNext : true,
                        pagination : '.swiper-pagination',
                        preventLinksPropagation : true,
                        onInit:function(swiper){
                            setTimeout(function(){
                                document.querySelector('.swiper-pagination').style.opacity = 1;
                            },1000)
                        }
                    });
                });
            }
    }
    
    

    但是在上面代码中

    [temfunction.context[@"setTimeout"] callWithArguments:@[model]];
    

    我们并没有设置延迟的时间所以需要加上这样的数据

    [temfunction.context[@"setTimeout"] callWithArguments:@[temfunction, @0, model]];
    

    callWithArguments后面跟的是一个数组,里面要另外加上我们的缓存时间和对象。至于数组里面能放多少元素,元素的位置有没有要求等,还不是很清楚,留待以后解决。

    下面是官方对这个方法的介绍:

    /*!
    @methodgroup Calling Functions and Constructors
    */
    /*!
    @method
    @abstract Invoke a JSValue as a function.
    @discussion In JavaScript, if a function doesn't explicitly return a value then it
     implicitly returns the JavaScript value <code>undefined</code>.
    @param arguments The arguments to pass to the function.
    @result The return value of the function call. 
    */
    - (JSValue *)callWithArguments:(NSArray *)arguments;
    

    arguments传递给函数的参数。

    相关文章

      网友评论

          本文标题:iOS js交互遇到的问题

          本文链接:https://www.haomeiwen.com/subject/oyrqkqtx.html