美文网首页我爱编程
ios端与js交互(WebView+WKWebView)

ios端与js交互(WebView+WKWebView)

作者: 三好夫人 | 来源:发表于2018-02-01 01:01 被阅读0次

    需求:1点击js登入按钮将用户账号和密码传给移动端
    2将地东段的token传给html端

    ios端
    有3种方法
    1:webview的javascriptCore
    2:webkit
    3:uir拦截
    4:第三方库

    理论:js与oc相互调用并且传值 我们可以理解成河2边需要送东西的过程 我们需要在js和oc之间搭建一个桥梁而jsexport就是这做桥梁,有了桥梁以后在2端传值我们还需要一个对象(快递员)
    就好比现实中js在桥的一段,而移动端在桥的这一边现在他们需要给彼此送东西那么就需要一个快递员(对象)理解了吧,哈哈。好了现在我们来举个例子

    第一种方法jscascriptcore
    第一步搭建2端之间桥梁javascriptcore

    1)导入javascriptCore
    Build phass->link binary with libraries
    添加头文件

    import<JavaScriptCore/JavaScriptCore.h>

    2)初始化桥梁
    @property(nonatomic,strong)JSContext *jsContext;
    在web的webViewDidFinishLoad:代理方法中
    self.jsContext = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    让js中的快递员搬运工也让oc所持有
    self.jsContext[@"objcet"] = self;

    self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
        context.exception = exception;
        NSLog(@"错误信息:%@",exception);
    };
    

    3创建快递员其中object就是js端的对象 一般是js端创建好的我们移动端只要引用这个快递员
    self.jsContext[@"objcet"] = self;
    好了现在桥梁有了搬运工也有了现在我们需要给搬运工一个交通工具(代理方法)

    4)创建对象传递工具—摩托车(代理方法) 注意:交通工具是js端定义的,一般都是协商好的 下面的getcall就是快递员需要搭乘的交通工具而callstring这个字符串就是快递
    @protocol JSObjcDelegate <JSExport>

    • (void)getcall:(NSString *)callString;
      @end

    5)oc端接收快递不对,接收值
    -(void)getcall:(NSString *)callstring{
    }
    好了,js端可以给oc传值了 完成了

    二:oc给js传值

    js端定义个点击事件 call()并且该点击事件被obj对象(这个对象就是oc对象)持有当触发call事件时会调用oc端的call方法
    我们这这里可以给js端传值
    <input type="button" value="js端接收oc传值" onclick="obj.call()">

    //oc给js传值:js点击按钮获取oc中的值---也就是点击js端触发call事件时调用occall方法 我们可以在理做原生的push pop等
    -(void)call{

    // 调用js中的Call1方法
    JSValue *Callback = self.jsContext[@"Call1"];
    //传值给web端call1函数字符串
    [Callback callWithArguments:@[@"我是oc端传给js端的值测试值:123456789"]];
    

    }
    js端call1函数方法
    var Call1 = function(str)
    {
    alert(str);
    }

    ————————————————WKWebView中js交互
    WKWebview
    和webview差不多只不过我们的桥梁变成了
    WKUserContentController *conntentController
    这家伙可以充当我们的桥梁作用
    而且它有一个方法可以让我oc端直接监听到js端的某一个快递员 其中第一个参数是代理,name:就是js端的快递员名字
    [conntentController addScriptMessageHandler:self name:@"getUserandPwd"];
    js端只要在需要传值得函数中加入以下函数
    其中getUseranPwd就是需要监听的快递员名字,而postMessage()中是需要传送的值
    window.webkit.messageHandlers.getUserandPwd.postMessage(xxxx)

    当我们js端的方法被触发而里面的快递员将会被派送出去oc端也监听到了快递员来了接下来就需要签收快递
    我们在下面这个方法中来接收快递
    其中第一个参数是初始化wkweb时的配置信息可以打印一下,而后面的message就是消息体(快递单里面有快递员名字,电话和快递)其中
    message.name—>快递员名字
    message.body——>快递(js端传来的值)
    如果js端创建了多个快递员那么我们需要根据名字来分别接受快递(处理)
    注意:这个方法是关键我们相互传至的关键
    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

    oc给js传值
    例子:oc无法直接给js端触发事件的函数传智,只能当js端点击了某一个按钮给oc端派送一个空的快递 我们oc端监听到了然后传智给js端(调用js端的函数)
    [self.web evaluateJavaScript:Call1Result completionHandler:^(id _Nullable result, NSError * _Nullable error) {
    NSLog(@"111%@", error);
    }];
    其中:第一个函数是函数名字 block中显示调用结果
    下面的列子其中Call(str)就是js端的某一个函数而str是值
    NSString *Call1Result = [NSString stringWithFormat:@"Call1('%@')",str];

    完整代码
    初始化web
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
    WKUserContentController *conntentController = [[WKUserContentController alloc]init];

    //获取js端需要调用的方法 name是js端的方法名getUserandPwd (message.Body>消息体)
    

    // window.webkit.messageHandlers.getUserandPwd.postMessage(<message.Body>)
    //这个是监听js端点击事件当js端触在这2个事件中添加了上面的方法那么这2个点击事件那么我们oc端就可以知道并且做出回应
    [conntentController addScriptMessageHandler:self name:@"getUserandPwd"];
    [conntentController addScriptMessageHandler:self name:@"CallGet"];

    config.userContentController = conntentController;
    
    self.web = [[WKWebView alloc]initWithFrame:self.view.bounds configuration:config];
    

    self.web.UIDelegate = self;
    [self.view addSubview:self.web];

    在web的这个delegate方法 不然会报错

    • (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{

      NSLog(@"%@",message);

      //必须要加上这句不然不执行
      completionHandler();

    }

    监听
    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

    // //oc代码传给js端
    if ([message.name isEqualToString:@"CallGet"]) {

        [self shareJS];
        //js传值给oc
    } else if ([message.name isEqualToString:@"getUserandPwd"]){
        //接收js端传值
        NSString *UserStr = [NSString stringWithFormat:@"%@",message.body[@"user"]];
        NSString *PassWordStr = [NSString stringWithFormat:@"%@",message.body[@"password"]];
        
        NSLog(@"我是js端传过来的值:用户名%@ 密码:%@",UserStr,PassWordStr);
    
    }
    

    }

    -(void)shareJS{

    NSString *str = @"OC给js端传过去的测试值--随便写吧我爱鹿晗";
    NSString *Call1Result = [NSString stringWithFormat:@"Call1('%@')",str];
    //OC调用JS
    [self.web evaluateJavaScript:Call1Result completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        NSLog(@"111%@", error);
    }];
    

    }

    js端代码
    <button onclick="copyText()">登入-传值给client</button>

    function copyText() {

      <!--wkweb使用-->
      window.webkit.messageHandlers.getUserandPwd.postMessage({user:document.getElementById("user").value,password:document.getElementById("password").value});
    
    
        <!--webvieiw使用其中object就是对象(快递员)getcall(NSStirng *)-->
    


    }

    <input type="button" value="js端接收oc传值" onclick="call()">
    </div>

    <h1>回调展示区</h1>
    <textarea id ="returnValue" type="value" rows="5" cols="40">


    function Call1(str)
    {
    document.getElementById("returnValue").value = str;

    }
    function call() {
    window.webkit.messageHandlers.CallGet.postMessage(null);
    alert('你你好我叫郑伊健');
    }

    相关文章

      网友评论

        本文标题:ios端与js交互(WebView+WKWebView)

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