iOS开发笔记之七十六——轻量级组件化路由方案XYPageMaster(二)

******阅读完此文,大概需要20分钟******

一、项目源码

XYPageMaster是为了实现VivaVideo家族产品组件化的轻量级Router解决方案,有了它业务页面之间的跳转不在相互依赖,在业务项目之间解耦起到重要作用。在开发过程中,XYPageMaster参考了原大众点评App的路由方案,同时也调研了市场上主流的几种Router方案,它的源码地址:https://github.com/Leon0206/XYPageMaster。由于推到github的代码以及比较晚,所以文中的1.0、2.0版本是一种记录吧,代码最终是2.0版本。

二、接入说明

XYPageMaster的接入比较简单,大致分为以下几步:

1、首先,需要明确下XYPageMaster支持的Url格式(已经与Android约定):

xiaoying://home?id=123456&index=1

说明:

(1)schema字段区域:xiaoying(字母全小写)

(2)page key字段区域:home(字母全小写)

(3)参数字段区域:key="value"格式,(key值字母全小写,value不限,其中Json字串须UTF8转码)

2、注册并创建可以跳转的类,实现必要的方法

要支持跳转的类首先需要在urlmapping文件(主项目目录下)中进行注册一下,格式如下:

扫描二维码关注公众号,回复: 3017288 查看本文章

说明:

(1)页面key值:全部小写字符串,格式为"pagekey"或者 "业务group/pagekey";

(2)页面className:所要push的页面className

(3)storyboardName:viewController所在的storyboard名称(不写默认为非sb类型的跳转)

(4)bundleName:storyboard所在的bundle名称(不写默认为mainBundle)

3、跳转URL的配置以及跳转参数配置

目前pageMaster暴露了两个方法供选择进行跳转,如下:

(1)带result回调的跳转,方法如下:

- (void)openURLAction:(XYUrlAction *)urlAction result:(void(^)(NSString *viewController))result

使用示例:

XYUrlAction *action = [XYUrlAction actionWithURL:[NSURL URLWithString:@"xiaoying://home?id=123456"]];
[[XYPageMaster master] openURLAction:action result:^(NSString *class) {
    UIViewController *viewController = [NSClassFromString(class) new];
    [viewController handleWithURLAction:action];
    [self.navigationController pushViewController:viewController animated:YES];
}];

此种方法result回调回帮你返回你要跳转的VC的class,具体的跳转代码业务自己写。

(2)手动设置navigator的跳转,方法如下:

由于目前VivaVideo工程是多导航的,不同的页面可能是基于不同的navigator跳转的,所以1.0版本的pageMaster暂时暴露方法可以设置跳转导航器,示例代码如下:

[[XYPageMaster master] setNavigationController:self.navigationController];

XYUrlAction *action = [XYUrlAction actionWithURL:[NSURL URLWithString:@"xiaoying://home?id=123456"]];

[[XYPageMaster master] openURLAction:action];

此时openURLAction:方法内部会帮你实现vc的初始化与跳转。

(3)2.0版本之后,已经在appDelegate中接管了根navigationController,业务一般不需要再手动设置,App中后续的所有跳转,都应基于此navigationController;

appdelegate中代码如下:

- (void)setupPageMaster
{
    NSDictionary *params = @{@"schema":@"xiaoying",@"pagesFile":@"urlmapping",@"rootVC":@"XYHomeTabViewController",@"rootVC_SB":@""};
    [[XYPageMaster master] setupNavigationControllerWithParams:params];
    self.window.rootViewController = [XYPageMaster master].navigationContorller;
}
[XYPageMaster master].navigationController //业务可以直接调用下面的api直接实现跳转:
- (void)openURLAction:(nonnull XYUrlAction *)urlAction;
- (void)openUrl:(nonnull NSString *)url action:(nonnull void(^)(XYUrlAction * _Nullable action))actionBlock;

4、数值的传递

(1)数值的正向传递

数据分为两种,基本数据类型,例如bool、int、string、float这些,复杂数据类型,例如UIImage等;

pageMaster的参数可以选择拼在url中,也可以选择手动封装在action(action提供了一系列的方法可供操作)对象中,当然复杂数据类型只能手动封装在action对象中,如下:

XYUrlAction *action = [XYUrlAction actionWithURL:[NSURL URLWithString:@"xiaoying://home?id=123456&selectedindex=1"]];
[action setAnyObject:image forKey:@"image"];

如果你需要获取上一页面传递过来的参数,你只需要在跳转VC里面#import "XYPageMaster.h"

然后实现handleWithURLAction:方法即可。

- (void)handleWithURLAction:(XYUrlAction *)urlAction
{
    NSString *str = [urlAction stringForKey:@"string"];
}

(2)数值的反向传递

为了方便数据的反向回调,XYUrlAction中封装了以下两个属性:

@property (nonatomic, copy) CallBack callBack;
@property (nonatomic, strong) XYReactBlackBoard *callBackBoard;

如果你仅仅是做简单场景的数值回调,callBack即可满足你,如果你需要正反向比较频繁、灵活的传递,callBackBoard可以满足你。

具体使用实例如下:

[[XYPageMaster master] openUrl:@"xiaoying://datashare_1" action:^(XYUrlAction * _Nullable action) {
    action.singletonType = XYSingletonTypeRenew;
    action.callBack = ^(id x) {
        NSLog(@"-------->%@",x); //打印“回调啦”
    };
}];
- (void)handleWithURLAction:(XYUrlAction *)urlAction
{
    if (urlAction.callBack) {
        self.callback = urlAction.callBack;//self.callback,执行回调
        self.callBack(@"回调啦~");
    }
}

callBackBoard的使用参考数据黑白版相关文档。

5、单例页面的支持

(1)如果选择手动设置navigator的跳转方式,在你的跳转VC里可以实现isSingleton方法(默认是单例页面),如下:

+ (BOOL)isSingleton
{
    return YES;
}

return YES;当前导航堆栈中有且只有一份(默认值),return NO;导航堆栈中可以存在多份。

(2)2.0版本已经支持XYSingletonType设置,你只需要进行以下设置:

XYSingletonType的几种区别如下:

typedef NS_ENUM(NSInteger, XYSingletonType) {
    //非单例页面,vc可以循环进栈;
    XYSingletonTypeNone = 0,
    //单例页面:发现栈中已有时,popTo此vc;例如首页vc
    XYSingletonTypeRetop,
    //单例页面:发现栈中已有时,把此vc提到栈顶;例如登录注册页
    XYSingletonTypeReuse,
    //单例页面:发现栈中已有时,remove栈中vc再把新new的vc进行push;例如camera页
    XYSingletonTypeRenew
};

具体使用如下:

XYUrlAction *action = [XYUrlAction actionWithURL:[NSURL URLWithString:@"xiaoying://aTest"]];
XYNaviTransition *naviTransiton = [XYNaviTransition new];
naviTransiton.animation = XYNaviAnimationTransition;
naviTransiton.transition.type = kCATransitionPush;
naviTransiton.transition.subtype = kCATransitionFromTop;
naviTransiton.transition.duration = 0.3;
action.naviTransition = naviTransiton;
action.singletonType = XYSingletonTypeReuse; //设置单例的type
[action setBool:YES forKey:@"bool_value"];
[[XYPageMaster master] openURLAction:action];

当然你也可以进行url设置:

XYUrlAction *action = [XYUrlAction actionWithURL:[NSURL URLWithString:@"xiaoying://aTest?singletonType=3"]];
XYNaviTransition *naviTransiton = [XYNaviTransition new];
naviTransiton.animation = XYNaviAnimationTransition;
naviTransiton.transition.type = kCATransitionPush;
naviTransiton.transition.subtype = kCATransitionFromTop;
naviTransiton.transition.duration = 0.3;
action.naviTransition = naviTransiton;
// action.singletonType = XYSingletonTypeReuse; //设置单例的type
[action setBool:YES forKey:@"bool_value"];
[[XYPageMaster master] openURLAction:action];

(3)2.0版本之后如果你要实现一个单例页面,(1)中设置isSingleton仍是必须的(已经设置默认YES),如果你想自定义Type,你需要再

设置singletonType中的非XYSingletonTypeNone状态,因为组件已经进行了代码逻辑如下:

BOOL isSingleton = NO;
if ([[controller class] respondsToSelector:@selector(isSingleton)]) {
    isSingleton = [[controller class] isSingleton];
}
XYSingletonType singletonType = urlAction.singletonType;
if (isSingleton && singletonType != XYSingletonTypeNone) {
    [self pushSingletonViewController:controller withURLAction:urlAction];
} else {
    [self openViewController:controller withURLAction:urlAction];
}

6、自定义动画的设置

2.0 版本已经支持CATransition自定义动画设置,如果传统的push动画满足不了你,你可以仿照以下代码进行自定义转场动画设置:

XYUrlAction *action = [XYUrlAction actionWithURL:[NSURL URLWithString:@"xiaoying://aTest?singletonType=3"]];
XYNaviTransition *naviTransiton = [XYNaviTransition new];
naviTransiton.animation = XYNaviAnimationTransition;
naviTransiton.transition.type = kCATransitionPush;
naviTransiton.transition.subtype = kCATransitionFromTop;
naviTransiton.transition.duration = 0.3;
action.naviTransition = naviTransiton;
[[XYPageMaster master] openURLAction:action];

当然,对于XYSingletonType的几种状态,如果你不设置transition,内部也有些内置的defaultTransition。

7、面向接口的改进:

中间经过业务同学的建议,提供了面向接口的优化:

/**
 此方法会完成url解析、参数传递、跳转,带block回调;
 */
- (void)openUrl:(nonnull NSString *)url action:(nonnull void(^)(XYUrlAction * _Nullable action))actionBlock;
[[XYPageMaster master] openUrl:@"xiaoying://testVC" action:^(XYUrlAction *action) { 
     [action setString:@"hello world" forKey:MyStringKey];
}];

此方法使用起来更加简洁;

8、注意事项

(1)XYPageMaster所有操作应该在主线程中进行;

(2)组件里默认都是单例页面,单例的设置是由isSingleton和XYSingletonType两者同时来控制的;

(3)如果你需要跳转的单例VC已经在栈的最上面,跳转逻辑会直接return;

(3)如果你的跳转或者对viewcontroller的操作,需要一个navigationContorller,请尽可能使用XYPageMaster中的navigationContorller;

(4)如果你需要presentVC:这种独立rootNavigationContorller之外的操作,请及时dismiss你的VC,以防影响到可能的外部的url跳转带来的push和pop操作;对于业务中的已有presentVC操作,须逐步修改掉;

(5)对于xib的跳转暂不支持,如果必须要跳转,openURLAction:result:这个方法仍可以使用;

(6)进行URL传递Json参数时,需要对Json字符串进行UTF8编码,否则[NSURL URLWithString:urlString]可能会生成NSURL对象失败;

(7)文档可能会有落后,代码不断更新,一切以最终代码逻辑为准。

猜你喜欢

转载自blog.csdn.net/lizitao/article/details/82286690
今日推荐