# App如何动态管理合作小程序
# 1. 问题背景
App接入FinClip后,可能产生如下问题:
- App是否能够实现“一对多”,即:1个App内能够打开多个不同环境、不同企业的小程序。 如:同时打开来自于企业A私有化环境下的小程序1、企业B私有化环境下的小程序2、企业C在凡泰SaaS环境下的小程序3
- App能否在不发版的前提下,动态管理小程序的展示、隐藏。如:当App在包含小程序1和2的情况下、已发布应用市场,此时再增加小程序3
针对以上两个常见问题,我们整理了对应解决方案。
# 2. App实现“一对多”
FinClip支持多服务器配置,此时所指的多服务器包括:
- 多个不同的部署环境(如企业A私有化环境、企业B私有化环境)
- 多个不同企业的小程序(无论该小程序部署在什么环境上)
# 2.1 iOS 多服务器配置方式
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"servers" ofType:@"plist"];
NSArray *array = [NSArray arrayWithContentsOfFile:plistPath];
NSMutableArray *storeArrayM = [NSMutableArray array];
for (NSDictionary *dict in array) {
FATStoreConfig *storeConfig = [[FATStoreConfig alloc] init];
storeConfig.sdkKey = dict[@"sdkKey"];
storeConfig.sdkSecret = dict[@"sdkSecret"];
storeConfig.apiServer = dict[@"apiServer"];
storeConfig.apiPrefix = dict[@"apiPrefix"];
storeConfig.apmServer = dict[@"apmServer"];
if ([@"SM" isEqualToString:dict[@"cryptType"]]) {
storeConfig.cryptType = FATApiCryptTypeSM;
} else {
storeConfig.cryptType = FATApiCryptTypeMD5;
}
[storeArrayM addObject:storeConfig];
}
FATConfig *config = [FATConfig configWithStoreConfigs:storeArrayM];
[[FATClient sharedClient] initWithConfig:config error:nil];
# 2.2 Android 多服务器配置方式
// 服务器信息集合
List<FinStoreConfig> storeConfigs = new ArrayList<>();
// 服务器1的信息
FinStoreConfig storeConfig1 = new FinStoreConfig(
"SDK Key信息", // SDK Key
"SDK Secret信息", // SDK Secret
"服务器1的地址", // 服务器地址
"服务器1的数据上报服务器地址", // 数据上报服务器地址
"/api/v1/mop/", // 服务器接口请求路由前缀
"", // SDK指纹
"加密方式" // 加密方式,国密:SM,md5: MD5
);
storeConfigs.add(storeConfig1);
// 服务器2的信息
FinStoreConfig storeConfig2 = new FinStoreConfig(
"SDK Key信息", // SDK Key
"SDK Secret信息", // SDK Secret
"服务器2的地址", // 服务器地址
"服务器2的数据上报服务器地址", // 数据上报服务器地址
"/api/v1/mop/", // 服务器接口请求路由前缀
"", // SDK指纹
"加密方式" // 加密方式,国密:SM,md5: MD5
);
storeConfigs.add(storeConfig2);
FinAppConfig config = new FinAppConfig.Builder()
.setFinStoreConfigs(storeConfigs) // 服务器信息集合
.build();
# 3. App在不发版的前提下、动态管理小程序
App打开小程序实际是由两个步骤完成的:
- 使用SDK配置信息,完成SDK初始化
- 使用AppID,打开指定小程序
此时,如小程序均在同一个环境下,则SDK配置信息无需修改,仅通过动态管理的小程序列表页增加新的小程序入口(AppID)即可。此时,SDK初始化的节点可以放在App打开后、小程序打开前的任意时间点。
小程序列表页由App开发、维护,通常是小程序icon+文字,用户通过点击icon唤醒小程序。我们建议这个列表页使用可动态维护的框架进行开发,如H5页面。
当小程序不在同一个环境时,则需要从App后台(小程序列表页的管理后台)下发对应新的SDK初始化信息及小程序AppID信息。
整体业务流程如下,此时SDK初始化只能放在已获得不同小程序的配置信息后、小程序打开前。
我们将在后文,提供对应的代码示例,便利App开发者了解具体实现方式。
# 3.1 iOS 配置方式
# 3.1.1 从服务器端获取服务器信息
App 从后台或其他途径获取服务器的配置信息。
# 3.1.2 缓存该服务器的配置信息
这一步不是必要的。是否缓存看App获取配置是每次获取一个,还是获取所有的配置。如果每次获取一个服务器就需要缓存,如果每次获取所有服务器则没必要缓存,直接构造成配置对象初始化SDK即可。
# 3.1.3 初始化SDK
// 构造一个服务器配置对象
FATStoreConfig *storeConfig = [[FATStoreConfig alloc] init];
storeConfig.sdkKey = @"SDK Key";
storeConfig.sdkSecret = @"SDK secret";
storeConfig.apiServer = @"服务器地址";
storeConfig.apmServer = @"apm 上报的服务器地址,不传默认使用apiServer";
storeConfig.cryptType = FATApiCryptTypeSM;
// 存到数组中
NSArray *configs = @[storeConfig];
// 将多套配置构造成一个config对象
FATConfig *config = [FATConfig configWithStoreConfigs:configs];
// 初始化SDK
[[FATClient sharedClient] initWithConfig:config error:nil];
# 3.1.4 打开小程序
FATAppletRequest *request = [[FATAppletRequest alloc] init];
request.appletId = @"小程序id";
request.apiServer = @"服务器地址";
request.transitionStyle = FATTranstionStyleUp;
request.startParams = startParams;
[[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) {
NSLog(@"打开小程序:%@", error);
} closeCompletion:^{
NSLog(@"关闭小程序");
}];
# 3.2 Android 多服务器配置方式
# 3.2.1 动态获取服务器信息
App从后台或其它途径获取未在SDK初始化时配置的服务器信息。
FinStoreConfig storeConfig = new FinStoreConfig(
"SDK Key信息", // SDK Key
"SDK Secret信息", // SDK Secret
"服务器1的地址", // 服务器地址
"服务器1的数据上报服务器地址", // 数据上报服务器地址
"/api/v1/mop/", // 服务器接口请求路由前缀
"", // SDK指纹
"加密方式" // 加密方式,国密:SM,md5: MD5
);
# 3.2.2 初始化新获取到的服务器信息
注意,若此时非第一次初始化SDK,即已在其它地方如Application中初始化过SDK,
则不能使用
new FinAppConfig.Builder()
的方式重新进行初始化,否则会丢失原有的SDK配置。
在主进程进行初始化:
// 获取之前的SDK配置
FinAppConfig finAppConfig = FinAppClient.INSTANCE.getFinAppConfig();
// 若此时是第一次初始化SDK,则可使用Builder的方式进行配置
// 若能够确保代码运行到此处时SDK已初始化过,则可省略掉该if代码块
if (finAppConfig == null) {
FinAppConfig.Builder builder = new FinAppConfig.Builder();
// builder.setXXXX 使用builder进行配置
finAppConfig = builder.build();
}
List<FinStoreConfig> finStoreConfigs = finAppConfig.getFinStoreConfigs();
// 添加之前动态获取到的服务器信息
finStoreConfigs.add(storeConfig);
// 重新进行SDK初始化
FinAppClient.INSTANCE.init(application, finAppConfig, new FinCallback<Object>() {
@Override
public void onSuccess(Object result) {
}
@Override
public void onError(int code, String error) {
}
@Override
public void onProgress(int status, String info) {
}
});
# 3.2.3 打开对应新增服务器的小程序
FinAppClient.INSTANCE.getAppletApiManager().startApplet(context, "apiServer", "appId", null, null);