美文网首页
iOS 路由改进

iOS 路由改进

作者: 赵哥窟 | 来源:发表于2021-04-23 15:58 被阅读0次

    之前写过一篇关于iOS 组件化之CTMediator的文章,小项目中使用起来还是不怎么方便,改进了下,取名为DRouter吧,目录结构是这样的

    截屏2021-04-23 15.45.46.png
    DRouter

    这个两个文件就不说了,就是CTMediator源文件改下名字,代码是一样的

    Target_Commons

    看代码就知道就是动态添加参数和回调的,CTMediator是在每个Module下面都添加一个Target_xxxx,这样觉得麻烦就写一个通用的。

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    extern NSString * const DRouterTargetCommons;
    
    @interface Target_Commons : NSObject
    
    // 自定义push方法
    - (UIViewController *)Action_Push_CommonController:(NSDictionary *)params;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "Target_Commons.h"
    #import "UIViewController+Parameter.h"
    #import "UIViewController+Block.h"
    #import <objc/runtime.h>
    
    typedef void (^callBlock)(NSDictionary *);
    
    
    NSString * const DRouterTargetCommons = @"Commons";
    
    @implementation Target_Commons
    
    
    // 自定义push方法
    - (UIViewController *)Action_Push_CommonController:(NSDictionary *)params{
        NSString *vcClassName = params[@"vcClassName"];
        
        callBlock callback = params[@"callback"];
        
        Class class = NSClassFromString(vcClassName);
        UIViewController *controller = [[class alloc] init];
        //传值
        if([params objectForKey:@"vauleParameter"] != nil){
            controller.parameter = [params objectForKey:@"vauleParameter"];
        }
        //参数回调
        if(callback != nil){
            controller.backBlock = ^(NSDictionary * _Nonnull parameter) {
                callback(parameter);
            };
        }
        
        return controller;
    }
    
    
    @end
    
    
    UIViewController+Parameter

    分类给Controller添加参数用的

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface UIViewController (Parameter)
    
    @property (copy, nonatomic) NSDictionary *parameter;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    #import "UIViewController+Parameter.h"
    #import <objc/runtime.h>
    
    static const char * PARAMETER_KEY = "parameter_key";
    
    @implementation UIViewController (Parameter)
    
    - (void)setParameter:(NSDictionary *)parameter{
        objc_setAssociatedObject(self, PARAMETER_KEY, parameter, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    - (NSDictionary *)parameter {
        return  objc_getAssociatedObject(self, PARAMETER_KEY);
    }
    
    
    @end
    
    
    UIViewController+Block

    给Controller添加回调用的

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    typedef  void (^BackBlock)(NSDictionary *parameter);
    
    @interface UIViewController (Block)
    
    /** 完成的回调block */
    @property (nonatomic, copy) BackBlock backBlock;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "UIViewController+Block.h"
    #import <objc/runtime.h>
    
    static const char * BLOCK_KEY = "block_key";
    
    @implementation UIViewController (Block)
    
    - (void)setBackBlock:(BackBlock)backBlock{
        objc_setAssociatedObject(self, BLOCK_KEY, backBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    - (BackBlock)backBlock {
        return  objc_getAssociatedObject(self, BLOCK_KEY);
    }
    
    @end
    
    具体使用
    截屏2021-04-23 15.52.38.png

    如果图,每个Module还是新建一个Mediator

    #import "DRouter.h"
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface DRouter (A_Module)
    
    - (UIViewController *)mediator_AModulePage1:(NSMutableDictionary *)params;
    
    - (UIViewController *)mediator_AModulePage1:(NSMutableDictionary *)params completion:(void (^)(NSDictionary *))completion;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    #import "DRouter+A_Module.h"
    
    //  字符串 是类名 Target_xxx.h 中的 xxx 部分
    NSString * const kMediatorTarget_A_Module = @"A_Module";
    
    @implementation DRouter (A_Module)
    
    - (UIViewController *)mediator_AModulePage1:(NSMutableDictionary *)params{
        UIViewController *viewController = [self performTarget:@"Commons"
                                                        action:@"Action_Push_CommonController"
                                                        params:params shouldCacheTarget:NO];
        if ([viewController isKindOfClass:[UIViewController class]]) {
            // view controller 交付出去之后,可以由外界选择是push还是present
            return viewController;
        } else {
            // 这里处理异常场景,具体如何处理取决于产品
            NSLog(@"%@ 未能实例化页面", NSStringFromSelector(_cmd));
            return [[UIViewController alloc] init];
        }
    }
    
    - (UIViewController *)mediator_AModulePage1:(NSMutableDictionary *)params completion:(void (^)(NSDictionary *))completion{
        [params setValue:completion forKey:@"callback"];
        return [self mediator_AModulePage1:params];
    }
    
    @end
    
    Controller中使用
    - (void)pushAModulePage1
    {
        NSMutableDictionary *param = [NSMutableDictionary dictionary];
        [param setValue:@"APage1Controller" forKey:@"vcClassName"];
        //需要回调时添加
        [param setValue:@"callback" forKey:@"callback"];
        //需要传值是添加
        [param setValue:@{@"value":@"我是上一个页面传过来的value"} forKey:@"vauleParameter"];
        
        UIViewController *viewController = [[DRouter sharedInstance]mediator_AModulePage1:param completion:^(NSDictionary * _Nonnull dic) {
            [self showAlert:[dic objectForKey:@"value"]];
            
        }];
       [self.navigationController pushViewController:viewController animated:YES];
    }
    
    返回参数
    - (IBAction)blockAction:(UIButton *)sender {
        
        if(self.backBlock){
            [self.navigationController popViewControllerAnimated:YES];
            
            self.backBlock(@{@"value":@"A_Module_Page1_Block"});
        }else{
            [self.navigationController popViewControllerAnimated:YES];
        }
    }
    
    

    可以看到,我们在跳转并没有#import 需要跳转的页面。都是动态创建,传参和返回参数的。

    下载地址

    Demo

    相关文章

      网友评论

          本文标题:iOS 路由改进

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