FinClip为企业提供小程序生态圈技术产品,开发者可在FinClip小程序开发帮助中心找到相关FinClip小程序指引

# 小程序管理

小程序管理主要介绍操作小程序的API,包括:打开小程序,关闭小程序,搜索小程序等。

# 1. 打开小程序

从用户角度看,小程序启动可以分为冷启动和热启动2种情况。 冷启动:首次打开小程序或小程序销毁后被用户再次打开,此时小程序需要重新加载启动,即冷启动。 热启动:如果用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态,这个过程就是热启动。

不同的场景,所使用的打开小程序的api也不同。所以,我们提供了多种不同的打开小程序的api。

  1. 打开线上小程序,这里一般只需要小程序id和服务器地址即可,该api只能打开正式版和审核版的小程序。
  2. 二维码打开小程序,这个场景是扫描小程序平台上的二维码,得到二维码里的内容,然后使用该内容打开小程序。正式版、体验版、审核版、开发版、预览版本的小程序二维码都可以使用该Api打开。
  3. 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 小程序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事件中

注意:如果要首次离线启动,则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,见下图示例

image.jpg

然后,在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. 关闭小程序

关闭小程序 等价于 点击右上角胶囊里的小程序,此时小程序是退至后台,小程序并未销毁。

# 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. 结束小程序

小程序被关闭后,并没有真的结束,而是在后台挂起。等下次打开小程序时,会立即将小程序切换至前台运行。 所以,如果我们希望小程序关闭后,真的被结束掉,可以根据实际情况使用以下API来结束指定小程序或所有小程序。

# 3.1 结束指定小程序

小程序关闭后,调用该api可删除缓存,即可销毁该小程序。

/**
删除内存中的指定小程序
*/
- (void)clearMemeryApplet:(NSString *)appletId;

# 3.2 结束所有小程序

当打开,关闭过多个小程序,想一次性将后台挂起的所有小程序都结束掉时,就可以使用该api。

/**
 清空内存中缓存的所有小程序
 */
- (void)clearMemoryCache;

# 4. 删除小程序

由于小程序的运行,会将小程序包和小程序信息缓存在本地,以后打开时会优先使用缓存,所以打开时速度也就会很快。 所以,如果想要将小程序的所有信息都删除,那么可以使用以下api删除某个小程序或者删除所有小程序。

# 4.1 删除指定小程序

/**
 从本地存储中删除指定小程序
 
 @param appletId 小程序id
 @return BOOL 结果
 */
- (BOOL)removeAppletFromLocalCache:(NSString *)appletId;

# 4.2 删除所有小程序

///  删除本地缓存的小程序
- (void)clearLocalApplets;

# 5 批量下载小程序

提前把小程序下载到本地,可以减少初次启动小程序的耗时。

/**
 @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];
© 2022 FinClip with ❤