美文网首页
BeeHive学习总结

BeeHive学习总结

作者: Easy_VO | 来源:发表于2017-02-17 11:11 被阅读146次

    设计原则:

    解耦,避免对接口依赖
    使用invoke以及动态链接库实现对接口的解耦

    BeeHive每个模块都是有生命周期事件的,用来与宿主环境进行必要的交互
    事件分为三种类型:

    系统事件  
    通用事件
    业务自定义事件
    

    1.1 系统事件

    系统事件通常是Application生命周期事件,例如DidBecomeActive、WillEnterBackground等。
    系统事件基本工作流如下:


    imageimage

    1.2 通用事件

    在系统事件的基础之上,扩展了应用的通用事件,例如modSetup、modInit等,可以用于编码实现各插件模块的设置与初始化。

    扩展的通用事件如下:


    通用事件通用事件

    1.3 业务自定义事件

    如果觉得系统事件、通用事件不足以满足需要,可以通过继承 BHAppdelegate来扩展自己的事件

    2. 模块注册

    模块注册的方式有静态注册与动态注册两种。

    2.1 静态注册

    通过在BeeHive.plist文件中注册符合BHModuleProtocol协议模块类:


    plistplist

    2.2 动态注册

    2.2 动态注册

    @implementation HomeModule
    
    BH_EXPORT_MODULE()  // 声明该类为模块入口
    
    @end
    

    在模块入口类实现中 使用BH_EXPORT_MODULE()宏声明该类为模块入口实现类。

    2.3 异步加载

    如果设置模块导出为BH_EXPORT_MODULE(YES),则会在启动之后第一屏内容展现之前异步执行模块的初始化,可以优化启动时时间消耗

    3. 编程开发

    BHModuleProtocol为各个模块提供了每个模块可以Hook的函数,用于实现插件逻辑以及代码实现。

    3.1 设置环境变量

    通过context.env可以判断我们的应用环境状态来决定我们如何配置我们的应用。

    -(void)modSetup:(BHContext *)context
    {
    switch (context.env) {
        case BHEnvironmentDev:
        //....初始化开发环境
        break;
        case BHEnvironmentProd:
        //....初始化生产环境
        default:
        break;
    }
    }
    

    3.2 模块初始化

    如果模块有需要启动时初始化的逻辑,可以在modInit里编写,例如模块注册一个外部模块可以访问的Service接口

    -(void)modInit:(BHContext *)context
    {
    //注册模块的接口服务
    [[BeeHive shareInstance] registerService:@protocol(UserTrackServiceProtocol) service:[BHUserTrackViewController class]];
    }
    

    3.3 处理系统事件

    系统的事件会被传递给每个模块,让每个模块自己决定编写业务处理逻辑,比如3D-Touch功能

    -(void)modQuickAction:(BHContext *)context
    {
    [self process:context.shortcutItem handler:context.scompletionHandler];
    }
    

    3.4 模间调用

    通过处理Event编写各个业务模块可以实现插件化编程,各业务模块之间没有任何依赖,core与module之间通过event交互,实现了插件隔离。但有时候我们需要模块间的相互调用某些功能来协同完成功能。

    通常会有三种形式的接口访问形式:

    基于接口的实现Service访问方式(Java spring框架实现)
    基于函数调用约定实现的Export Method(PHP的extension,ReactNative的扩展机制)
    基于跨应用实现的URL Route模式(iPhone App之间的互访)
    我们目前实现了第一种方式,后续会逐步实现后两种方式。

    基于接口Service访问的优点是可以编译时检查发现接口的变更,从而及时修正接口问题。缺点是需要依赖接口定义的头文件,通过模块增加得越多,维护接口定义的也有一定工作量。

    3.4.1 定义接口

    以为HomeServiceProtocol
    为例。

    @protocol HomeServiceProtocol <NSObject, BHServiceProtocol>- (void)registerViewController:(UIViewController *)vc title:(NSString *)title iconName:(NSString *)iconName;
    @end
    

    注册Service
    有两种方式:
    API注册

    [[BeeHive shareInstance] registerService:@protocol(HomeServiceProtocol) service:[BHViewController class]];
    

    BHService.plist注册

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
     <dict>
     <key>HomeServiceProtocol</key> <string>BHViewController</string>
     </dict>
    </plist>
    

    3.4.3 调用Service

    #import "BHService.h"id< HomeServiceProtocol > homeVc = [[BeeHive shareInstance] createService:@protocol(HomeServiceProtocol)];
    

    3.5 单例与多例

    对于有些场景下,我们访问每个声明Service
    的对象,希望对象能保留一些状态,那我们需要声明这个Service
    对象是一个单例对象。
    我们只需要在Service
    对象中实现事件函数
    声明

    -(BOOL) singleton{
     return YES;
    }
    

    通过createService
    获取的对象则为单例对象,如果实现上面函数返回的是NO
    ,则createService
    返回的是多例。

    id< HomeServiceProtocol > homeVc = [[BeeHive shareInstance] createService:@protocol(HomeServiceProtocol)];
    

    3.6 上下文环境Context

    初始化设置应用的项目信息,并在各模块间共享整个应用程序的信息

      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    [BHContext shareInstance].env = BHEnvironmentDev; //定义应用的运行开发环境
    [BHContext shareInstance].application = application;
    [BHContext shareInstance].launchOptions = launchOptions;
    [BHContext shareInstance].moduleConfigName = @"BeeHive.bundle/CustomModulePlist";//可选,默认为BeeHive.bundle/BeeHive.plist
    [BHContext shareInstance].serviceConfigName =  @"BeeHive.bundle/CustomServicePlist";//可选,默认为BeeHive.bundle/BHService.plist
    [[BeeHive shareInstance] setContext:[BHContext shareInstance]];
    
    [super application:application didFinishLaunchingWithOptions:launchOptions];
    
    id<HomeServiceProtocol> homeVc = [[BeeHive shareInstance] createService:@protocol(HomeServiceProtocol)];
    
    if ([homeVc isKindOfClass:[UIViewController class]]) {
        UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:(UIViewController*)homeVc];
    
        self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        self.window.rootViewController = navCtrl;
        [self.window makeKeyAndVisible];
    }
    
    return YES;
    } [self.window makeKeyAndVisible]; } return YES;}

    相关文章

      网友评论

          本文标题:BeeHive学习总结

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