zoukankan      html  css  js  c++  java
  • iOS开发 UIWebView+JavaScript 交互总结

    算是个人项目经验的,印象比较深的Web+JS交互的使用

    iOS原生应用与Web页面元素交互方式有很多,JavaScriptCore、拦截协议、第三方框架WebViewJavaScriptBridge、iOS8之后的WKWebView等;

    简要记录下之前开发用到的两种方式:

    1. 劫持页面加载,从 UIWebVIew 的 shouldStartLoadWithRequest 方法中拦截RequestURL 判断加载项,代码简要:

    -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

    {

        NSString *urlStr = [[request URL] absoluteString];

    // 加载的url 关键词需要同后台约定

         NSRange range_keyWord = [urlStr rangeOfString:@"opengood://"];

        if (range_keyWord.length > 0) {

         [self doSomeThing];

      }

        return YES;

    }

    2. iOS7之后水果公司推出的 JavaScriptCore 框架,交互起来hin方便

    需要注意的是JS调用的方法名等需要同前端的同事沟通好,最好由前端提供给你。

    浅显的说,这个方式等同于将当前ViewController 注入到web的context中,不同webClick都能够有不同的JS方法与VC上面的代理方法相对应,

    例:

      Web端

       javaScript控件的点击事件约定触发  'task.openNewWeb('urlStr')'

      “task”这个东西在web源码中并没有什么实际意义 它只相当于iOS端的某个viewController的占位符号

    iOS端代码:

    #import <JavaScriptCore/JavaScriptCore.h>

     UIWebView  代理方法中将当前控制器动态注入js中

    - (void)webViewDidStartLoad:(UIWebView *)webView {

       

       //首先创建JSContext 对象(此处通过当前webView的键获取到jscontext)   

      JSContext * context =[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

      // 控制器self 填充web中预留的占位符‘task’

        self.context[@"task"] = self;

    //  这时候javaScript控件的点击事件约定触发  'task.openNewWeb('urlStr')'

    //  那么在OC语法中相当于 [self openNewWeb:urlStr];

        self.context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {

            context.exception = exceptionValue;

            NSLog(@"异常信息:%@", exceptionValue);

        };

     }

    ******** ⚠️ 注意:WEB JS交互crush

    /*

    *    web点击事件 'task.click()' ,OC中必须要有对应的方法声明和实现,否则无法响应交互或导致crush

    *     而且,在iOS10 以后  貌似加强了调度表查询机制,所以声明OC方法名的时候注意重复问题,

    *    例如 openWeb:(int)index (NSString *)url  与 openWeb:(NSString *)url  形参数量存在差异,视为两个不同方法

    *    因为在OC消息传递机制中,self.openNewWeb()   首先是通过self 查找保存本身所有selector的调度表

    *       若self的selectorNameList中并未找到js调用的task.selectorName ,则通过self的isa定位到superClass,继续从super中的函数调度表 selectorNameList查询

    *     superClass中仍未查到则继续根据其isa顺藤摸瓜找到super的元类继续查找  如果元类中还没有  抛出异常>> crush.nice    - -b

    */    

    所以对于上面拦截web加载的方式,JavaScriptCore 的另一个优点就是提升代码可读性。。。

    由于项目代码内部有涉及到公司业务不方便贴出来,给大家提供两个之前调研过的连接,里面有详尽的JavaScriptCore 使用

    链接1

    http://mp.weixin.qq.com/s?__biz=MzAxMzE2Mjc2Ng==&mid=401786074&idx=1&sn=f03d52e7b4f980d694ed4a6b0e808d3b&scene=23&srcid=0309JfhgdIYEJ4vg1YY3OD2T#rd

    链接2

    http://mp.weixin.qq.com/s?plg_nld=1&plg_auth=1&plg_nld=1&plg_dev=1&plg_uin=1&plg_usr=1&plg_vkey=1&plg_nld=1&plg_uin=1&mid=403853462&plg_nld=1&idx=1&scene=23&plg_auth=1&__biz=MjM5Nzc1MzU2NA%3D%3D&plg_dev=1&srcid=0308AYX0Hpyq3w7TEdwDQ8z8&plg_usr=1&sn=f7437fe6fa45e62d86c026efa4aa1645&plg_vkey=1#rd

    在很多页面涉及web交互时,就要频繁调用JS与ViewController关联的方法

    这个之前写的一个web类目,提供下载链接,欢迎修改和完善

    http://pan.baidu.com/s/1eRSt6p0

  • 相关阅读:
    Heapsort 堆排序算法详解(Java实现)
    GIve Me A Welcome Hug!
    linux系统救援模式拯救mv libc.so.6文件后无法使用命令的悲剧
    RabbitMQ集群部署
    使用Xshell通过堡垒机登录服务器
    dubbo + zookeeper环境部署
    zookeeper集群部署
    zabbix-3.0.1 添加微信报警
    zabbix-3.0.1结合grafana绘图
    Centos7.2安装zabbix3.0.1简要
  • 原文地址:https://www.cnblogs.com/dev1024/p/5466525.html
Copyright © 2011-2022 走看看