1. mPaaS iOS 框架介绍
mPaaS iOS 框架源自支付宝客户端的开发框架,基于 Framework 的设计思想:
1.将业务隔离成相对独立的模块
2.着力追求模块与模块之间高內聚、低耦合。
mPaaS iOS 框架直接接管应用的生命周期负责:
1.整个应用启动托管、
2.应用生命周期管理、处理与分发
3.UIApplication 的代理事件、统一管理各业务模块(微应用和服务)等。
与apache Cordova 类似,应该是在标准的iOS 层次结构上进行了封装
2. 启动托管
通过程序 main 函数的替换,直接接管应用的生命周期,整个启动的过程如下:
main -> DFClientDelegate -> 打开 Launcher 应用(MPLauncherAppDelegate):
(个人认为 DF的含义是default,MP是mPaaS的缩写)
2.1我们看一下main函数
//
// main.m
// MPH5Demo_plugin
//
// Created by vivi.yw on 2019/03/28.
// Copyright © 2019 Alibaba. All rights reserved.
//
#import <UIKit/UIKit.h>
#ifdef HOTPATCHEXIST
APSecBufferRef APSecGetPKS()
{
char sig[] = {0x89,0x55,0xec,0x73,0xd3,0xb1,0x98,0x20,0xb4,0xa3,0x2b,0x1,0x6a,0x1,0xc5,0x59,0xd9,0x3,0x48,0x9d,0x90,0x32,0x69,0xab,0x8e,0x61,0xb8,0x26,0xd5,0xbe,0xd2,0x42,0xde,0xf8,0x8a,0x4d,0xe2,0x57,0xa9,0xbc,0xb2,0x5b,0x7,0x56,0xfa,0x16,0x38,0x7c,0x27,0x3b,0x98,0x4b,0x12,0x30,0x2f,0x2,0xc0,0x2a,0x4b,0x57,0xfb,0xba,0x90,0xd5,0x17,0x8a,0x31,0x40,0x5e,0x94,0x35,0x9e,0x11,0x5b,0xb5,0x1c,0x5d,0xdb,0x9e,0x97,0x24,0x59,0x61,0xf,0x3,0xe,0x15,0x9d,0x19,0x4c,0x8a,0xba,0x1e,0x41,0x4e,0x25,0x39,0x72,0x41,0xaf,0xb8,0xc1,0x1c,0x35,0x2f,0x55,0xe1,0xbd,0x78,0x49,0xac,0x34,0x6d,0xe8,0x6,0x6f,0x9b,0x5f,0xda,0xd5,0xe8,0xca,0x86,0x4d,0xb3,0xe3,0xc0,0x8c,0x1c,0x6a,0x6c,0x98,0x72,0xe8,0x4d,0xb2,0x6b,0x88,0x22,0x2,0xb3,0xc8,0x77,0x24,0xc,0x62,0xd,0x3d,0xdf,0xfc,0x3e,0xd4,0xf4,0xf3,0x2b,0x89,0x27,0x23,0x57,0xf6,0x52,0x57,0x56,0x71,0x4a,0x91,0xbc,0x36,0xa3,0x59,0x16,0xb5,0xd4,0xd7,0x1d,0x7b,0xd0,0x72,0xb2,0x7e,0xb0,0x84,0x9,0x93,0x4e,0xcd,0x33,0x4e,0xfc,0x25,0x4a,0x50,0x90,0x7a,0x73,0x4f,0x45,0xb4,0x18,0x40,0xdc,0x92,0xf6,0xa1,0x1f,0x34,0xdf,0x63,0x81,0x26,0xcb,0xd3,0x7,0xfe,0x4a,0x17,0xe9,0xe8,0x8,0x80,0xc,0x1b,0xba,0x38,0xb9,0xfe,0x69,0x78,0xbd,0x9d,0xcf,0xe5,0x12,0xdf,0xbe,0x86,0x86,0x11,0x99,0x36,0xb9,0xb2,0xee,0xfc,0x71,0xf6,0x2f,0xbb,0xd9,0x16,0x67,0x42,0x9f,0xb9,0x58,0x89};
size_t len = sizeof(sig);
APSecBufferRef buf = (APSecBufferRef)malloc(sizeof(APSecBuffer) + len);
buf->length = len;
memcpy(buf->data, sig, len);
return buf;
}
#endif
int main(int argc, char * argv[]) {
@autoreleasepool {
#ifdef HOTPATCHEXIST
NSString *path;
APSecBufferRef buf;
int ret;
path = [[NSBundle mainBundle] pathForResource:@"pubkey" ofType:@"pem"];
APSecInitPublicKey([path UTF8String]); // 读取并初始化公钥
buf = APSecGetPKS(); // 读取公钥的签名
ret = APSecVerifyFile([path UTF8String], buf->data, buf->length); // 验证公钥文件自身是否符合签名
free(buf);
if (ret != 0) {
NSLog(@"The public key is modified.");
}
#endif
return UIApplicationMain(argc, argv, @"DFApplication", @"DFClientDelegate"); // NOW USE MPAAS FRAMEWORK
}
}
2.2查看DFClientDelegate的源码
我们在项目中找不到DFClientDelegate的源码,我们看一下启动时的调用关系栈:
2.3 打开 Launcher 应用
我们来看一下Launcher 应用的一些情况,包括目录结构,头文件,源文件:
我们发现了,MPLauncherAppDelegate的源文件,头文件,还有个MobileRuntime.plist文件,这个文件的作用之后再说;
我们来看一下头文件的内容:
//
// MPLauncherAppDelegate.h
#import <Foundation/Foundation.h>
@interface MPLauncherAppDelegate : NSObject <DTMicroApplicationDelegate>
- (UIViewController *)rootControllerInApplication:(DTMicroApplication *)application;
@end
我们看到了类 MPLauncherAppDelegate,继承自NSObject,遵循协议 DTMicroApplicationDelegate
但是 这个协议是个啥玩意呢?我们看到了在框架里的头文件,我们来仔细看看!
我们看到了协议,返回了应用的根视图控制器,而且这个协议DTMicroApplicationDelegate必须实现;
我们来看一下实现情况(部分代码如下)
@interface MPLauncherAppDelegate ()
@property (nonatomic, strong) UITabBarController* tabBarController;
@property (nonatomic, strong) UIViewController *rootController;
@end
- (UIViewController *)rootControllerInApplication:(DTMicroApplication *)application
{
return self.rootController;
}
我们看到了两个视图的控制器:tabBarController和rootController
看来这是一个 带有tabBar的东西;
我们看一下,这个类的init方法:
- (id)init
{
self = [super init];
if (self)
{
// 这里指定Tab使用的图片
NSArray *baseImgs = [NSArray arrayWithObjects:
@"TabBar_HomeBar",
@"TabBar_Discovery",
@"TabBar_PublicService",
@"TabBar_Friends", nil];
NSArray *selectImgs = [NSArray arrayWithObjects:
@"TabBar_HomeBar_Sel",
@"TabBar_Discovery_Sel",
@"TabBar_PublicService_Sel",
@"TabBar_Friends_Sel", nil];
UIViewController* tab1ViewController = (UIViewController *) [self createLoggingViewController:@"DemoViewController"];
UIViewController* tab2ViewController = [[DTViewController alloc] init];
UIViewController* tab3ViewController = [[DTViewController alloc] init];
UIViewController* tab4ViewController = [[DTViewController alloc] init];
NSArray *navArray = @[tab1ViewController, tab2ViewController, tab3ViewController, tab4ViewController];
NSArray *titles = @[@"Tab1", @"Tab2", @"Tab3", @"Tab4"];
for (int i = 0; i < [navArray count]; i ++)
{
UIImage *bImg = [UIImage imageNamed:baseImgs[i]];
UIImage *selectImg = [UIImage imageNamed:selectImgs[i]];
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:titles[i] image:bImg selectedImage:selectImg];
item.selectedImage = [item.selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
item.image = [item.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
item.tag = i;
[(UIViewController *)navArray[i] setTabBarItem:item];
((UIViewController *)navArray[i]).title = titles[i];
}
self.tabBarController = [[MPTabBarController alloc] init];
self.tabBarController.viewControllers = navArray;
self.tabBarController.selectedIndex = 0;
[self.tabBarController.delegate tabBarController:self.tabBarController didSelectViewController:tab1ViewController];
self.rootController = self.tabBarController;
}
return self;
}
它初始化了一些 UIViewController,然后将其与tabBarController连接起来,又将self.tabBarController赋值给self.rootController;
这样,应用程序的委托对象是MPLauncherAppDelegate;
应用的视图是MPLauncherAppDelegate的属性;