文章目录
  1. 1. 解决问题
    1. 1.0.1. 场景1:从apns推送来的的信息,根据服务端推送过来的数据规则,跳转到对应的控制器。
    2. 1.0.2. 场景2:点击webview中某链接时,跳转到原生ViewController中继续后续操作。
  • 2. 简介
  • 3. 使用
  • 4. 思路
  • 5. 实现代码
  • 6. 实例:
    1. 6.0.1. 1. ExampleApp.html
    2. 6.0.2. 2.uiwebview所在控制器(依赖WebViewJavascriptBridge)
  • 7. 完整代码:https://github.com/mozhenhau/D3Generator
  • 解决问题

    场景1:从apns推送来的的信息,根据服务端推送过来的数据规则,跳转到对应的控制器。

    场景2:点击webview中某链接时,跳转到原生ViewController中继续后续操作。

    要实现以上的产品逻辑, 通常都需要前后端约定一些规则实现跳转。
    约定的弊端很明显, 需要开发前就约定很多规则, 不一定能覆盖所有逻辑,没有覆盖到的逻辑需要更新客户端才能实现跳转,并且要各种switch判断,肯定会晕乎的。
    本项目就是为了解决这种问题,只需要根据后台返回的数据则可实现万能跳转。要怎么跳转后台你们来决定吧,-_-#

    简介

    这是一个轻量的web view与js交互Demo。
    根据dict字典生成对象。 适用webview或push推送时,根据后台传回字典实现动态跳转。ps:webview与js的交互依赖WebViewJavascriptBridge。
    后台提供json如下,即会根据className生成TestViewController2控制器,并且把title、comFrom赋值给控制器:

    {
    'className': 'TestViewController2',
    'title': '页面2',
    'comFrom':'web'
    }
    

    使用

    可以直接根据字典规则跳转

    [D3Generator createViewControllerWithDictAndPush:data];
    

    可以生成控制器自行跳转

    UIViewController *vc = [D3Generator createViewControllerWithDict:data];
    

    思路

    1. 后台提供json,信息包括:要生成的控制器名称、跳转到该控制器所需的参数值。
    2. 利用objective-c强大的runtime动态特性,通过NSClassFromString生成控制器对象。
    3. 利用objective-c强大的runtime动态特性,通过setValue设置控制器对象所需的参数值。
    4. 获取window的rootViewcontroller,然后实现界面跳转。

    实现代码

    动态生成对象:

    Class class = NSClassFromString(dict[@"className"]);
    id object = [[class alloc]init];
    

    获取控制器属性值:

    (NSMutableArray*)getPropertiesWithClass:(Class)cls{
        // 获取当前类的所有属性
        unsigned int count;// 记录属性个数
        objc_property_t *properties = class_copyPropertyList(cls, &count);
        // 遍历
        NSMutableArray *mArray = [NSMutableArray array];
        for (int i = 0; i < count; i++) {
        // objc_property_t 属性类型
        objc_property_t property = properties[i];
        // 获取属性的名称 C语言字符串
        const char *cName = property_getName(property);
        // 转换为Objective C 字符串
        NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
        [mArray addObject:name];
        }
        return mArray.copy;
    }
    

    设置属性值:

     NSArray *properties = [self getPropertiesWithClass:class];
    for (NSString* key in properties) {
    if (dict[key]) {
    [object setValue:dict[key] forKey:key];
    }
    }
    

    实例:

    1. ExampleApp.html

    <!doctype html>
    <html><head>
    </head><body>
    <h1>我是UIWebview</h1>
    <script>
    function clickButton1(){
    var data = {'className': 'TestViewController',
    'comFrom':'web'};
    window.WebViewJavascriptBridge.send(data);
    };
    
    
    function clickButton2(){
    var data = {'className': 'TestViewController1',
    'comFrom':'web'};
    window.WebViewJavascriptBridge.send(data);
    };
    
    
    function clickButton3(){
    var data = {'className': 'TestViewController2',
    'storyboard': 'Main',
    'comFrom':'web'};
    window.WebViewJavascriptBridge.send(data);
    };
    </script>
    <div id='button1' onClick='clickButton1()'>Go VC1, 跳转到纯代码写的vc</div><br>
    <div id='button2' onClick='clickButton2()'>Go VC2, 跳转到xib写的vc</div><br>
    <div id='button3' onClick='clickButton3()'>Go VC3, 跳转到storyboard写的vc</div>
    </body></html>
    

    2.uiwebview所在控制器(依赖WebViewJavascriptBridge)

    import "WebViewController.h"
    import "WebViewJavascriptBridge.h"
    import "D3Generator.h"
    
    @interface WebViewController ()<UIWebViewDelegate>
    @property(nonatomic,strong)WebViewJavascriptBridge *bridge;
    @property (weak, nonatomic) IBOutlet UIWebView *webView;
    
    @end
    
    @implementation WebViewController
    
    (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"];
        NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];
        NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];
        [_webView loadHTMLString:appHtml baseURL:baseURL];
        [self addRoute:_webView];
    }
    
    
    -(void)addRoute:(UIWebView*)webView{
    _bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {
    NSLog(@"ObjC received message from JS: %@", data);
    responseCallback(@"报告: IOS收到!!!");
    
    [D3Generator createViewControllerWithDictAndPush:data];
    //        或者:
    //        UIViewController *vc = [D3Generator createViewControllerWithDict:data];
    //        [self.navigationController pushViewController:vc animated:YES];
    }];
    }
    @end
    

    完整代码:https://github.com/mozhenhau/D3Generator

    文章目录
    1. 1. 解决问题
      1. 1.0.1. 场景1:从apns推送来的的信息,根据服务端推送过来的数据规则,跳转到对应的控制器。
      2. 1.0.2. 场景2:点击webview中某链接时,跳转到原生ViewController中继续后续操作。
  • 2. 简介
  • 3. 使用
  • 4. 思路
  • 5. 实现代码
  • 6. 实例:
    1. 6.0.1. 1. ExampleApp.html
    2. 6.0.2. 2.uiwebview所在控制器(依赖WebViewJavascriptBridge)
  • 7. 完整代码:https://github.com/mozhenhau/D3Generator