当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS与网页JS交互

iOS与网页JS交互

2018年09月18日  | 移动技术网IT编程  | 我要评论

栗原弘子,健康一身轻张国玺,罗马假日下载


随着移动app的快速迭代开发趋势,越来越多的app中嵌入了html网页,但在一些大中型app中,尤其是电商类app,html页面已经不仅仅满足展示功能,这时html要求能与原生语言进行交互、相互传值。比如携程app中一个热门景点的网页中,点击某个景点,可以跳转到原生中的该景点详情页控制器。

为此,我整理了三种最常用最便捷有效的oc与js交互的方式,供大家学习交流。

第一种:js给oc传值。

1. 技术方案:使用javascriptcore.framework框架
2. 使用场景: 网页中代码中的某个方法,比如点击事件方法,将该方法的参数传值给oc,供oc使用。
比如:携程app中一个热门景点的网页中,有很多个热门景点,点击某个景点的图片或名称,可以跳转到原生中的该景点详情页控制器。
3. 代码实现如下:

oc里要实现的代码:

拖入javascriptcore.framework静态库,遵守uiwebviewdelegate代理协议。
在-webviewdidfinishload:方法里编写如下代码:

- (void)webviewdidfinishload:(uiwebview *)webview{

    jscontext *context = [webview valueforkeypath:@"documentview.webview.mainframe.javascriptcontext"];

    context[@"passvalue"] = ^{

        nsarray *arg = [jscontext currentarguments];
        for (id obj in arg) {
            nslog(@"%@", obj);
        }
    };

}

其中 passvalue 是js的函数名,得到的 arg数组 里面为js的 passvalue 函数的参数,即 js要传给oc的参数

js里要实现的代码:

function testclick()
            {
                var str1=document.getelementbyid("text1").value;
                var str2=document.getelementbyid("text2").value;

                passvalue(str1,str2);
            }

在需要给oc传值的函数里(例如:testclick())直接调用 passvalue()函数,将值传进去即可。


第二种:js给oc传值。

1. 技术方案:使用自定义url方法,每次点击网页
2. 使用场景: 网页中代码中的某个方法,比如点击事件方法,将该方法的参数传值给oc,供oc使用。
比如:携程app中一个热门景点的网页中,有很多个热门景点,点击某个景点的图片或名称,可以跳转到原生中的该景点详情页控制器。
3. 代码实现如下:

js里要实现的代码:

  function testclick()
            {

                var str1=document.getelementbyid("text1").value;
                var str2=document.getelementbyid("text2").value;

                //  "objc://"为自定义协议头;
                //  str1&str2为要传给oc的值,以":/"作为分隔
                window.location.href="objc://"+":/"+str1+":/"+str2;
            }

在需要给oc传值的函数里(例如:testclick())写如上格式的代码。

其中 objc:// 是自定义的协议头,str1与str2为js要传给oc的值

oc里要实现的代码:

//遵守uiwebviewdelegate代理协议。
-(bool)webview:(uiwebview *)webview shouldstartloadwithrequest:(nsurlrequest *)request navigationtype:(uiwebviewnavigationtype)navigationtype{
    //拿到网页的实时url
    nsstring *requeststr = [[request.url absolutestring] stringbyremovingpercentencoding];

    //在url中寻找自定义协议头"objc://"
    if ([requeststr hasprefix:@"objc://"]) {

        // 以"://"为中心将url分割成两部分,放进数组arr
        nsarray *arr = [requeststr componentsseparatedbystring:@"://"];
        nslog(@"%@",arr);

        //取其后半段
        nsstring *paramstr = arr[1];
        nslog(@"%@",paramstr);

        //以":/"为标识将后半段url分割成若干部分,放进数组arr2,此时arr2[0]为空,arr2[1]为第一个传参值,arr2[2]为第二个传参值,以此类推
        nsarray *arr2 = [paramstr componentsseparatedbystring:@":/"];
        nslog(@"%@",arr2);

        //取出参数,进行使用
        if (arr2.count) {
            nslog(@"有参数");
            [self dosomethingwithparama:arr2[1] andparamb:arr2[2]];
        }else{
            nslog(@"无参数");
        }
        return no;
    }

    return yes;
}
//对js传来的值进行调用
- (void)dosomethingwithparama:(id)parama andparamb:(id)paramb{

    nslog(@"%@    %@", parama, paramb);
}

第三种:利用第三方库实现js与oc的相互传值。

1. 技术方案:使用webviewjavascriptbridge三方库
2. 使用场景: 网页中代码中的某个方法,比如点击事件方法,将该方法的参数传值给oc,供oc使用。
比如:携程app中一个热门景点的网页中,有很多个热门景点,点击某个景点的图片或名称,可以跳转到原生中的该景点详情页控制器。
或者将原生中的用户信息传递给网页,以便其个性化展示
3. 代码实现如下:

oc传值给js

js里需要实现的代码:

function setupwebviewjavascriptbridge(callback) {
        if (window.webviewjavascriptbridge) { return callback(webviewjavascriptbridge); }
        if (window.wvjbcallbacks) { return window.wvjbcallbacks.push(callback); }
        window.wvjbcallbacks = [callback];
        var wvjbiframe = document.createelement('iframe');
        wvjbiframe.style.display = 'none';
        wvjbiframe.src = 'wvjbscheme://__bridge_loaded__';
        document.documentelement.appendchild(wvjbiframe);
        settimeout(function() { document.documentelement.removechild(wvjbiframe) }, 0)
    }

    //调用上面定义的函数
    setupwebviewjavascriptbridge(function (bridge){

        //oc传值给js 'testjavascripthandler'为双方自定义好的统一方法名;'data'是oc传过来的值;'responsecallback'是js接收到之后给oc的回调
        bridge.registerhandler('testjavascripthandler', function(data, responsecallback) {
                //打印oc传过来的值
                log('objc called testjavascripthandler with', data)

                var responsedata = { 'javascript says':'right back atcha!' }

                log('js responding with', responsedata)

                //给oc的回调
                responsecallback(responsedata)

            })

oc里需要实现的代码:

导入第三方库webviewjavascriptbridge;遵守uiwebviewdelegate;

    //设置第三方bridge是否可用
    [webviewjavascriptbridge enablelogging];

    //关联webview和bridge
    _bridge = [webviewjavascriptbridge bridgeforwebview:web];

    [_bridge setwebviewdelegate:self];

    //oc给js传值,双方自定义一个统一的方法名'testjavascripthandler';data里即为要传过去的值
    [_bridge callhandler:@"testjavascripthandler" data:@{@"年龄":@"20"}];

js传值给oc

js里需要实现的代码:

     //点击网页上一个按钮时
     callbackbt.onclick = function()
     {  
     var str1=document.getelementbyid("text1").value;
     var str2=document.getelementbyid("text2").value;

     //js给oc传值。'passvalue'为双方自定义的统一方法名;'str1'&'str2'为要传的值; response为oc收到后给js的回调
     bridge.callhandler('passvalue', {str1,str2}, function(response) {
                                })

     }

oc里需要实现的代码:

导入第三方库webviewjavascriptbridge;遵守uiwebviewdelegate;

   //设置第三方bridge是否可用
    [webviewjavascriptbridge enablelogging];

    //关联webview和bridge
    _bridge = [webviewjavascriptbridge bridgeforwebview:web];

    [_bridge setwebviewdelegate:self];

    //js给oc传值.'passvalue'为双方自定义的统一方法名;'data'为js传过来的值;'responsecallback'为oc收到值后给js返回的回调
    [_bridge registerhandler:@"passvalue" handler:^(id data, wvjbresponsecallback responsecallback) {

        //打印js传过来的值
        nslog(@"%@", data);

        //返回给js的值
        responsecallback(@"收到了");
    }];

需要注意的是:不论哪方给哪方传值,传值的方法名称与对应接收值的方法名称要保持一致。

有任何问题,大家可以在评论区留言,我会一一解答。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网