mPaaS 框架介紹
mPaaS iOS 框架源自支付寶客戶(hù)端的開(kāi)發(fā)框架,基于 Framework 的設(shè)計(jì)思想,將業(yè)務(wù)隔離成相對(duì)獨(dú)立的模塊,并著力追求模塊與模塊之間高內(nèi)聚、低耦合。
mPaaS iOS 框架直接接管應(yīng)用的生命周期,負(fù)責(zé)整個(gè)應(yīng)用啟動(dòng)托管、應(yīng)用生命周期管理、處理與分發(fā) UIApplication 的代理事件、統(tǒng)一管理各業(yè)務(wù)模塊(微應(yīng)用和服務(wù))等。
本文將對(duì) mPaaS iOS 框架進(jìn)行詳細(xì)的介紹。
啟動(dòng)托管
通過(guò)程序 main 函數(shù)的替換,直接接管應(yīng)用的生命周期,整個(gè)啟動(dòng)的過(guò)程如下:
main -> DFClientDelegate -> 打開(kāi) Launcher 應(yīng)用
應(yīng)用生命周期管理
mPaaS 框架接入之后,完全替代了 AppDelegate 的角色,整個(gè)應(yīng)用的生命周期由框架進(jìn)行管理,但是用戶(hù)依然可以實(shí)現(xiàn)應(yīng)用生命周期各個(gè)階段對(duì)應(yīng)的代理方法,UIApplicationDelegate 中的所有代理方法,框架都提供了等價(jià)的接入方式,只需要在 Category 中覆蓋對(duì)應(yīng)的方法即可。
框架提供的生命周期方法聲明如下,具體內(nèi)容可以查看 DTFrameworkInterface.h
文件。
/**
* 框架有一些自己的初始化邏輯在didFinishLaunching里需要實(shí)現(xiàn),但會(huì)在執(zhí)行之前回調(diào)該方法。
*/
- (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
/**
* 框架回調(diào)該方法,讓接入應(yīng)用可以接管自己的didFinishLaunching邏輯。
* 并且當(dāng)返回DTFrameworkCallbackResultReturnYES或DTFrameworkCallbackResultReturnNO時(shí),直接給系統(tǒng)返回,不再執(zhí)行接下來(lái)的邏輯。
* 這個(gè)方法在框架啟動(dòng)BootLoader前回調(diào),應(yīng)用可以通過(guò)返回DTFrameworkCallbackResultReturnYES或DTFrameworkCallbackResultReturnNO讓框架提前退出,不運(yùn)行默認(rèn)的BootLoader。
* 使用框架內(nèi)部的默認(rèn)實(shí)現(xiàn)即可,通常不需要覆蓋。
*
* @return 是繼續(xù)讓框架執(zhí)行,還是直接給系統(tǒng)返回YES或NO
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
/**
* 框架有一些自己的初始化邏輯在didFinishLaunching里需要實(shí)現(xiàn),但會(huì)在所有邏輯完成后回調(diào)該方法。
*/
- (void)application:(UIApplication *)application afterDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
/**
* 框架會(huì)率先回調(diào)該方法,讓接入應(yīng)用可以預(yù)先處理通知消息。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架會(huì)把通知消息通過(guò)UIApplicationDidReceiveRemoteNotification廣播給全局監(jiān)聽(tīng)者。并調(diào)用completionHandler(UIBackgroundFetchResultNoData)。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),表示接入應(yīng)用已經(jīng)完全處理完通知消息,框架中止執(zhí)行之后的邏輯。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
/**
* 框架會(huì)率先回調(diào)該方法,讓接入應(yīng)用可以預(yù)先處理通知消息。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架會(huì)把通知消息通過(guò)UIApplicationDidReceiveLocalNotification廣播給全局監(jiān)聽(tīng)者。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),表示接入應(yīng)用已經(jīng)完全處理完通知消息,框架中止執(zhí)行之后的邏輯。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
/**
* 框架會(huì)率先回調(diào)該方法,讓接入應(yīng)用可以預(yù)先處理通知消息。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架會(huì)把通知消息通過(guò)UIApplicationDidReceiveLocalNotification廣播給全局監(jiān)聽(tīng)者。并調(diào)用completionHandler()。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),表示接入應(yīng)用已經(jīng)完全處理完通知消息,框架中止執(zhí)行之后的邏輯。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler;
/**
* 框架會(huì)率先回調(diào)該方法,讓接入應(yīng)用可以拿到deviceToken。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架會(huì)把deviceToken通過(guò)UIApplicationDidRegisterForRemoteNotifications廣播給全局監(jiān)聽(tīng)者。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),表示接入應(yīng)用已經(jīng)完全處理完,框架中止執(zhí)行之后的邏輯。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
/**
* 當(dāng)取deviceToken失敗時(shí),框架率先回調(diào)該方法。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架繼續(xù)執(zhí)行,目前無(wú)其它邏輯。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),框架中止之后的邏輯,目前無(wú)其它邏輯。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
/**
* 框架會(huì)先給分享組件(如果有,并且shouldAutoactivateShareKit返回YES)通知,如果分享組件處理不了,再回調(diào)該方法,由接入應(yīng)用處理openURL。
* 當(dāng)返回DTFrameworkCallbackResultReturnYES或DTFrameworkCallbackResultReturnNO時(shí),框架直接給系統(tǒng)返回,不再執(zhí)行接下來(lái)的邏輯。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),繼續(xù)由框架處理URL,并分發(fā)給SchemeHandler等類(lèi)來(lái)處理。
*
* 這個(gè)方法相比系統(tǒng)方法,多了一個(gè)newURL參數(shù),允許應(yīng)用在處理后,返回一個(gè)不同的url。如果函數(shù)整體返回DTFrameworkCallbackResultContinue,并且給newURL賦值,框架會(huì)使用新的URL來(lái)做后續(xù)處理。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application openURL:(NSURL *)url newURL:(NSURL **)newURL sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
/**
* 框架率先回調(diào)該方法。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架繼續(xù)執(zhí)行,目前無(wú)其它邏輯。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),框架中止之后的邏輯,目前無(wú)其它邏輯。
*/
- (DTFrameworkCallbackResult)applicationWillResignActive:(UIApplication *)application;
/**
* 框架率先回調(diào)該方法。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架繼續(xù)執(zhí)行,目前無(wú)其它邏輯。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),框架中止之后的邏輯,目前無(wú)其它邏輯。
*/
- (DTFrameworkCallbackResult)applicationDidEnterBackground:(UIApplication *)application;
/**
* 框架率先回調(diào)該方法。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架繼續(xù)執(zhí)行,目前無(wú)其它邏輯。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),框架中止之后的邏輯,目前無(wú)其它邏輯。
*/
- (DTFrameworkCallbackResult)applicationWillEnterForeground:(UIApplication *)application;
/**
* 框架先回調(diào)該方法。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架繼續(xù)執(zhí)行,給分享組件事件(如果有,并且shouldAutoactivateShareKit返回YES)。并且當(dāng)整個(gè)應(yīng)用沒(méi)被加載時(shí),調(diào)用BootLoader
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),框架中止之后的邏輯,目前無(wú)其它邏輯。
*/
- (DTFrameworkCallbackResult)applicationDidBecomeActive:(UIApplication *)application;
/**
* 框架率先回調(diào)該方法。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架繼續(xù)執(zhí)行,目前無(wú)其它邏輯。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),框架中止之后的邏輯,目前無(wú)其它邏輯。
*/
- (DTFrameworkCallbackResult)applicationWillTerminate:(UIApplication *)application;
/**
* 框架率先回調(diào)該方法。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架繼續(xù)執(zhí)行,目前無(wú)其它邏輯。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),框架中止之后的邏輯,目前無(wú)其它邏輯。
*/
- (DTFrameworkCallbackResult)applicationDidReceiveMemoryWarning:(UIApplication *)application;
/**
* 框架率先回調(diào)該方法,接入應(yīng)用可以先行處理Watch的消息。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架會(huì)把Watch消息通過(guò)UIApplicationWatchKitExtensionRequestNotifications廣播給全局監(jiān)聽(tīng)者。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),表示接入應(yīng)用已經(jīng)完全處理完通知消息,框架中止執(zhí)行之后的邏輯。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply;
/**
* 框架率先回調(diào)該方法,接入應(yīng)用可以先行處理消息。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架會(huì)把消息通過(guò)UIApplicationUserActivityNotifications廣播給全局監(jiān)聽(tīng)者,并最后給系統(tǒng)返回NO。
* 當(dāng)返回DTFrameworkCallbackResultReturnYES或DTFrameworkCallbackResultReturnNO時(shí),框架直接給系統(tǒng)返回,不再執(zhí)行接下來(lái)的邏輯。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler;
/**
* 框架率先回調(diào)該方法,接入應(yīng)用可以先行處理3D Touch快捷入口的消息。
* 當(dāng)返回DTFrameworkCallbackResultContinue時(shí),框架會(huì)處理shortcutItem帶過(guò)來(lái)的URL,并最后調(diào)用completionHandler()返回是否已經(jīng)處理。
* 當(dāng)返回DTFrameworkCallbackResultReturn時(shí),框架直接給系統(tǒng)返回,不再執(zhí)行接下來(lái)的邏輯。
*/
- (DTFrameworkCallbackResult)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler;
/**
* Background Fetch 機(jī)制回調(diào)
* 必須在30s內(nèi)回調(diào)completionHandler,否則進(jìn)程將被terminate
* 若要啟用此機(jī)制,需要先配置Background Modes的fetch選項(xiàng)。其次在didFinishLaunching中調(diào)用下面的方法。更多信息參考文檔。
* [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
* 默認(rèn)實(shí)現(xiàn)為空,需要接入方自己處理。
*/
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;
應(yīng)用模塊劃分
mPaaS 框架內(nèi)定義了微應(yīng)用和服務(wù)的概念來(lái)進(jìn)行模塊間的劃分。其中,以是否有 UI 界面作為標(biāo)準(zhǔn),F(xiàn)ramework 將不同的模塊劃分為 微應(yīng)用 和 服務(wù),通過(guò) 框架上下文 進(jìn)行微應(yīng)用與服務(wù)的生命周期管理。
中文 | 英文 | 解釋 |
---|---|---|
微應(yīng)用 | MicroApplication | 客戶(hù)端運(yùn)行期帶有用戶(hù)界面的微應(yīng)用 |
服務(wù) | Service | 客戶(hù)端運(yùn)行期提供的輕量級(jí)抽象服務(wù) |
框架上下文 | Context | 客戶(hù)端微組件運(yùn)行期上下文 |
本文主要介紹微應(yīng)用、服務(wù)、框架上下文的概念。有關(guān)具體的使用方法,查看 創(chuàng)建微應(yīng)用。
微應(yīng)用
在基于 mPaaS iOS 框架開(kāi)發(fā)應(yīng)用的過(guò)程中,一般會(huì)將帶有 UI 界面的獨(dú)立業(yè)務(wù)設(shè)置為一個(gè)微應(yīng)用(如支付寶中的轉(zhuǎn)賬、手機(jī)充值等),與其他的業(yè)務(wù)隔離開(kāi),實(shí)現(xiàn)各個(gè)微應(yīng)用之間高度獨(dú)立,不相互依賴(lài)。
微應(yīng)用也有自己的生命周期,整個(gè)過(guò)程如下:
微應(yīng)用整個(gè)生命周期的回調(diào)方法,具體內(nèi)容參考 DTMicroApplicationDelegate.h
文件。
@required
/**
* 請(qǐng)求應(yīng)用對(duì)象的代理返回根視圖控制器。
*
* @param application 應(yīng)用對(duì)象。
*
* @return 應(yīng)用的根視圖控制器。
*/
- (UIViewController *)rootControllerInApplication:(DTMicroApplication *)application;
@optional
/**
* 通知應(yīng)用代理,應(yīng)用對(duì)象已經(jīng)對(duì)經(jīng)被實(shí)例化。
*
* @param application 應(yīng)用對(duì)象。
*/
- (void)applicationDidCreate:(DTMicroApplication *)application;
/**
* 通知應(yīng)用代理,應(yīng)用將要啟動(dòng)。
*
* @param application 啟動(dòng)的應(yīng)用對(duì)象。
* @param options 應(yīng)用運(yùn)行參數(shù)。
*/
- (void)application:(DTMicroApplication *)application willStartLaunchingWithOptions:(NSDictionary *)options;
/**
* 通知應(yīng)用代理,應(yīng)用已啟動(dòng)。
*
* @param application 啟動(dòng)的應(yīng)用對(duì)象。
*/
- (void)applicationDidFinishLaunching:(DTMicroApplication *)application;
/**
* 通知應(yīng)用代理,應(yīng)用即將暫停進(jìn)入后臺(tái)運(yùn)行。
*
* @param application 啟動(dòng)的應(yīng)用對(duì)象。
*/
- (void)applicationWillPause:(DTMicroApplication *)application;
/**
* 通知應(yīng)用代理,應(yīng)用將被重新激活。
*
* @param application 要激活的應(yīng)用對(duì)象。
*/
- (void)application:(DTMicroApplication *)application willResumeWithOptions:(NSDictionary *)options;
/**
* 通知應(yīng)用代理,應(yīng)用已經(jīng)被激活。
*
* @param application 要激活的應(yīng)用對(duì)象。
*/
- (void)applicationDidResume:(DTMicroApplication *)application;
/**
* 通知應(yīng)用代理,應(yīng)用已經(jīng)被激活。
*
* @param application 要激活的應(yīng)用對(duì)象,帶上參數(shù)的版本。
*/
- (void)application:(DTMicroApplication *)application didResumeWithOptions:(NSDictionary *)options;
/**
* 通知應(yīng)用的代理,應(yīng)用將要退出。
*
* @param application 應(yīng)用對(duì)象。
*/
- (void)applicationWillTerminate:(DTMicroApplication *)application;
/**
* 通知應(yīng)用的代理,應(yīng)用將要退出。
*
* @param application 應(yīng)用對(duì)象。
* @param animated 是否以動(dòng)畫(huà)方式退出。
*/
- (void)applicationWillTerminate:(DTMicroApplication *)application animated:(BOOL)animated;
/**
* 詢(xún)問(wèn)應(yīng)用的代理,應(yīng)用是否可以退出。
* 注意:只有特殊情況才返回 NO;如果默認(rèn)是 YES,則可以退出。
*
* @param application 應(yīng)用對(duì)象。
*
* @return 是否可以退出。
*/
- (BOOL)applicationShouldTerminate:(DTMicroApplication *)application;
服務(wù)
mPaaS iOS 框架將沒(méi)有 UI 界面的 Framework 稱(chēng)為服務(wù),其與微應(yīng)用的區(qū)別如下:
微應(yīng)用是獨(dú)立的業(yè)務(wù)流程,服務(wù)則用來(lái)提供通用服務(wù)。
服務(wù)有狀態(tài),一旦啟動(dòng)后,其在整個(gè)客戶(hù)端的生命周期中一直存在,任何時(shí)候都可以被獲取;微應(yīng)用在退出后即被銷(xiāo)毀。
服務(wù)管理相關(guān)的接口,具體內(nèi)容參考 DTService.h
文件。
@required
/**
* 啟動(dòng)一個(gè)服務(wù)。
* 注意:
* 框架在完成初始化操作后,會(huì)調(diào)用該方法。
* 在一個(gè)服務(wù)里面,要先調(diào)用該方法,之后才能去啟動(dòng)應(yīng)用。
*/
- (void)start;
@optional
/**
* 創(chuàng)建服務(wù)完成。
*/
- (void)didCreate;
/**
* 服務(wù)將要銷(xiāo)毀。
*/
- (void)willDestroy;
框架上下文(Context)
框架上下文(Context)是整個(gè)客戶(hù)端框架的控制中心,統(tǒng)一管理各個(gè)微應(yīng)用和服務(wù)之間的交互與跳轉(zhuǎn),主要負(fù)責(zé):
提供啟動(dòng)微應(yīng)用的接口,可通過(guò)名字快速查找、關(guān)閉、管理微應(yīng)用的跳轉(zhuǎn)等。
提供啟動(dòng)服務(wù)的接口,管理服務(wù)的注冊(cè)、發(fā)現(xiàn)和反注冊(cè)。
微應(yīng)用管理
微應(yīng)用管理相關(guān)接口,具體內(nèi)容參考
DTContext.h
文件。
/**
* 根據(jù)指定的名稱(chēng)啟動(dòng)一個(gè)應(yīng)用。
*
* @param name 要啟動(dòng)的應(yīng)用名。
* @param params 啟動(dòng)應(yīng)用時(shí),需要轉(zhuǎn)遞給另一個(gè)應(yīng)用的參數(shù)。
* @param animated 指定啟動(dòng)應(yīng)用時(shí),是否顯示動(dòng)畫(huà)。
*
* @return 應(yīng)用啟動(dòng)成功返回 YES,否則返回 NO。
*/
- (BOOL)startApplication:(NSString *)name params:(NSDictionary *)params animated:(BOOL)animated;
/**
* 根據(jù)指定的名稱(chēng)啟動(dòng)一個(gè)應(yīng)用。
*
* @param name 要啟動(dòng)的應(yīng)用名。
* @param params 啟動(dòng)應(yīng)用時(shí),需要轉(zhuǎn)遞給另一個(gè)應(yīng)用的參數(shù)。
* @param launchMode 指定 App 的啟動(dòng)方式。
*
* @return 應(yīng)用啟動(dòng)成功返回 YES,否則返回 NO。
*/
- (BOOL)startApplication:(NSString *)name params:(NSDictionary *)params launchMode:(DTMicroApplicationLaunchMode)launchMode;
/**
* 查找一下指定的應(yīng)用。
*
* @param name 要查找的應(yīng)用名。
*
* @return 如果指定的應(yīng)用已在應(yīng)用棧中,則返回對(duì)應(yīng)的應(yīng)用對(duì)象。否則返回 nil。
*/
- (DTMicroApplication *)findApplicationByName:(NSString *)name;
/**
* 返回當(dāng)前在棧頂?shù)膽?yīng)用,即對(duì)用戶(hù)可見(jiàn)的應(yīng)用。
*
* @return 當(dāng)前可見(jiàn)的應(yīng)用。
*/
- (DTMicroApplication *)currentApplication;
微應(yīng)用啟動(dòng)過(guò)程:
服務(wù)管理
服務(wù)管理相關(guān)接口,具體內(nèi)容參考
DTContext.h
文件。
/**
* 根據(jù)指定的名稱(chēng)查找服務(wù)。
*
* @param name 服務(wù)名
*
* @return 如果找到指定名稱(chēng)的服務(wù),則返回一個(gè)服務(wù)對(duì)象,否則返回空。
*/
- (id)findServiceByName:(NSString *)name;
/**
* 注冊(cè)一個(gè)服務(wù)。
*
* @param name 服務(wù)名
*/
- (BOOL)registerService:(id)service forName:(NSString *)name;
/**
* 反注冊(cè)一個(gè)已存在的服務(wù)。
*
* @param name 服務(wù)名。
*/
- (void)unregisterServiceForName:(NSString *)name;
服務(wù)啟動(dòng)過(guò)程:
框架上下文管理微應(yīng)用與服務(wù)的 UML 類(lèi)圖如下: