全部產品
Search
文件中心

Mobile Platform as a Service:mPaaS 架構介紹

更新時間:Jul 13, 2024

mPaaS iOS 架構源自支付寶用戶端的開發架構,基於 Framework 的設計思想,將業務隔離成相對獨立的模組,並著力追求模組與模組之間高內聚、低耦合。

mPaaS iOS 架構直接接管應用的生命週期,負責整個應用啟動託管、應用生命週期管理、處理與分發 UIApplication 的代理事件、統一管理各業務模組(微應用和服務)等。

本文將對 mPaaS iOS 架構進行詳細的介紹。

啟動託管

通過程式 main 函數的替換,直接接管應用的生命週期,整個啟動的過程如下:

main -> DFClientDelegate -> 開啟 Launcher 應用

應用生命週期管理

mPaaS 架構接入之後,完全替代了 AppDelegate 的角色,整個應用的生命週期由架構進行管理,但是使用者依然可以實現應用生命週期各個階段對應的代理方法,UIApplicationDelegate 中的所有代理方法,架構都提供了等價的接入方式,只需要在 Category 中覆蓋對應的方法即可。

架構提供的生命週期方法聲明如下,具體內容可以查看 DTFrameworkInterface.h 檔案。

/**
 *  架構有一些自己的初始化邏輯在didFinishLaunching裡需要實現,但會在執行之前回調該方法。
 */
- (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

/**
 *  架構回調該方法,讓接入應用可以接管自己的didFinishLaunching邏輯。
 *  並且當返回DTFrameworkCallbackResultReturnYES或DTFrameworkCallbackResultReturnNO時,直接給系統返回,不再執行接下來的邏輯。
 *  這個方法在架構啟動BootLoader前回調,應用可以通過返回DTFrameworkCallbackResultReturnYES或DTFrameworkCallbackResultReturnNO讓架構提前退出,不運行預設的BootLoader。
 *  使用架構內部的預設實現即可,通常不需要覆蓋。
 *
 *  @return 是繼續讓架構執行,還是直接給系統返回YES或NO
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

/**
 *  架構有一些自己的初始化邏輯在didFinishLaunching裡需要實現,但會在所有邏輯完成後回調該方法。
 */
- (void)application:(UIApplication *)application afterDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

/**
 *  架構會率先回調該方法,讓接入應用可以預先處理通知訊息。
 *  當返回DTFrameworkCallbackResultContinue時,架構會把通知訊息通過UIApplicationDidReceiveRemoteNotification廣播給全域監聽者。並調用completionHandler(UIBackgroundFetchResultNoData)。
 *  當返回DTFrameworkCallbackResultReturn時,表示接入應用已經完全處理完通知訊息,架構中止執行之後的邏輯。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;

/**
 *  架構會率先回調該方法,讓接入應用可以預先處理通知訊息。
 *  當返回DTFrameworkCallbackResultContinue時,架構會把通知訊息通過UIApplicationDidReceiveLocalNotification廣播給全域監聽者。
 *  當返回DTFrameworkCallbackResultReturn時,表示接入應用已經完全處理完通知訊息,架構中止執行之後的邏輯。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;

/**
 *  架構會率先回調該方法,讓接入應用可以預先處理通知訊息。
 *  當返回DTFrameworkCallbackResultContinue時,架構會把通知訊息通過UIApplicationDidReceiveLocalNotification廣播給全域監聽者。並調用completionHandler()。
 *  當返回DTFrameworkCallbackResultReturn時,表示接入應用已經完全處理完通知訊息,架構中止執行之後的邏輯。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler;

/**
 *  架構會率先回調該方法,讓接入應用可以拿到deviceToken。
 *  當返回DTFrameworkCallbackResultContinue時,架構會把deviceToken通過UIApplicationDidRegisterForRemoteNotifications廣播給全域監聽者。
 *  當返回DTFrameworkCallbackResultReturn時,表示接入應用已經完全處理完,架構中止執行之後的邏輯。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;

/**
 *  當取deviceToken失敗時,架構率先回調該方法。
 *  當返回DTFrameworkCallbackResultContinue時,架構繼續執行,目前無其它邏輯。
 *  當返回DTFrameworkCallbackResultReturn時,架構中止之後的邏輯,目前無其它邏輯。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;

/**
 *  架構會先給分享組件(如果有,並且shouldAutoactivateShareKit返回YES)通知,如果分享組件處理不了,再回調該方法,由接入應用處理openURL。
 *  當返回DTFrameworkCallbackResultReturnYES或DTFrameworkCallbackResultReturnNO時,架構直接給系統返回,不再執行接下來的邏輯。
 *  當返回DTFrameworkCallbackResultContinue時,繼續由架構處理URL,並分發給SchemeHandler等類來處理。
 *
 *  這個方法相比系統方法,多了一個newURL參數,允許應用在處理後,返回一個不同的url。如果函數整體返回DTFrameworkCallbackResultContinue,並且給newURL賦值,架構會使用新的URL來做後續處理。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application openURL:(NSURL *)url newURL:(NSURL **)newURL sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;

/**
 *  架構率先回調該方法。
 *  當返回DTFrameworkCallbackResultContinue時,架構繼續執行,目前無其它邏輯。
 *  當返回DTFrameworkCallbackResultReturn時,架構中止之後的邏輯,目前無其它邏輯。
 */
- (DTFrameworkCallbackResult)applicationWillResignActive:(UIApplication *)application;

/**
 *  架構率先回調該方法。
 *  當返回DTFrameworkCallbackResultContinue時,架構繼續執行,目前無其它邏輯。
 *  當返回DTFrameworkCallbackResultReturn時,架構中止之後的邏輯,目前無其它邏輯。
 */
- (DTFrameworkCallbackResult)applicationDidEnterBackground:(UIApplication *)application;

/**
 *  架構率先回調該方法。
 *  當返回DTFrameworkCallbackResultContinue時,架構繼續執行,目前無其它邏輯。
 *  當返回DTFrameworkCallbackResultReturn時,架構中止之後的邏輯,目前無其它邏輯。
 */
- (DTFrameworkCallbackResult)applicationWillEnterForeground:(UIApplication *)application;

/**
 *  架構先回調該方法。
 *  當返回DTFrameworkCallbackResultContinue時,架構繼續執行,給分享組件事件(如果有,並且shouldAutoactivateShareKit返回YES)。並且當整個應用沒被載入時,調用BootLoader
 *  當返回DTFrameworkCallbackResultReturn時,架構中止之後的邏輯,目前無其它邏輯。
 */
- (DTFrameworkCallbackResult)applicationDidBecomeActive:(UIApplication *)application;

/**
 *  架構率先回調該方法。
 *  當返回DTFrameworkCallbackResultContinue時,架構繼續執行,目前無其它邏輯。
 *  當返回DTFrameworkCallbackResultReturn時,架構中止之後的邏輯,目前無其它邏輯。
 */
- (DTFrameworkCallbackResult)applicationWillTerminate:(UIApplication *)application;

/**
 *  架構率先回調該方法。
 *  當返回DTFrameworkCallbackResultContinue時,架構繼續執行,目前無其它邏輯。
 *  當返回DTFrameworkCallbackResultReturn時,架構中止之後的邏輯,目前無其它邏輯。
 */
- (DTFrameworkCallbackResult)applicationDidReceiveMemoryWarning:(UIApplication *)application;

/**
 *  架構率先回調該方法,接入應用可以先行處理Watch的訊息。
 *  當返回DTFrameworkCallbackResultContinue時,架構會把Watch訊息通過UIApplicationWatchKitExtensionRequestNotifications廣播給全域監聽者。
 *  當返回DTFrameworkCallbackResultReturn時,表示接入應用已經完全處理完通知訊息,架構中止執行之後的邏輯。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply;

/**
 *  架構率先回調該方法,接入應用可以先行處理訊息。
 *  當返回DTFrameworkCallbackResultContinue時,架構會把訊息通過UIApplicationUserActivityNotifications廣播給全域監聽者,並最後給系統返回NO。
 *  當返回DTFrameworkCallbackResultReturnYES或DTFrameworkCallbackResultReturnNO時,架構直接給系統返回,不再執行接下來的邏輯。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler;

/**
 *  架構率先回調該方法,接入應用可以先行處理3D Touch快捷入口的訊息。
 *  當返回DTFrameworkCallbackResultContinue時,架構會處理shortcutItem帶過來的URL,並最後調用completionHandler()返回是否已經處理。
 *  當返回DTFrameworkCallbackResultReturn時,架構直接給系統返回,不再執行接下來的邏輯。
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler;

/**
 *  Background Fetch 機制回調
 *  必須在30s內回調completionHandler,否則進程將被terminate
 *  若要啟用此機制,需要先配置Background Modes的fetch選項。其次在didFinishLaunching中調用下面的方法。更多資訊參考文檔。
 *  [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
 *  預設實現為空白,需要接入方自己處理。
 */
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;

應用模組劃分

mPaaS 架構內定義了微應用和服務的概念來進行模組間的劃分。其中,以是否有 UI 介面作為標準,Framework 將不同的模組劃分為 微應用服務,通過 架構上下文 進行微應用與服務的生命週期管理。

中文

英文

解釋

微應用

MicroApplication

用戶端運行期帶有使用者介面的微應用

服務

Service

用戶端運行期提供的輕量級抽象服務

架構上下文

Context

用戶端微組件運行期上下文

本文主要介紹微應用、服務、架構內容相關的概念。有關具體的使用方法,查看 建立微應用

微應用

在基於 mPaaS iOS 架構開發應用的過程中,一般會將帶有 UI 介面的獨立業務設定為一個微應用(如支付寶中的轉賬、手機儲值等),與其他的業務隔離開,實現各個微應用之間高度獨立,不相互依賴。

微應用也有自己的生命週期,整個過程如下:

applicationSchedule

微應用整個生命週期的回調方法,具體內容參考 DTMicroApplicationDelegate.h 檔案。

@required
/**
 * 請求應用對象的代理返回根視圖控制器。
 *
 * @param application 應用對象。
 *
 * @return 應用的根視圖控制器。
 */
- (UIViewController *)rootControllerInApplication:(DTMicroApplication *)application;

@optional

/**
 * 通知應用代理,應用對象已經對經被執行個體化。
 *
 * @param application 應用對象。
 */
- (void)applicationDidCreate:(DTMicroApplication *)application;

/**
 * 通知應用代理,應用將要啟動。
 *
 * @param application 啟動的應用對象。
 * @param options 應用運行參數。
 */
- (void)application:(DTMicroApplication *)application willStartLaunchingWithOptions:(NSDictionary *)options;

/**
 * 通知應用代理,應用已啟動。
 *
 * @param application 啟動的應用對象。
 */
- (void)applicationDidFinishLaunching:(DTMicroApplication *)application;

/**
 * 通知應用代理,應用即將暫停進入後台運行。
 *
 * @param application 啟動的應用對象。
 */
- (void)applicationWillPause:(DTMicroApplication *)application;

/**
 * 通知應用代理,應用將被重新啟用。
 *
 * @param application 要啟用的應用對象。
 */
- (void)application:(DTMicroApplication *)application willResumeWithOptions:(NSDictionary *)options;

/**
 * 通知應用代理,應用已經被啟用。
 *
 * @param application 要啟用的應用對象。
 */
- (void)applicationDidResume:(DTMicroApplication *)application;

/**
 * 通知應用代理,應用已經被啟用。
 *
 * @param application 要啟用的應用對象,帶上參數的版本。
 */
- (void)application:(DTMicroApplication *)application didResumeWithOptions:(NSDictionary *)options;

/**
 * 通知應用的代理,應用將要退出。
 *
 * @param application 應用對象。
 */
- (void)applicationWillTerminate:(DTMicroApplication *)application;

/**
 * 通知應用的代理,應用將要退出。
 *
 * @param application 應用對象。
 * @param animated 是否以動畫方式退出。
 */
- (void)applicationWillTerminate:(DTMicroApplication *)application animated:(BOOL)animated;

/**
 * 詢問應用的代理,應用是否可以退出。
 * 注意:只有特殊情況才返回 NO;如果預設是 YES,則可以退出。
 *
 * @param application 應用對象。
 *
 * @return 是否可以退出。
 */
- (BOOL)applicationShouldTerminate:(DTMicroApplication *)application;

服務

mPaaS iOS 架構將沒有 UI 介面的 Framework 稱為服務,其與微應用的區別如下:

  • 微應用是獨立的商務程序,服務則用來提供泛型服務。

  • 服務有狀態,一旦啟動後,其在整個用戶端的生命週期中一直存在,任何時候都可以被擷取;微應用在退出後即被銷毀。

服務管理相關的介面,具體內容參考 DTService.h 檔案。

@required

/**
 * 啟動一個服務。
 * 注意:
 * 架構在完成初始化操作後,會調用該方法。
 * 在一個服務裡面,要先調用該方法,之後才能去啟動應用。
 */
- (void)start;

@optional

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

/**
 * 服務將要銷毀。
 */
- (void)willDestroy;

架構上下文(Context)

架構上下文(Context)是整個用戶端架構的控制中心,統一管理各個微應用和服務之間的互動與跳轉,主要負責:

  • 提供啟動微應用的介面,可通過名字快速尋找、關閉、管理微應用的跳轉等。

  • 提供啟動服務的介面,管理服務的註冊、發現和反註冊。

微應用管理

  • 微應用管理相關介面,具體內容參考 DTContext.h 檔案。

/**
 * 根據指定的名稱啟動一個應用。
 *
 * @param name 要啟動的應用程式名稱。
 * @param params 啟動應用時,需要轉遞給另一個應用的參數。
 * @param animated 指定啟動應用時,是否顯示動畫。
 *
 * @return 應用啟動成功返回 YES,否則返回 NO。
 */
- (BOOL)startApplication:(NSString *)name params:(NSDictionary *)params animated:(BOOL)animated;

/**
 * 根據指定的名稱啟動一個應用。
 *
 * @param name 要啟動的應用程式名稱。
 * @param params 啟動應用時,需要轉遞給另一個應用的參數。
 * @param launchMode 指定 App 的啟動方式。
 *
 * @return 應用啟動成功返回 YES,否則返回 NO。
 */
- (BOOL)startApplication:(NSString *)name params:(NSDictionary *)params launchMode:(DTMicroApplicationLaunchMode)launchMode;

/**
 * 尋找一下指定的應用。
 *
 * @param name 要尋找的應用程式名稱。
 *
 * @return 如果指定的應用已在應用棧中,則返回對應的應用對象。否則返回 nil。
 */
- (DTMicroApplication *)findApplicationByName:(NSString *)name;

/**
 * 返回當前在棧頂的應用,即對使用者可見的應用。
 * 
 * @return 當前可見的應用。
 */
- (DTMicroApplication *)currentApplication;
  • 微應用啟動過程:

app-launcher

服務管理

  • 服務管理相關介面,具體內容參考 DTContext.h 檔案。

/**
 * 根據指定的名稱尋找服務。
 *
 * @param name 服務名
 *
 * @return 如果找到指定名稱的服務,則返回一個服務物件,否則返回空。
 */
- (id)findServiceByName:(NSString *)name;

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

/**
 * 反註冊一個已存在的服務。
 *
 * @param name 服務名。
 */
- (void)unregisterServiceForName:(NSString *)name;
  • 服務啟動過程:

    service-Launcher

架構上下文管理微應用與服務的 UML 類圖如下:

uml