天天看點

iOS的App子產品化程式設計的架構實作方案——BeeHive0. 概述1 子產品生命周期的事件2. 子產品注冊3. 程式設計開發4. 內建方式

iOS的App子產品化程式設計的架構實作方案——BeeHive0. 概述1 子產品生命周期的事件2. 子產品注冊3. 程式設計開發4. 內建方式

0. 概述

BeeHive

是用于

iOS

App

子產品化程式設計的架構實作方案,吸收了

Spring

架構

Service

的理念來實作子產品間的

API

耦合。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#01-%E5%9F%BA%E6%9C%AC%E6%9E%B6%E6%9E%84 0.1 基本架構

iOS的App子產品化程式設計的架構實作方案——BeeHive0. 概述1 子產品生命周期的事件2. 子產品注冊3. 程式設計開發4. 內建方式

0.2 實作特性

  • 插件化的子產品開發運作架構
  • 子產品具體實作與接口調用分離
  • 子產品生命周期管理,擴充了應用的系統事件

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#03-%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99 0.3 設計原則

因為基于

Spring

Service

理念,雖然可以使子產品間的具體實作與接口解耦,但無法避免對接口類的依賴關系。

為什麼不使用

invoke

以及動态連結庫技術實作對接口實作的解耦,類似

Apache

DSO

的方式?

主要是考慮學習成本難度以及動态調用實作無法在編譯檢查階段檢測接口參數變更等問題,動态技術需要更高的程式設計門檻要求。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#04-%E9%A1%B9%E7%9B%AE%E5%90%8D%E6%9D%A5%E6%BA%90 0.4 項目名來源

BeeHive

靈感來源于蜂窩。蜂窩是世界上高度子產品化的工程結構,六邊形的設計能帶來無限擴張的可能。是以我們用了

BeeHive

來做為這個項目的命名。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#1-%E6%A8%A1%E5%9D%97%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%9A%84%E4%BA%8B%E4%BB%B6 1 子產品生命周期的事件

BeeHive

會給每個子產品提供生命周期事件,用于與

BeeHive

宿主環境進行必要資訊互動,感覺子產品生命周期的變化。

事件分為三種類型:

  • 系統事件
  • 通用事件
  • 業務自定義事件

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#11-%E7%B3%BB%E7%BB%9F%E4%BA%8B%E4%BB%B6 1.1 系統事件

系統事件通常是

Application

生命周期事件,例如

DidBecomeActive

WillEnterBackground

等。

系統事件基本工作流如下:

iOS的App子產品化程式設計的架構實作方案——BeeHive0. 概述1 子產品生命周期的事件2. 子產品注冊3. 程式設計開發4. 內建方式

1.2 通用事件

在系統事件的基礎之上,擴充了應用的通用事件,例

iOS的App子產品化程式設計的架構實作方案——BeeHive0. 概述1 子產品生命周期的事件2. 子產品注冊3. 程式設計開發4. 內建方式

1.3 業務自定義事件

如果覺得系統事件、通用事件不足以滿足需要,我們還将事件封裝簡化成

BHAppdelgate

,你可以通過繼承

BHAppdelegate

來擴充自己的事件。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#2-%E6%A8%A1%E5%9D%97%E6%B3%A8%E5%86%8C 2. 子產品注冊

子產品注冊的方式有靜态注冊與動态注冊兩種。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#21-%E9%9D%99%E6%80%81%E6%B3%A8%E5%86%8C 2.1 靜态注冊

通過在

BeeHive.plist

檔案中注冊符合

BHModuleProtocol

協定子產品類:

擴充的通用事件如下:

iOS的App子產品化程式設計的架構實作方案——BeeHive0. 概述1 子產品生命周期的事件2. 子產品注冊3. 程式設計開發4. 內建方式

2.2 動态注冊

@implementation HomeModule

BH_EXPORT_MODULE()  // 聲明該類為子產品入口

@end
      

在子產品入口類實作中 使用

BH_EXPORT_MODULE()

宏聲明該類為子產品入口實作類。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#23-%E5%BC%82%E6%AD%A5%E5%8A%A0%E8%BD%BD 2.3 異步加載

如果設定子產品導出為

BH_EXPORT_MODULE(YES)

,則會在啟動之後第一屏内容展現之前異步執行子產品的初始化,可以優化啟動時時間消耗。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#3-%E7%BC%96%E7%A8%8B%E5%BC%80%E5%8F%91 3. 程式設計開發

BHModuleProtocol

為各個子產品提供了每個子產品可以

Hook

的函數,用于實作插件邏輯以及代碼實作。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#31-%E8%AE%BE%E7%BD%AE%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F 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

互動,實作了插件隔離。但有時候我們需要子產品間的互相調用某些功能來協同完成功能。

通常會有三種形式的接口通路形式:

  1. 基于接口的實作

    Service

    通路方式(

    Java spring

    架構實作)
  2. 基于函數調用約定實作的

    Export Method

    (

    PHP

    extension

    ReactNative

    的擴充機制)
  3. 基于跨應用實作的

    URL Route

    模式(

    iPhone

    App

    之間的互訪)

我們目前實作了第一種方式,後續會逐漸實作後兩種方式。

基于接口

Service

通路的優點是可以編譯時檢查發現接口的變更,進而及時修正接口問題。缺點是需要依賴接口定義的頭檔案,通過子產品增加得越多,維護接口定義的也有一定工作量。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#341-%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3 3.4.1 定義接口

@protocol HomeServiceProtocol <NSObject, BHServiceProtocol>

- (void)registerViewController:(UIViewController *)vc title:(NSString *)title iconName:(NSString *)iconName;

@end
      

3.4.2 注冊

Service

有兩種方式:

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#api%E6%B3%A8%E5%86%8C

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;
}
      

更多細節可以參考Example用例。

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#4-%E9%9B%86%E6%88%90%E6%96%B9%E5%BC%8F 4. 內建方式

https://github.com/alibaba/BeeHive/blob/master/README-CN.md#cocoapods

cocoapods

pod "BeeHive", '1.1.1'