支付寶客戶端架構解析:iOS 容器化框架初探

1. 前言

由本章節開始,咱們將從支付寶客戶端的架構設計方案入手,細分拆解客戶端在「容器化框架設計」、「網絡優化」、「性能啓動優化」、「自動化日誌收集」、「RPC 組件設計」、「移動應用監控、診斷、定位」等具體實現,帶領你們進一步瞭解支付寶在客戶端架構上的迭代與優化歷程。數組

本節將介紹支付寶 iOS 容器化框架設計的基本思路。bash

2. 容器化實現概覽

在 mPaaS 開篇介紹中已經和你們分享過《模塊化與解耦式開發在螞蟻金服 mPaaS 中的實踐》:經過容器化開發框架將業務隔離成相對獨立的模塊,並着力追求模塊與模塊之間高內聚、低耦合,所以咱們實現了靈活的插件式開發,並得以將業務劃分爲上千個獨立工程。網絡

mPaaS iOS 框架源自於支付寶客戶端,爲了實現這種上千個工程之間的低耦合和相關依賴調用,mPaaS 框架直接接管了 App 的生命週期,負責整個 App 啓動託管、App 生命週期管理、處理與分發 UIApplication 的代理事件。 mPaaS 框架提供了容器化環境,業務開發人員在這個容器化環境中使用 微應用服務 進行具體的業務需求開發。架構

mPaaS iOS 框架-w400

微應用服務 是 mPaaS 框架內定義的概念,主要是用來進行業務模塊間的劃分。按照是否有 UI 界面做爲標準,mPaaS 框架將不一樣的業務模塊劃分爲 微應用服務微應用 是 APP 運行期間帶有用戶界面的業務模塊;服務 是 App 運行期由業務提供的輕量級抽象服務。在 mPaaS 框架中,經過 框架上下文Context 進行 微應用服務 的生命週期管理。app

3. 應用生命週期管理

經過修改 main.m 函數的實現,mPaaS 框架使用本身的 ClientDelegate 類接管了 UIApplicationDelegate 中各類 App 生命週期。mPaaS 框架接入以後,ClientDelegate 徹底替代了通常工程中的 AppDelegate 的角色,從而實現了整個應用的生命週期都是由框架進行管理。框架

int main(int argc, char * argv[]) {
    @autoreleasepool {
        // Now use mPaaS framework
        return UIApplicationMain(argc, argv, @"Application", @"ClientDelegate"); 
    }
}

複製代碼

爲了方便用戶獲取 App 生命週期來開發自定義功能,mPaaS 框架提供了 DTFrameworkInterface 類裏面實現了 UIApplicationDelegate 中全部代理方法的等價接入方式,只須要在 DTFrameworkInterface 的 Category 中覆蓋對應的方法便可。模塊化

例以下面常見的 UIApplicationDelegate 代理方法:函數

@protocol UIApplicationDelegate<NSObject>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

- (void)applicationDidBecomeActive:(UIApplication *)application;

- (void)applicationWillResignActive:(UIApplication *)application;

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation;

@end
複製代碼

DTFrameworkInterface 中都提供了對應的方法:post

typedef NS_ENUM(NSInteger, DTFrameworkCallbackResult)
{
    DTFrameworkCallbackResultContinue   = 0,  // 繼續執行
    DTFrameworkCallbackResultReturn     = 1,  // 中斷執行
    DTFrameworkCallbackResultReturnYES  = 2,  // 中斷以後的邏輯,並返回 YES
    DTFrameworkCallbackResultReturnNO   = 3,  // 中斷以後的邏輯,並返回 NO
};

@interface DTFrameworkInterface : NSObject

#pragma mark - 應用配置,微應用配置、服務配置、Scheme 處理器配置,可用 Category 覆蓋
- (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (void)application:(UIApplication *)application afterDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

- (DTFrameworkCallbackResult)applicationDidBecomeActive:(UIApplication *)application;

- (DTFrameworkCallbackResult)applicationWillResignActive:(UIApplication *)application;

- (DTFrameworkCallbackResult)application:(UIApplication *)application
                                 openURL:(NSURL *)url
                                  newURL:(NSURL **)newURL
                       sourceApplication:(NSString *)sourceApplication
                              annotation:(id)annotation;
@end
複製代碼

因爲 mPaaS 框架有一些本身的初始化邏輯須要實現,在 DTFrameworkInterface 中額外提供了 beforeDidFinishLaunchingWithOptionsafterDidFinishLaunchingWithOptions 方法,方便用戶在 App 啓動時肯定的時間執行本身的初始化代碼。性能

DTFrameworkInterfaceafterDidFinishLaunchingWithOptions 以前會啓動 BootLoader,執行 mPaaS 框架的初始化邏輯。在嵌入式操做系統中,BootLoader 的做用是初始化硬件設備,以便爲最終調用操做系統內核準備好正確的環境。相似的在 mPaaS 框架中,BootLoader用來初始化整個 mPaaS 框架環境,默認實現爲依次執行下面的流程:

  • 建立window
  • 建立主NavigationController
  • 運行那些只運行一次就能夠,而且須要率先啓動的服務
  • 啓動其它全部非lazyload的服務
  • 啓動在ServicesMap的"[AUTOSTART]"數組中指定須要自動啓動的服務分組
  • 顯示主Window
  • 啓動 Launcher 微應用,顯示出首頁

這樣就完成了 mPaaS 框架的初始化和首頁的顯示。

後面將詳細介紹其中關鍵的3個概念:微應用服務框架上下文 Context

4. 微應用

微應用就是帶 UI 界面的獨立業務模塊,其中最特殊的一個微應用是 Launcher 微應用,Launcher 做爲 App 啓動以後第一個打開的微應用,通常用來建立 App 首頁。在 mPaaS 框架中,各個微應用之間是高度獨立、不相互依賴的。

微應用 經過 plist 文件配置來進行註冊。配置微應用時須要指定 delegate 對應的類名、微應用的描述 description 以及打開微應用時使用的 name。這樣 框架上下文 Context 經過微應用的 name 就能夠打開指定的微應用。

微應用註冊方式-w500

爲了方便業務開發,每一個 微應用 也存在生命週期。微應用的生命週期,是模仿 iOS App 的生命週期來作的。每一個微應用須要實現本身的 DTMicroApplicationDelegate 代理,這個相似於 iOS App 中實現的 Appdelege 類。

微應用生命週期-w550

對於具體業務開發而言 微應用 的開發和一個完整的 App 同樣,每一個 微應用 負責控制本身應用內的頁面堆棧,並根據 微應用 的生命週期執行相應的操做。在 mPaaS 框架中,全部的 微應用 都是運行在 mPaaS 框架提供的容器中,其不須要關注 App 的生命週期。對於一些特殊的業務場景,mPaaS 支持建立微應用的多個實例。

mPaaS 微應用結構-w500

5. 服務

服務微應用 不一樣地方在於其沒有 UI 界面,是在後臺執行。一旦服務啓動後,其在整個客戶端的生命週期中一直存在,所以服務通常用於給微應用提供通用服務,好比執行某個功能或者獲取數據等。

一個常見的服務是用戶登錄狀態服務,每一個微應用能夠經過這個服務來獲取到用戶的登陸狀態和用戶信息。

服務 也是經過 plist 文件配置來進行註冊。服務註冊時須要提供服務的惟一標識 name 和對應的實現類 class 類名。框架在建立 服務 時會利用 Objective-C 語言的運行時機制建立 服務 實現類的實例。lazyLoading 用來控制是否延遲加載該類。若是是延遲加載,在框架啓動時該 服務 並不會實例化,只有在用到該 服務 時纔會實例化並啓動。若是是非延遲加載,則在框架啓動時會啓動該服務。

因爲服務的特殊性,在 mPaaS 中同時提供了 ServicesMap 來批量註冊類,ServicesMap 中的 [AUTOSTART] 用來講明哪些組的服務須要在 App 啓動的時候最早啓動。

服務註冊方式-w500

這種分級啓動服務的特色能夠有效控制 App 的啓動時間,提供很好的用戶體驗。

每一個服務都須要實現 服務 接口:

@required

/**
 * 啓動一個服務。
 * 注意:
 * 框架在完成初始化操做後,會調用該方法。
 * 若是一個服務要啓動一個應用,必須在該方法被調用以後,才能啓動其它的應用。
 */
- (void)start;

@optional

/**
 * 建立服務完成。
 */
- (void)didCreate;

/**
 * 服務將要銷燬。
 */
- (void)willDestroy;
複製代碼

在增長了 服務 以後,整個 App 的結構以下圖所示。後臺的服務成爲各個 微應用 之間溝通的橋樑。

mPaaS 容器化結構-w500

6. 框架上下文 Context

經過前面的介紹,你們已經對 微應用服務 有了深刻的瞭解。在 mPaaS 框架中,框架上下文Context 承擔了一個調度員的角色,負責各個 微應用服務 的調度、通訊管理,這樣就實現了每一個 微應用 的打開、頁面推棧以及關閉不會影響 App 其餘 微應用 模塊。

經過 mPaaS 框架提供的 DTContext * DTContextGet() 函數能夠獲取到框架上下文Context 對象。一個簡化的 Context 類實現以下:

@interface Context : NSObject

@property(nonatomic, strong) UIWindow *window;
@property(nonatomic, strong) UINavigationController *navigationController;

// 根據指定的名稱啓動一個微應用
- (BOOL)startApplication:(NSString *)name params:(NSDictionary *)params animated:(BOOL)animated;

// 逆向遍歷微應用棧,返回最新的微應用對象。
- (DTMicroApplication *)findApplicationByName:(NSString *)name;

// 根據指定的名稱查到一個服務
- (id)findServiceByName:(NSString *)name;

// 註冊一個服務
- (BOOL)registerService:(id)service forName:(NSString *)name;

// 反註冊一個已存在的服務
- (void)unregisterServiceForName:(NSString *)name;
@end
複製代碼

對於業務開發人員,能夠經過 框架上下文 Context 獲取到主 window、啓動指定的 微應用、獲取一個 服務、動態註冊與反註冊 服務,從而實現業務之間的鏈接。

7. 小結

經過本節內容,咱們初步瞭解了 mPaaS 在 iOS 端容器化框架的設計思路,經過 微應用服務 的方式完成業務模塊之間的解耦和調用。框架上下文 Context 做爲一個迷你的容器操做系統,爲 微應用服務 的運行提供了所需的容器化環境,保證了獨立的業務開發流程和流暢的用戶體驗。

歡迎你們體驗 mPaaS 容器化開發框架,期待你們的反饋與交流。

往期閱讀

《支付寶客戶端架構解析:Android容器化框架初探》

《開篇 | 模塊化與解耦式開發在螞蟻金服 mPaaS 深度實踐探討》

《口碑 App 各 Bundle 之間的依賴分析指南》

《源碼剖析 | 螞蟻金服 mPaaS 框架下的 RPC 調用歷程》

《支付寶移動端動態化方案實踐》

關注咱們公衆號,得到第一手 mPaaS 技術實踐乾貨

QRCode
相關文章
相關標籤/搜索