All Products
Search
Document Center

Mobile Platform as a Service:mPaaS iOS framework

Last Updated:Sep 07, 2023

mPaaS iOS framework originates from the development framework of Alipay client. In line with the design idea of Framework, mPaaS iOS isolates business into multiple relatively independent modules and aims for achieving high cohesion and low coupling between modules.

mPaaS iOS framework directly takes over the lifecycle of application, and responsible for Host startup, managing application lifecycle, processing and distributing the delegate events of UIApplication, managing each business modules (MicroApplication and Services) in a unified way, etc.

This article gives a detailed introduction to the mPaaS iOS framework.

Host startup

Through the replacement of the main function of the program, the lifecycle of the application is directly taken over. The whole startup process is as follows:

main -> DFClientDelegate -> Open Launcher application

Application lifecycle management

After you access mPaaS framework, it completely replaces AppDelegate. The entire lifecycle of the application is managed by the framework, but you can still implement the delegate methods in different stages of the application’s lifecycle. The framework provides the access method for all delegate methods in the UIApplicationDelegate, you only need to override the corresponding method in Category.

The life cycle method is declared as follows (see DTFrameworkInterface.h file for more information):

/**
 *  The framework needs to implement certain initialization logic in didFinishLaunching, but this method will be called before execution.
 */
- (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

/**
 *  The framework calls back this method, making the accessed application taking over its own didFinishLaunching logic.
 *  When DTFrameworkCallbackResultReturnYES or DTFrameworkCallbackResultReturnNO is returned, they are directly returned to the system, without executing the subsequent logic.
 *  This method is called back before starting BootLoader, application can make the framework exit in advance by returning DTFrameworkCallbackResultReturnYES or DTFrameworkCallbackResultReturnNO, without running the default BootLoader.
 *  Use the default implementation in the framework, override is normally not required.
 *
 *  @return : To continue run the framework, or return YES/NO to the system.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

/**
 *  The framework needs to implement certain initialization logic in didFinishLaunching, but this method will be called after all the logics are done.
 */
- (void)application:(UIApplication *)application afterDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

/**
 *  The framework calls back this method in advance, allowing the accessed application to process the notification message in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework broadcasts the message to global listeners through UIApplicationDidReceiveRemoteNotification, and calls completionHandler(UIBackgroundFetchResultNoData).
 *  When DTFrameworkCallbackResultReturn is returned, it means the accessed application has completely processed the message, and the framework stops executing the subsequent logic.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;

/**
 *  The framework calls back this method in advance, allowing the accessed application to process the notification message in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework broadcasts the message to global listeners through UIApplicationDidReceiveLocalNotification.
 *  When DTFrameworkCallbackResultReturn is returned, it means the accessed application has completely processed the message, and the framework stops executing the subsequent logic.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;

/**
 *  The framework calls back this method in advance, allowing the accessed application to process the notification message in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework broadcasts the message to global listeners through UIApplicationDidReceiveLocalNotification, and calls completionHandler().
 *  When DTFrameworkCallbackResultReturn is returned, it means the accessed application has completely processed the message, and the framework stops executing the subsequent logic.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler;

/**
 *  The framework calls back this method in advance, allowing the accessed application to get deviceToken.
 *  When DTFrameworkCallbackResultContinue is returned, the framework broadcasts the message to global listeners through UIApplicationDidRegisterForRemoteNotifications.
 *  When DTFrameworkCallbackResultReturn is returned, it means the accessed application has completely processed, and the framework stops executing the subsequent logic.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;

/**
 *  The framework calls back this method in advance when it fails to obtain deviceToken.
 *  When DTFrameworkCallbackResultContinue is returned, the framework continues to execute, no other logic currently.
 *  When DTFrameworkCallbackResultReturn is returned, the framework stops executing the subsequent logic, no other logic currently.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;

/**
 *  The framework notifies sharing component (if there is, and shouldAutoactivateShareKit returns YES) in advance, if the sharing component cannot process it, this method is called back to allow the accessed application to process openURL.
 *  When DTFrameworkCallbackResultReturnYES or DTFrameworkCallbackResultReturnNO is returned, the framework directly returns to the system, without executing the subsequent logic.
 *  When DTFrameworkCallbackResultContinue is returned, the framework continues to process the URL, and distribute it to SchemeHandler and other classes for further processing.
 *
 *  Comparing with the system method, this method has an additional newURL parameter, allowing the application to return a different URL after processing. If the function returns DTFrameworkCallbackResultContinue and assign value to newURL, the framework will use the new URL for subsequent processing.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application openURL:(NSURL *)url newURL:(NSURL **)newURL sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;

/**
 *  The framework calls back this method in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework continues to execute, no other logic currently.
 *  When DTFrameworkCallbackResultReturn is returned, the framework stops executing the subsequent logic, no other logic currently.
 */
- (DTFrameworkCallbackResult)applicationWillResignActive:(UIApplication *)application;

/**
 *  The framework calls back this method in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework continues to execute, no other logic currently.
 *  When DTFrameworkCallbackResultReturn is returned, the framework stops executing the subsequent logic, no other logic currently.
 */
- (DTFrameworkCallbackResult)applicationDidEnterBackground:(UIApplication *)application;

/**
 *  The framework calls back this method in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework continues to execute, no other logic currently.
 *  When DTFrameworkCallbackResultReturn is returned, the framework stops executing the subsequent logic, no other logic currently.
 */
- (DTFrameworkCallbackResult)applicationWillEnterForeground:(UIApplication *)application;

/**
 *  The framework calls back this method in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework continues to execute and give event to sharing component (if there is, and shouldAutoactivateShareKit returns YES). If the entire application is not loaded, BootLoader is called.
 *  When DTFrameworkCallbackResultReturn is returned, the framework stops executing the subsequent logic, no other logic currently.
 */
- (DTFrameworkCallbackResult)applicationDidBecomeActive:(UIApplication *)application;

/**
 *  The framework calls back this method in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework continues to execute, no other logic currently.
 *  When DTFrameworkCallbackResultReturn is returned, the framework stops executing the subsequent logic, no other logic currently.
 */
- (DTFrameworkCallbackResult)applicationWillTerminate:(UIApplication *)application;

/**
 *  The framework calls back this method in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework continues to execute, no other logic currently.
 *  When DTFrameworkCallbackResultReturn is returned, the framework stops executing the subsequent logic, no other logic currently.
 */
- (DTFrameworkCallbackResult)applicationDidReceiveMemoryWarning:(UIApplication *)application;

/**
 *  The framework calls back this method in advance, allowing the accessed application to process the Watch message in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework broadcasts the Watch message to global listeners through UIApplicationWatchKitExtensionRequestNotifications.
 *  When DTFrameworkCallbackResultReturn is returned, it means the accessed application has completely processed the message, and the framework stops executing the subsequent logic.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply;

/**
 *  The framework calls back this method in advance, allowing the accessed application to process the message in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework broadcasts the message to global listeners through UIApplicationUserActivityNotifications, and returns NO to the system in the end.
 *  When DTFrameworkCallbackResultReturnYES or DTFrameworkCallbackResultReturnNO is returned, the framework directly returns to the system, without executing the subsequent logic.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler;

/**
 *  The framework calls back this method in advance, allowing the accessed application to process the message of 3D Touch quick entry in advance.
 *  When DTFrameworkCallbackResultContinue is returned, the framework processes the URL brought by shortcutItem, and calls completionHandler() to return whether it has been processed.
 *  When DTFrameworkCallbackResultReturn is returned, the framework directly returns to the system, without executing the subsequent logic.
 */
- (DTFrameworkCallbackResult)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler;

/**
 *  Background Fetch mechanism callback
 *  completionHandler must be called back in 30 seconds, otherwise the process will be terminated.
 *  To enable this mechanism, you need to configure the fetch option of Background Modes, and then call the following method in didFinishLaunching. See documentation for more information.
 *  [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
 *  The default implementation is null, you need to process it in your own way.
 */
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;

Division of application modules

mPaaS framework has defined MicroApplication and Service to separate different modules. Take “whether it has an UI interface” as criteria, the Framework classifies different modules into MicroApplication and Service and implements lifecycle management on the modules via Context.

Terminology

Definition

MicroApplication

A micro application with UI on client at runtime

Service

Lightweight abstracted service provided by client at runtime

Context

Context of client micro-component at runtime

This section introduces the concepts of micro application, service, and context. See Create a micro application for more information.

MicroApplication

In the process of developing application based on mPaaS iOS framework, we generally set the independent service with UI as a micro application (e.g.: transfer, mobile top-up and other services in Alipay) and isolate it from other services to achieve high independence and zero interdependence among micro applications.

Each micro application has its own lifecycle. The overall process is as follows:

applicationSchedule

The callback methods of micro application through the whole lifecycle (see DTMicroApplicationDelegate.h file for more information):

@required
/**
* Request the delegate of application object to return root view controller. 
*
* @param application: Application object. 
*
* @return: The root view controller of application. 
*/
- (UIViewController *)rootControllerInApplication:(DTMicroApplication *)application;
@optional
/**
* Notify the application delegate that the application object has been instantiated. 
*
* @param application: Application object. 
*/
- (void)applicationDidCreate:(DTMicroApplication *)application;
/**
* Notify the application delegate that the application will be launched. 
*
* @param application: Launched application object. 
* @param options: Running parameters of the application. 
*/
- (void)application:(DTMicroApplication *)application willStartLaunchingWithOptions:(NSDictionary *)options;
/**
* Notify the application delegate that the application is launched already. 
*
* @param application: Launched application object. 
*/
- (void)applicationDidFinishLaunching:(DTMicroApplication *)application;
/**
* Notify the application delegate that the application will be paused and put into background. 
*
* @param application: Launched application object. 
*/
- (void)applicationWillPause:(DTMicroApplication *)application;
/**
* Notify the application delegate that the application will be reactivated. 
*
* @param application: The application object to be activated. 
*/
- (void)application:(DTMicroApplication *)application willResumeWithOptions:(NSDictionary *)options;
/**
* Notify the application delegate that the application has been activated. 
*
* @param application: The application object to be activated. 
*/
- (void)applicationDidResume:(DTMicroApplication *)application;
/**
* Notify the application delegate that the application has been activated. 
*
* @param application: The application object to be activated, together with parameter version. 
*/
- (void)application:(DTMicroApplication *)application didResumeWithOptions:(NSDictionary *)options;
/**
* Notify the application delegate that the application will quit. 
*
* @param application: Application object. 
*/
- (void)applicationWillTerminate:(DTMicroApplication *)application;
/**
* Notify the application delegate that the application will quit. 
*
* @param application: Application object. 
* @param animated: Whether to quit in animated way. 
*/
- (void)applicationWillTerminate:(DTMicroApplication *)application animated:(BOOL)animated;
/**
* Inquire the application delegate whether the application can quit or not. 
* Note: The delegate returns **NO** in some special cases. If it defaults to **Yes**, the application can quit. 
*
* @param application: Application object. 
*
* @return: Whether the application can quit or not. 
*/
- (BOOL)applicationShouldTerminate:(DTMicroApplication *)application;

Service

mPaaS iOS framework regards the Framework without UI as service. The differences between microapplication and service are as follows:

  • Microapplication serves as an independent business process while service is used to provide general service.

  • Service is stateful. Once started, the service exists through the whole lifecycle of the client and can be acquired at any time; microapplication will be destroyed after exit.

Relevant interfaces of service management (see DTService.h file for more information):

@required
/**
* Start a service.
* Note:
* The framework will call the method after initialization.
* The service can start an application only when the method is called.
*/
- (void)start;
@optional
/**
* A service is created.
*/
- (void)didCreate;
/**
* The service will be destroyed.
*/
- (void)willDestroy;

Context

Context is the control center of the whole client framework, performing unified management on the interaction and jumps among micro applications and services, with the following responsibilities:

  • Provide an interface for starting micro application. Users can quickly find, close and manage the jumps of the micro application through using name;

  • Provide an interface for starting service, managing the registration, discovery and deregistration of services.

Manage micro application

  • Relevant interfaces of micro application management (see DTContext.h file for more information):

/**
* Start an application as per the given name.
*
* @param name: Name of the application to be started.
* @param params: The parameters need to be forwarded to another application when an application is started.
* @param animated: Specify whether to display animation when starting an application.
*
* @return: Return YES if the application is successfully started, otherwise NO.
*/
- (BOOL)startApplication:(NSString *)name params:(NSDictionary *)params animated:(BOOL)animated;
/**
* Start an application as per the given name.
*
* @param name: Name of the application to be started.
* @param params: The parameters need to be forwarded to another application when an application is started.
* @param launchMode: Specify the method of starting application.
*
* @return: Return YES if the application is successfully started, otherwise NO.
*/
- (BOOL)startApplication:(NSString *)name params:(NSDictionary *)params launchMode:(DTMicroApplicationLaunchMode)launchMode;
/**
* Find the specified application.
*
* @param name: Name of the application to find.
*
* @return: Return corresponding application object if the specified application is in the application stack, otherwise nil.
*/
- (DTMicroApplication *)findApplicationByName:(NSString *)name;
/**
* Return the application which is on the top of the stack currently, namely the application visible to users.
* 
* @return: Current visible applications.
*/
- (DTMicroApplication *)currentApplication;
  • Micro application starting process:

    image.png

Service management

  • Relevant interfaces of service management (see DTContext.h file for more information):

/**
* Find a service as per the given name. 
*
* @param name: Service name
*
* @return: Return a service object if the service with given name is found, otherwise null. 
*/
- (id)findServiceByName:(NSString *)name;

/**
* Register a service. 
*
* @param name: Service name
*/
- (BOOL)registerService:(id)service forName:(NSString *)name;

/**
* Deregister an existing service. 
*
* @param name: Service name
*/
- (void)unregisterServiceForName:(NSString *)name;
  • Service starting process:

    image.png

    The UML class diagram illustrating how context manages micro application and service is shown below:

    uml