支付宝客户端架构解析:iOS 容器化框架初探

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文将介绍支付宝 iOS 容器化框架设计的基本思路。

1. 前言

由本章节开始,我们将从支付宝客户端的架构设计方案入手,细分拆解客户端在“容器化框架设计”、“网络优化”、“性能启动优化”、“自动化日志收集”、“RPC 组件设计”、“移动应用监控、诊断、定位”等具体实现,带领大家进一步了解支付宝在客户端架构上的迭代与优化历程。

本节将介绍支付宝 iOS 容器化框架设计的基本思路。

2. 容器化实现概览

在 mPaaS 开篇介绍中已经和大家分享过《模块化与解耦式开发在蚂蚁金服 mPaaS 中的实践》:通过容器化开发框架将业务隔离成相对独立的模块,并着力追求模块与模块之间高内聚、低耦合,因此我们实现了灵活的插件式开发,并得以将业务划分为上千个独立工程。

mPaaS iOS 框架源自于支付宝客户端,为了实现这种上千个工程之间的低耦合和相关依赖调用,mPaaS 框架直接接管了 App 的生命周期,负责整个 App 启动托管、App 生命周期管理、处理与分发 UIApplication 的代理事件。
mPaaS 框架提供了容器化环境,业务开发人员在这个容器化环境中使用 微应用服务 进行具体的业务需求开发。

mPaaS iOS 框架-w400

微应用服务 是 mPaaS 框架内定义的概念,主要是用来进行业务模块间的划分。按照是否有 UI 界面作为标准,mPaaS 框架将不同的业务模块划分为 微应用服务微应用 是 APP 运行期间带有用户界面的业务模块;服务 是 App 运行期由业务提供的轻量级抽象服务。在 mPaaS 框架中,通过 框架上下文Context 进行 微应用服务 的生命周期管理。

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 中都提供了对应的方法:

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」,获得第一手 mPaaS 技术实践干货

目录
相关文章
|
6天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
4天前
|
边缘计算 自动驾驶 5G
|
7天前
|
存储 安全 Java
系统安全架构的深度解析与实践:Java代码实现
【11月更文挑战第1天】系统安全架构是保护信息系统免受各种威胁和攻击的关键。作为系统架构师,设计一套完善的系统安全架构不仅需要对各种安全威胁有深入理解,还需要熟练掌握各种安全技术和工具。
33 10
|
4天前
|
消息中间件 编解码 开发者
深入解析 Flutter兼容鸿蒙next全体生态的横竖屏适配与多屏协作兼容架构
本文深入探讨了 Flutter 在屏幕适配、横竖屏切换及多屏协作方面的兼容架构。介绍了 Flutter 的响应式布局、逻辑像素、方向感知、LayoutBuilder 等工具,以及如何通过 StreamBuilder 和 Provider 实现多屏数据同步。结合实际应用场景,如移动办公和教育应用,展示了 Flutter 的强大功能和灵活性。
70 6
|
4天前
|
存储 SQL 缓存
AnalyticDB 实时数仓架构解析
AnalyticDB 是阿里云自研的 OLAP 数据库,广泛应用于行为分析、数据报表、金融风控等应用场景,可支持 100 trillion 行记录、10PB 量级的数据规模,亚秒级完成交互式分析查询。本文是对 《 AnalyticDB: Real-time OLAP Database System at Alibaba Cloud 》的学习总结。
17 1
|
6天前
|
监控 安全 Serverless
"揭秘D2终端大会热点技术:Serverless架构最佳实践全解析,让你的开发效率翻倍,迈向技术新高峰!"
【10月更文挑战第23天】D2终端大会汇聚了众多前沿技术,其中Serverless架构备受瞩目。它让开发者无需关注服务器管理,专注于业务逻辑,提高开发效率。本文介绍了选择合适平台、设计合理函数架构、优化性能及安全监控的最佳实践,助力开发者充分挖掘Serverless潜力,推动技术发展。
16 1
|
10天前
|
移动开发 网络协议 小程序
基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v9.1版已发布
RainbowChat是一套基于开源IM聊天框架 MobileIMSDK 的产品级移动端IM系统。RainbowChat源于真实运营的产品,解决了大量的屏幕适配、细节优化、机器兼容问题
33 5
|
10天前
|
监控 网络协议 安全
DNS服务器故障不容小觑,从应急视角谈DNS架构
DNS服务器故障不容小觑,从应急视角谈DNS架构
31 4
|
8天前
|
Swift iOS开发 开发者
探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】在苹果生态系统中,SwiftUI的引入无疑为iOS应用开发带来了革命性的变化。本文将通过深入浅出的方式,带领读者了解SwiftUI的基本概念、核心优势以及如何在实际项目中运用这一框架。我们将从一个简单的例子开始,逐步深入到更复杂的应用场景,让初学者能够快速上手,同时也为有经验的开发者提供一些深度使用的技巧和策略。
25 1
|
10天前
|
监控 安全 Java
构建高效后端服务:微服务架构深度解析与最佳实践###
【10月更文挑战第19天】 在数字化转型加速的今天,企业对后端服务的响应速度、可扩展性和灵活性提出了更高要求。本文探讨了微服务架构作为解决方案,通过分析传统单体架构面临的挑战,深入剖析微服务的核心优势、关键组件及设计原则。我们将从实际案例入手,揭示成功实施微服务的策略与常见陷阱,为开发者和企业提供可操作的指导建议。本文目的是帮助读者理解如何利用微服务架构提升后端服务的整体效能,实现业务快速迭代与创新。 ###
34 2

推荐镜像

更多