# 小程序管理
小程序管理主要介绍操作小程序的API,包括:打开小程序,关闭小程序,搜索小程序等。
# 1. 打开小程序
支持的app类型
小程序✅ 小游戏✅ H5应用✅
从用户角度看,小程序启动可以分为冷启动和热启动2种情况。 冷启动:首次打开小程序或小程序销毁后被用户再次打开,此时小程序需要重新加载启动,即冷启动。 热启动:如果用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态,这个过程就是热启动。
不同的场景,所使用的打开小程序的api也不同。所以,我们提供了多种不同的打开小程序的api。
- 打开线上小程序,这里一般只需要小程序id和服务器地址即可,该api只能打开正式版和审核版的小程序。
- 二维码打开小程序,这个场景是扫描小程序平台上的二维码,得到二维码里的内容,然后使用该内容打开小程序。正式版、体验版、审核版、真机调试版、预览版本的小程序二维码都可以使用该Api打开。
- URL Scheme 打开小程序,这个场景是在H5网页里嵌入 URL Scheme 的URI,触发打开App里的小程序,只支持打开上架的正式版本小程序。
# 1.1 普通打开小程序
打开小程序时,会先判断本地是否有缓存的小程序,如果没有,则会自动从远程服务器上下载小程序,然后打开;如果有缓存的小程序,则会先打开本地小程序,然后再校验服务器端是否有新版本。
如果有新版本,则下载新版小程序,下次打开时,就会使用新版小程序;如果没有新版本,则什么也不做。
/// 启动小程序
/// @param request 启动的request
/// @param parentVC 父页面
/// @param completion 完成回调
/// @param closeCompletion 关闭小程序时的回调
- (void)startAppletWithRequest:(FATAppletRequest *)request
InParentViewController:(UIViewController *)parentVC
completion:(void (^)(BOOL result, FATError *error))completion
closeCompletion:(dispatch_block_t)closeCompletion;
FATAppletRequest
属性名 | 类型 | 描述 |
---|---|---|
appletId | NSString | 小程序/小游戏/H5应用id,必填 |
apiServer | NSString | 小程序所属服务器,必填 |
appName | NSString | 小程序名称,非必填 |
appletLogo | NSString | 小程序图标的网络地址,非必填 |
startParams | NSDictionary | 小程序启动参数,支持的key,请参考FATStartParamKey,非必填 |
reLaunchMode | FATReLaunchMode | 小程序热启动时的reLaunch模式,请参考FATReLaunchMode说明,非必填 |
transitionStyle | FATTranstionStyle | 打开小程序时的转场动画方式,非必填,默认值为FATTranstionStyleUp |
animated | BOOL | 是否使用动画,非必填,默认值为YES |
sequence | NSNumber | 小程序索引, 非必填 |
offlineMiniprogramZipPath | NSString | 离线小程序压缩包路径,可传入一个本地小程序包路径,加快首次启动速度, 非必填 |
offlineFrameworkZipPath | NSString | 离线基础库压缩包路径,可传入一个基础库路径,加快首次启动速度, 非必填 |
hideMiniProgramCloseButton | BOOL | 是否隐藏小程序页面胶囊里的关闭按钮,默认为NO |
hideMiniProgramMoreButton | BOOL | 是否隐藏小程序页面胶囊里的更多按钮,默认为YES |
from | NSNumber | 来源,数据上报时记录到apm事件中 |
appletPageOrientation | FATInterfaceOrientation | 小程序页面的方向,优先级最高 |
commonUIOrientation | FATInterfaceOrientation | 非小程序页面的方向,优先级最高 |
注意:如果要首次离线启动,则offlineMiniprogramZipPath 和 offlineFrameworkZipPath必须都传递。
# 1.1.1 打开小程序(基础参数)
正常打开小程序只需要传小程序id和服务器地址即可。
示例代码:
FATAppletRequest *request = [[FATAppletRequest alloc] init];
request.appletId = @"小程序id"; // 必填项
request.apiServer = @"服务器地址"; // 必填项
[[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) {
NSLog(@"打开小程序:%@", error);
} closeCompletion:^{
NSLog(@"关闭小程序");
}];
# 1.1.2 打开小程序(带启动参数)
打开小程序也可以传启动参数,支持path(启动小程序的路径,代码包路径)、query(启动小程序的 query 参数)、scene(启动小程序的场景值)。
示例代码:
FATAppletRequest *request = [[FATAppletRequest alloc] init];
request.appletId = @"小程序id"; // 必填项
request.apiServer = @"服务器地址"; // 必填项
request.startParams = @{
@"path":@"/pages/index/index",
@"query":@"key1=value1&key2=value2",
@"scene" : @"1001"
}; // 小程序的启动参数
[[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) {
NSLog(@"打开小程序:%@", error);
} closeCompletion:^{
NSLog(@"关闭小程序");
}];
# 1.1.3 打开小程序(使用离线包)
由于首次打开小程序时,要下载小程序包和基础库包,所以首次启动较慢。针对这种情况,我们可以将小程序包、基础库包下载好放置再工程中打包;也可以在打开app后,合适的时机下载好小程序和基础库包。
FATAppletRequest *request = [[FATAppletRequest alloc] init];
request.appletId = @"小程序id";
request.apiServer = @"服务器地址";
// 小程序离线包地址(见上图),可以是bundle 路径,也可以是沙盒路径
request.offlineMiniprogramZipPath = [[NSBundle mainBundle] pathForResource:@"api_demo" ofType:@"zip"];
// 基础库离线包地址(见上图),可以是bundle 路径,也可以是沙盒路径
request.offlineFrameworkZipPath = [[NSBundle mainBundle] pathForResource:@"framework-3.0.49" ofType:@"zip"];
[[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self.window.rootViewController completion:^(BOOL result, FATError *error) {
NSLog(@"打开小程序11:%@", error);
} closeCompletion:^{
NSLog(@"关闭小程序11");
}];
# 1.1.4 iPad上以不同窗口模式打开小程序
在ipad上可以通过设置不同的窗口模式来显示小程序,更好的实现一些业务场景,提供更好的用户体验。目前支持如下几种模式:
fullScreen模式 默认模式,小程序打开后全屏显示 示例代码:
FATAppletRequest *request = [[FATAppletRequest alloc] init]; request.appletId = @"小程序id"; // 必填项 request.apiServer = @"服务器地址"; // 必填项 request.presentationConfig = [FATAppletPresentationConfig fullScreenPresentationConfig]; [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { NSLog(@"打开小程序:%@", error); } closeCompletion:^{ NSLog(@"关闭小程序"); }];
演示效果:
currentContext模式 从打开小程序的ParentViewController开始向上搜索视图控制器层次结构,并以第一个definesPresentationContext属性为true的ViewController为Context进行显示。当显示完成后,会将属于PresentingViewController的所有视图暂时移出视图栈。窗口显示大小跟找到的context显示模式有关。可以用在 iPad UISplitViewController中,指定单独覆盖屏幕单侧的控制器。 示例代码:
FATAppletRequest *request = [[FATAppletRequest alloc] init]; request.appletId = @"小程序id"; // 必填项 request.apiServer = @"服务器地址"; // 必填项 request.presentationConfig = [FATAppletPresentationConfig currentContextPresentationConfig]; [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { NSLog(ompletion:^{ NSLog(@@"打开小程序:%@", error); } closeC"关闭小程序"); }];
演示效果:
overCurrentContext模式 跟上面的currentContext模式显示效果一样,不同的是显示完成后,不会将属于PresentingViewController的视图移出视图栈。 示例代码:
FATAppletRequest *request = [[FATAppletRequest alloc] init]; request.appletId = @"小程序id"; // 必填项 request.apiServer = @"服务器地址"; // 必填项 request.presentationConfig = [FATAppletPresentationConfig overCurrentContextPresentationConfig]; [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { NSLog(ompletion:^{ NSLog(@@"打开小程序:%@", error); } closeC"关闭小程序"); }];
演示效果:
pageSheet模式 非全屏打开小程序,不可设置小程序窗口大小,小程序窗口宽度为该设备竖屏时候的宽度,高度横竖屏时会变化,小程序窗口外区域有蒙层。 示例代码:
FATAppletRequest *request = [[FATAppletRequest alloc] init]; request.appletId = @"小程序id"; // 必填项 request.apiServer = @"服务器地址"; // 必填项 request.presentationConfig = [FATAppletPresentationConfig pageSheetPresentationConfig]; [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { NSLog(ompletion:^{ NSLog(@@"打开小程序:%@", error); } closeC"关闭小程序"); }];
演示效果:
formSheet模式 跟pageSheet模式类似,非全屏打开小程序,不可设置小程序窗口大小,窗口大小由系统决定,总是居中显示。 示例代码:
FATAppletRequest *request = [[FATAppletRequest alloc] init]; request.appletId = @"小程序id"; // 必填项 request.apiServer = @"服务器地址"; // 必填项 request.presentationConfig = [FATAppletPresentationConfig formSheetPresentationConfig]; [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { NSLog(ompletion:^{ NSLog(@@"打开小程序:%@", error); } closeC"关闭小程序"); }];
演示效果:
popover模式 以弹出的方式显示小程序窗口,有一个小箭头指向触发该模态视图的按钮或者其他UI元素,可以设置窗口大小,有2种配置方式。 示例代码: 方式一:通过sourceView 和 sourceRect参数配置,sourceView 设定了触发小程序的视图元素,而 sourceRect 则定义了在这个视图上的具体区域。通常会尝试放置其箭头指向 sourceRect的中心。
FATAppletRequest *request = [[FATAppletRequest alloc] init]; request.appletId = @"小程序id"; // 必填项 request.apiServer = @"服务器地址"; // 必填项 request.presentationConfig = [FATAppletPresentationConfig popoverPresentationSourceViewConfig:self.view sourceRect:CGRectMake(20, 20, 500, 500)]; [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { NSLog(ompletion:^{ NSLog(@@"打开小程序:%@", error); } closeC"关闭小程序"); }];
演示效果:
方式二:可以在一个item(例如导航栏按钮 UIBarButtonItem 或者 UITabBarItem)后弹出小程序,会根据 barButtonItem 的位置,自动放置其箭头。
FATAppletRequest *request = [[FATAppletRequest alloc] init]; request.appletId = @"小程序id"; // 必填项 request.apiServer = @"服务器地址"; // 必填项 request.presentationConfig =[FATAppletPresentationConfig popoverPresentationSourceItemConfig:CGSizeMake(300, 500) barButtonItem:item]; [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { NSLog(ompletion:^{ NSLog(@@"打开小程序:%@", error); } closeC"关闭小程序"); }];
演示效果:
custom模式 小程序窗口以自定义的方式显示,可以自定义窗口区域,不支持自定义显示动画。 示例代码:
FATAppletRequest *request = [[FATAppletRequest alloc] init]; request.appletId = @"小程序id"; // 必填项 request.apiServer = @"服务器地址"; // 必填项 request.presentationConfig = [FATAppletPresentationConfig customPresentationConfig:CGPointMake(self.view.bounds.size.width / 3.0 / 2.0, 64) preferredContentSize:CGSizeMake(self.view.bounds.size.width / 3.0 * 2.0, self.view.bounds.size.height / 3 * 2)]; [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { NSLog(ompletion:^{ NSLog(@@"打开小程序:%@", error); } closeC"关闭小程序"); }];
演示效果:
# 1.2 二维码打开小程序
这种情况流程一般会复杂一些,需要先扫描FinClip小程序开放平台上的二维码,得到二维码里的内容,然后使用二维码内容调用该接口打开小程序。
/// 二维码信息启动小程序
/// @param request 请求对象
/// @param parentVC 父页面
/// @param requestBlock 校验二维码的请求完成的回调
/// @param completion 完成的回调
/// @param closeCompletion 关闭小程序时的回调
- (void)startAppletWithQrCodeRequest:(FATAppletQrCodeRequest *)request
inParentViewController:(UIViewController *)parentVC
requestBlock:(void (^)(BOOL result, FATError *error))requestBlock
completion:(void (^)(BOOL result, FATError *error))completion
closeCompletion:(dispatch_block_t)closeCompletion;
注意:打开体验版二维码时,需在初始化sdk时添加对应的体验成员userId。 FATAppletQrCodeRequest
属性名 | 类型 | 描述 |
---|---|---|
qrCode | NSString | 二维码内容,必填 |
transitionStyle | FATTranstionStyle | 打开小程序时的转场动画方式,非必填,默认值为FATTranstionStyleUp |
animated | BOOL | 是否使用动画,非必填,默认值为YES |
from | NSNumber | 来源,数据上报时记录到apm事件中 |
reLaunchMode | FATReLaunchMode | 小程序热启动时的reLaunch模式,请参考FATReLaunchMode说明,非必填 |
示例代码:
FATAppletQrCodeRequest *qrcodeRequest = [[FATAppletQrCodeRequest alloc] init];
qrcodeRequest.qrCode = qrCode;
[[FATClient sharedClient] startAppletWithQrCodeRequest:qrcodeRequest inParentViewController:self requestBlock:^(BOOL result, FATError *error) {
NSLog(@"请求完成:%@", error);
} completion:^(BOOL result, FATError *error) {
NSLog(@"打开完成:%@", error);
} closeCompletion:^{
NSLog(@"关闭");
}];
# 1.3 使用 URL Scheme 打开小程序
有些时候,我们希望能在safari加载的网页里或者其第三方app打开自己app中的小程序,这是用就可以使用URL Scheme来实现 通过自己的App打开小程序。
首先,需要添加URL Type。选择 Target -> 【Info】 -> 【URL Types】,新增一个URL Schemes。 URL Schemes的格式是fat+sdkKey的md5,见下图示例 URL Schemes的格式是fat+sdkKey的md5,见下图示例 URL Schemes的格式是fat+sdkKey的md5,见下图示例
然后,在AppDelagate 中实现 OpenURL代理方法。示例代码如下:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if ([[FATClient sharedClient] handleOpenURL:url]) {
return YES;
}
return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
if ([[FATClient sharedClient] handleOpenURL:url]) {
return YES;
}
return YES;
}
最后,在H5网页里添加Scheme 链接即可。
Scheme URI 的完整格式:${scheme}://applet/appid/${appId}?path=${path}&query=${encode过的query}&apiServer=${encode过的apiServer}
配置名称 | 类型 | 是否必填 | 配置描述 |
---|---|---|---|
scheme | String | 是 | fat{sdkKey的16位小写md5},示例fat705b46f78820c7a8 |
appId | String | 是 | 小程序id |
path | String | 否 | 小程序页面路径,示例pages/index/index |
query | String | 否 | 小程序的参数,URLEncode(key1=value1&key2=value2) |
apiServer | String | 否 | 小程序所属服务器,默认会取初始化的第一个服务器。当初始化多个服务器时,需要传入。 |
示例如下:
<a href='fatd919cec7395563d7://applet/appid/617bb42f530fb30001509b27?path=pages/index/index&query=key%3Dvalue%26name%3Dtable&apiServer=https%3A%2F%2Fwww.finclip.com'>打开小程序</a>
当然,您也可以在safari浏览器的地址栏中输入完整的url(比如:fat705b46f78820c7a8://applet/appid/5e017a61c21ecf0001343e31),然后回车就会打开您的App,然后启动小程序了。
# 1.4 冷启动场景
小程序冷启动时,如果启动参数带了path,则启动进入对应 path 的页面;如果没有带path参数,则进入小程序首页。
# 1.5 热启动场景
* 触发冷启动:如果上次启动后,小程序有了新版本或者环境有变化,则会重新启动小程序(冷启动)。
* 热启动场景可以设置reLaunch模式,来决定是否需要relaunch。
1. FATReLaunchModeParamsExist:启动参数中包含path、query或referrerInfo,并且其中某个参数不为空,则会触发reLaunch,有path参数则进入对应path的页面。
2. FATReLaunchModeOnlyParamsDiff:有启动参数,且启动参数与上一次的启动参数不同时,就执行reLaunch
3. FATReLaunchModeAlways:忽略启动参数,每次热启动均执行reLaunch
4. FATReLaunchModeNever:每次热启动均不执行reLaunch,即热启动永远复用页面栈
# 2. 关闭小程序
支持的app类型
小程序✅ 小游戏✅ H5应用✅
关闭小程序 等价于 点击右上角胶囊里的小程序,此时小程序是退至后台,小程序并未销毁。
# 2.1 关闭指定小程序
/**
关闭打开的指定小程序
@param animated 是否显示动画
@param completion 关闭完成的回调
*/
- (void)closeApplet:(NSString *)appletId animated:(BOOL)animated completion:(dispatch_block_t)completion;
# 2.2 关闭所有小程序
有些场景下,可能存在A小程序打开B小程序,B小程序打开C小程序的情况,这时想要关闭打开的所有小程序,可以使用该方法。
/**
关闭当前打开的所有小程序
@param completion 关闭完成的回调
*/
- (void)closeAllAppletsWithCompletion:(dispatch_block_t)completion;
# 2.3 关闭当前小程序
/**
关闭当前的小程序
@param animated 是否显示动画
@param completion 关闭完成的回调
*/
- (void)closeCurrentApplet:(BOOL)animated completion:(dispatch_block_t)completion;
# 3. 结束小程序
支持的app类型
小程序✅ 小游戏✅ H5应用✅
小程序被关闭后,并没有真的结束,而是在后台挂起。等下次打开小程序时,会立即将小程序切换至前台运行。 所以,如果我们希望小程序关闭后,真的被结束掉,可以根据实际情况使用以下API来结束指定小程序或所有小程序。
注意:如果正在显示的小程序,调用如下两个api是不会将小程序销毁的。需要先调用关闭函数,再调用如下两个方法其一才可以销毁小程序。
# 3.1 结束指定小程序
小程序关闭后,调用该api可删除缓存,即可销毁该小程序。
/**
删除内存中的指定小程序
*/
- (void)clearMemeryApplet:(NSString *)appletId;
# 3.2 结束所有小程序
当打开,关闭过多个小程序,想一次性将后台挂起的所有小程序都结束掉时,就可以使用该api。
/**
清空内存中缓存的所有小程序
*/
- (void)clearMemoryCache;
# 4. 删除小程序
支持的app类型
小程序✅ 小游戏✅ H5应用✅
由于小程序的运行,会将小程序包和小程序信息缓存在本地,以后打开时会优先使用缓存,所以打开时速度也就会很快。 所以,如果想要将小程序的所有信息都删除,那么可以使用以下api删除某个小程序或者删除所有小程序。
# 4.1 删除指定小程序
/**
从本地存储中删除指定小程序
@param appletId 小程序id
@return BOOL 结果
*/
- (BOOL)removeAppletFromLocalCache:(NSString *)appletId;
# 4.2 删除所有小程序
/// 删除本地缓存的小程序
- (void)clearLocalApplets;
# 5 批量下载小程序
支持的app类型
小程序✅ 小游戏✅ H5应用✅
提前把小程序下载到本地,可以减少初次启动小程序的耗时。
/**
@brief 批量更新小程序
@param appIds 小程序id数组
@param apiServer 服务器地址
@param complete 批量更新小程序回调
*/
- (void)downloadApplets:(NSArray *)appIds apiServer:(NSString *)apiServer complete:(void (^)(NSArray *results, FATError *error))complete;
/**
@brief 批量更新小程序
@param appIds 小程序id数组
@param apiServer 服务器地址
@param isBatchDownloadApplets 是否下载小程序
@param complete 批量更新小程序回调
*/
- (void)downloadApplets:(NSArray *)appIds apiServer:(NSString *)apiServer isBatchDownloadApplets:(BOOL)isBatchDownloadApplets complete:(void (^)(NSArray *results, FATError *error))complete;
示例代码
// 默认下载
[[FATClient sharedClient] downloadApplets:##appIds## apiServer:##apiServer## complete:^(NSArray *results, FATError *error) {
// 批量更新小程序回调
// results 批量更新小程序结果,是一个数组对象
// 其中元素为:@{@"appId": ##小程序id##, @"success": ##更新是否成功##, @"needUpdate": ##是否需要更新##}
// 每次传入的小程序id,有可能本地已缓存了最新的版本,故有可能无需更新,此时needUpdate字段为false
// error 错误,成功时为nil
}];
// 由isBatchDownloadApplets参数决定是否下载小程序
[[FATClient sharedClient] downloadApplets:##appIds## apiServer:##apiServer## isBatchDownloadApplets:##isBatchDownloadApplets## complete:^(NSArray *results, FATError *error) {
// 批量更新小程序回调
// results 批量更新小程序结果,是一个数组对象
// 其中元素为:@{@"appId": ##小程序id##, @"success": ##更新是否成功##, @"needUpdate": ##是否需要更新##}
// 每次传入的小程序id,有可能本地已缓存了最新的版本,故有可能无需更新,此时needUpdate字段为false
// error 错误,成功时为nil
}];
# 6 预下载基础库
配置预下载基础库,可以减少初次启动小程序的时间。
FATStoreConfig类中新增enablePreloadFramework属性,在初始化时配置enablePreloadFramework为YES,为该服务器开启基础库预下载。 初始化时,开启基础库预下载的服务器会下载基础库,打开小程序时,就会更快。
示例代码:
FATStoreConfig *storeConfig = [[FATStoreConfig alloc] init];
storeConfig.sdkKey = @"##sdkKey##";
storeConfig.sdkSecret = @"##sdkSecret##";
storeConfig.apiServer = @"##apiServer##";
storeConfig.cryptType = FATApiCryptTypeSM;
// 开启基础库预下载
storeConfig.enablePreloadFramework = YES;
FATConfig *config = [FATConfig configWithStoreConfigs:@[storeConfig]];
[[FATClient sharedClient] initWithConfig:config error:nil];