github下載地址:https://github.com/alibaba/BeeHive
BeeHive 詳細(xì)介紹
BeeHive是用于iOS的app模塊化編程的框架實(shí)現(xiàn)方案,吸收了Spring框架service的理念來實(shí)現(xiàn)模塊間的API耦合?;驹砣缦?

實(shí)現(xiàn)以下特性
- 插件化的模塊開發(fā)運(yùn)行框架
- 模塊具體實(shí)現(xiàn)與接口調(diào)用分離
- 模塊生命周期管理,擴(kuò)展了應(yīng)用的系統(tǒng)事件
因?yàn)榛赟pring的Service理念,雖然可以使模塊間的具體實(shí)現(xiàn)與接口解耦,但無法避免對(duì)接口類的依賴關(guān)系。
為什么不使用invoke以及動(dòng)態(tài)鏈接庫技術(shù)實(shí)現(xiàn)對(duì)接口實(shí)現(xiàn)的解耦,類似Apache的DSO的方式。
主要是考慮學(xué)習(xí)成本難度以及動(dòng)態(tài)調(diào)用實(shí)現(xiàn)無法在編譯檢查階段檢測(cè)接口參數(shù)變更等問題,動(dòng)態(tài)技術(shù)需要更高的編程門檻要求
BeeHive靈感來源于蜂窩。蜂窩是世界上高度模塊化的工程結(jié)構(gòu),六邊形的設(shè)計(jì)能帶來無限擴(kuò)張的可能。所以我們用了BeeHive來做為這個(gè)項(xiàng)目的命名。
生命周期的變化
事件
BeeHive會(huì)給每個(gè)模塊提供生命周期事件,用于與BeeHive宿主環(huán)境進(jìn)行必要信息交互 事件分為三種類型:
- 系統(tǒng)事件
- 通用事件
- 業(yè)務(wù)自定義事件
系統(tǒng)事件
系統(tǒng)事件通常是Application生命周期事件,例如DidBecomeActive、WillEnterBackground等系統(tǒng)事件基本工作流如下:

通用事件
在系統(tǒng)事件的基礎(chǔ)之上,擴(kuò)展了應(yīng)用的通用事件,例如modSetup、modInit等,可以用于編碼實(shí)現(xiàn)各插件模塊的設(shè)置與初始化
擴(kuò)展的通用事件如下:

業(yè)務(wù)自定義事件
如果覺得系統(tǒng)事件、通用事件不足以滿足需要,我們還將事件封裝簡化成BHAppdelgate,你可以通過繼承BHAppdelegate來擴(kuò)展自己的事件。
注冊(cè)
模塊注冊(cè)的方式有靜態(tài)注冊(cè)與動(dòng)態(tài)注冊(cè)兩種
-
靜態(tài)注冊(cè)
通過在BeeHive.plist文件中注冊(cè)符合BHModuleProtocol協(xié)議模塊類
靜態(tài)注冊(cè).png - 動(dòng)態(tài)注冊(cè)
@implementation HomeModule
BH_EXPORT_MODULE() //聲明該類為模塊入口
在模塊入口類實(shí)現(xiàn)中 使用BH_EXPORT_MODULE()宏聲明該類為模塊入口實(shí)現(xiàn)類
異步加載
如果設(shè)置模塊導(dǎo)出為BH_EXPORT_MODULE(YES),則會(huì)在啟動(dòng)之后第一屏內(nèi)容展現(xiàn)之前異步執(zhí)行模塊的初始化,可以優(yōu)化啟動(dòng)時(shí)時(shí)間消耗
編程開發(fā)
BHModuleProtocol為各個(gè)模塊提供了每個(gè)模塊可以hook的函數(shù),用于實(shí)現(xiàn)插件邏輯以及代碼實(shí)現(xiàn)
- 設(shè)置環(huán)境變量
通過context.env可以判斷我們的應(yīng)用環(huán)境狀態(tài)來決定我們?nèi)绾闻渲梦覀兊膽?yīng)用
-(void)modSetup:(BHContext *)context
{
switch (context.env) {
case BHEnvironmentDev:
//....初始化開發(fā)環(huán)境
break;
case BHEnvironmentProd:
//....初始化生產(chǎn)環(huán)境
default:
break;
}
}
- 模塊初始化
如果模塊有需要啟動(dòng)時(shí)初始化的邏輯,可以在modInit里編寫,例如模塊注冊(cè)一個(gè)外部模塊可以訪問的Service接口
-(void)modInit:(BHContext *)context
{
//注冊(cè)模塊的接口服務(wù)
[[BeeHive shareInstance] registerService:@protocol(UserTrackServiceProtocol) service:[BHUserTrackViewController class]];
}
- 處理系統(tǒng)事件
系統(tǒng)的事件會(huì)被傳遞給每個(gè)模塊,讓每個(gè)模塊自己決定編寫業(yè)務(wù)處理邏輯,比如3D-Touch功能
-(void)modQuickAction:(BHContext *)context
{
[self process:context.shortcutItem handler:context.scompletionHandler];
}
模間調(diào)用
通過處理Event編寫各個(gè)業(yè)務(wù)模塊可以實(shí)現(xiàn)插件化編程,各業(yè)務(wù)模塊之間沒有任何依賴,core與module之間通過event交互,實(shí)現(xiàn)了插件隔離。但有時(shí)候我們需要模塊間的相互調(diào)用某些功能來協(xié)同完成功能。 通常會(huì)有三種形式的接口訪問形式
- 基于接口的實(shí)現(xiàn)Service訪問方式(java spring框架實(shí)現(xiàn))
- 基于函數(shù)調(diào)用約定實(shí)現(xiàn)的Export Method(PHP的extension,ReactNatve的擴(kuò)展機(jī)制)
- 基于跨應(yīng)用實(shí)現(xiàn)的Url route模式(iphone app之間的互訪)
我們目前實(shí)現(xiàn)了第一種方式,后續(xù)會(huì)逐步實(shí)現(xiàn)后兩種方式
Servcie訪問
Service訪問的優(yōu)點(diǎn)是可以編譯時(shí)檢查發(fā)現(xiàn)接口的變更,從而及時(shí)修正接口問題。缺點(diǎn)是需要依賴接口定義的頭文件,通過模塊增加得越多,維護(hù)接口定義的也有一定工作量。以為HomeServiceProtocol為例
- 定義HomeServiceProtocol暴露模塊對(duì)外訪問的接口
@protocol HomeServiceProtocol <NSObject, BHServiceProtocol>
-(void)registerViewController:(UIViewController *)vc title:(NSString *)title iconName:(NSString *)iconName;
@end
- 注冊(cè)Service有三種方式
- 聲明式注冊(cè)
@implementation HomeService
BH_EXPORT_SERVICE()
- API注冊(cè)
[[BeeHive shareInstance] registerService:@protocol(HomeServiceProtocol) service:[BHViewController class]];
- BHService.plist注冊(cè)
<?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>
- 調(diào)用
#import "BHService.h"
id< HomeServiceProtocol > homeVc = [[BeeHive shareInstance] createService:@protocol(HomeServiceProtocol)];
單例與多例
對(duì)于有些場(chǎng)景下,我們?cè)L問每個(gè)聲明為service的對(duì)象,希望對(duì)象能保留一些狀態(tài),那我們需要聲明這個(gè)service對(duì)象是一個(gè)單例對(duì)象。
我們只需要在service對(duì)象中實(shí)現(xiàn)事件函數(shù)
聲明
-(BOOL) singleton
{
return YES;
}
通過createService獲取的對(duì)象則為單例對(duì)象,如果實(shí)現(xiàn)上面函數(shù)返回的是NO,則createService返回的是多例
id< HomeServiceProtocol > homeVc = [[BeeHive shareInstance] createService:@protocol(HomeServiceProtocol)];
上下文環(huán)境Context
- 初始化設(shè)置應(yīng)用的項(xiàng)目信息,并在各模塊間共享整個(gè)應(yīng)用程序的信息
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[BHContext shareInstance].env = BHEnvironmentDev; //定義應(yīng)用的運(yùn)行開發(fā)環(huán)境
[BHContext shareInstance].application = application;
[BHContext shareInstance].launchOptions = launchOptions;
[BHContext shareInstance].moduleConfigName = @"BeeHive.bundle/CustomModulePlist";//可選,默認(rèn)為BeeHive.bundle/BeeHive.plist
[BHContext shareInstance].serviceConfigName = @"BeeHive.bundle/CustomServicePlist";//可選,默認(rèn)為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;
}
更多細(xì)節(jié)可以參考Example用例
- 集成方式
use cocoapods
pod "BeeHive", '1.0.0'
