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 界面的独立业务设置为一个微应用(如支付宝中的转账、手机充值等),与其他的业务隔离开,实现各个微应用之间高度独立,不相互依赖。
微应用也有自己的生命周期,整个过程如下:
微应用整个生命周期的回调方法,具体内容参考 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;
微应用启动过程:
服务管理
服务管理相关接口,具体内容参考
DTContext.h
文件。
/**
* 根据指定的名称查找服务。
*
* @param name 服务名
*
* @return 如果找到指定名称的服务,则返回一个服务对象,否则返回空。
*/
- (id)findServiceByName:(NSString *)name;
/**
* 注册一个服务。
*
* @param name 服务名
*/
- (BOOL)registerService:(id)service forName:(NSString *)name;
/**
* 反注册一个已存在的服务。
*
* @param name 服务名。
*/
- (void)unregisterServiceForName:(NSString *)name;
服务启动过程:
框架上下文管理微应用与服务的 UML 类图如下: