iOS API
这里介绍 FinClip 小程序 SDK 提供了哪些能力,以及API的详细说明和使用示例。
1. 基础API
1.1 SDK初始化
在使用小程序的API之前,需要先初始化小程序SDK。只有成功初始化之后,才能使用SDK提供的API,否则 API都无法调用。
初始化SDK的API如下:
/// 初始化SDK
/// @param config 配置对象
/// @param error 初始化失败时返回的error
- (BOOL)initWithConfig:(FATConfig *)config error:(NSError **)error;
/// 初始化SDK
/// @param config 配置对象
/// @param uiConfig UI配置对象
/// @param error 初始化失败时返回的error
- (BOOL)initWithConfig:(FATConfig *)config uiConfig:(FATUIConfig *)uiConfig error:(NSError **)error;
初始化示例:
NSString *appKey = @"这里填上的SDK Key";
FATConfig *config = [FATConfig configWithAppSecret:@"这里填上SDK secret" appKey:appKey];
config.apiServer = @"https://api.finclip.com";
config.apiPrefix = @"/api/v1/mop";
[[FATClient sharedClient] initWithConfig:config error:nil];
注意
- 从2.13.109版本开始,FinClip SDK 支持配置多个服务器信息,可以同时打开多个不同服务器上的小程序,所以我们提供了配置多个服务器信息的方式。
- 以appSecret和appKey构造FATConfig的方法未来可能会弃用,请尽早更新为多服务器的方式。
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];
FATConfig中的配置项:
配置名称 | 配置描述 |
---|---|
appKey | SDK Key,校验失败时无法使用SDK (将要弃用) |
appSecret | SDK secret (将要弃用) |
apiServer | 服务器地址 (将要弃用) |
apmServer | apm统计的服务器地址 (将要弃用) |
apiPrefix | api的版本 (将要弃用) |
cryptType | SDK与后台交互的数据加密方式 (将要弃用) |
fingerprint | SDK指纹,证联服务器时必填(将要弃用) |
currentUserId | 当前用户唯一标识,小程序缓存信息会存储在以userId命名的不同目录下 |
disableAuthorize | 是否禁止SDK触发权限申请,默认为NO,如果设置为YES,则SDK内使用权限的api,不会主动申请权限。 |
disableGetSuperviseInfo | 是否禁用SDK的监管接口API,默认为NO,如果设置为YES,则SDK禁用监管接口API(getSuperviseInfo) |
appletIntervalUpdateLimit | 后台自动检查更新的小程序个数,取值范围:0~50。0代表不检查更新;不设置默认是3。 |
startCrashProtection | 是否开启Crash防崩溃。UnrecognizedSelector、KVO、Notification、Timer、Container(数组越界,字典插入nil等)、String (越界、nil等) |
enableApmDataCompression | apm数据上报时,是否压缩数据 |
encryptServerData | 平台接口返回的数据是否要加密 |
FATUIConfig中的配置项:
配置名称 | 配置描述 |
---|---|
navigationTitleTextAttributes | 导航栏标题的样式,目前仅支持字体的配置。 |
capsuleConfig | 右上角胶囊的样式配置,具体参数见FATCapsuleConfig表 |
progressBarColor | 小程序中的web-view组件加载链接时的进度条颜色 |
moreMenuStyle | 胶囊里更多按钮弹出的菜单视图的样式 |
hideForwardMenu | 是否隐藏更多菜单中的转发按钮。 |
hideFeedbackMenu | 是否隐藏更多菜单中的投诉反馈按钮。 |
hideBackToHome | 是否隐藏更多菜单中的回到首页按钮。 |
autoAdaptDarkMode | 是否适配暗黑模式。 |
appendingCustomUserAgent | 您需要添加至userAgent中的内容。 |
appletText | 默认为“小程序”,您需要替换展示的名称。比如设置会"轻应用",所有显示"小程序"的地方,都会变为"轻应用" |
hideTransitionCloseButton | 是否隐藏转场页的关闭按钮。默认为NO |
disableSlideCloseAppletGesture | 是否禁用侧滑关闭小程序的手势。默认为NO |
FATCapsuleConfig(胶囊)中的配置项:
配置名称 | 配置描述 |
---|---|
capsuleWidth | 胶囊的宽度 |
capsuleHeight | 胶囊的高度 |
capsuleRightMargin | 胶囊的右边框距离屏幕右边框的距离 |
capsuleCornerRadius | 胶囊的圆角半径 |
capsuleBorderWidth | 胶囊的边框宽度 |
capsuleBorderLightColor | 胶囊的浅色边框颜色 |
capsuleBorderDarkColor | 胶囊的深色边框颜色 |
capsuleBgLightColor | 胶囊的浅色下背景颜色 |
capsuleBgDarkColor | 胶囊的深色下背景颜色 |
moreLightImage | 胶囊的浅色更多按钮图片 |
moreDarkImage | 胶囊的深色更多按钮图片 |
moreBtnWidth | 胶囊的更多按钮宽度 |
moreBtnLeftMargin | 更多按钮的左边距 |
closeLightImage | 胶囊里的深色关闭按钮图片 |
closeDarkImage | 胶囊里的深色关闭按钮图片 |
closeBtnWidth | 胶囊里关闭按钮的宽度 |
closeBtnLeftMargin | 胶囊里关闭按钮的左边距 |
capsuleDividerLightColor | 胶囊里浅色分割线颜色 |
capsuleDividerDarkColor | 胶囊里的深色分割线颜色 |
我们的默认胶囊是这样:
那么,我们只需要这样设置,就可以变成圆角:
FATUIConfig *uiConfig = [[FATUIConfig alloc] init];
uiConfig.capsuleConfig.capsuleCornerRadius = 15.5;
效果如下:
1.2 打开小程序
打开小程序,其实是有两个场景:1.普通的打开小程序,这里一般只需要小程序id和服务器地址即可,只能打开上架的线上版本小程序;2.加密信息打开小程序,这个场景是扫描小程序平台上的二维码,得到二维码里的内容,然后使用二维码里的info(即加密信息)打开小程序。
1.2.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 *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(@"关闭小程序");
}];
1.2.2 加密信息打开小程序
这种情况流程一般会复杂一些,需要先扫描小程序平台上的二维码,得到二维码里的内容,然后取二维码里的info(即加密信息)调用该接口打开小程序。
/// 解密信息,并启动小程序
/// @param request 加密信息的request
/// @param parentVC 父页面
/// @param completion 完成回调
/// @param closeCompletion 关闭小程序时的回调
- (void)startAppletWithDecryptRequest:(FATAppletDecryptRequest *)request
InParentViewController:(UIViewController *)parentVC
completion:(void (^)(BOOL result, FATError *error))completion
closeCompletion:(dispatch_block_t)closeCompletion;
1.3 关闭小程序
1.3.1 关闭单个小程序
/**
关闭打开的指定小程序
@param animated 是否显示动画
@param completion 关闭完成的回调
*/
- (void)closeApplet:(NSString *)appletId animated:(BOOL)animated completion:(dispatch_block_t)completion;
1.3.2 关闭所有小程序
有些场景下,可能存在A小程序打开B小程序,B小程序打开C小程序的情况,这时想要关闭打开的所有小程序,可以使用该方法。
/**
关闭当前打开的所有小程序
@param completion 关闭完成的回调
*/
- (void)closeAllAppletsWithCompletion:(dispatch_block_t)completion;
1.3.3 关闭当前小程序
/**
关闭当前的小程序
@param animated 是否显示动画
@param completion 关闭完成的回调
*/
- (void)closeCurrentApplet:(BOOL)animated completion:(dispatch_block_t)completion;
1.3.4 其他关闭小程序
以下API都是上述api的旧版本,因为缺少了completion回调,所以未来可能会弃用。
/**
关闭打开的指定小程序
@param animated 是否显示动画
*/
- (void)closeApplet:(NSString *)appletId animated:(BOOL)animated;
/**
关闭当前打开的所有小程序
*/
- (void)closeAllApplets;
/**
关闭当前的小程序
@param animated 是否显示动画
*/
- (void)closeCurrentApplet:(BOOL)animated;
1.4 结束小程序
小程序被关闭后,并没有真的结束,而是在后台挂起。等下次打开小程序时,会立即将小程序切换至前台运行。 所以,如果我们希望小程序关闭后,真的被结束掉,可以根据实际情况调用以下API来结束单个小程序或所有小程序。
1.4.1 结束单个小程序
/**
删除内存中的某个小程序
*/
- (void)clearMemeryApplet:(NSString *)appletId;
1.4.2 结束所有小程序
/**
清空内存中缓存的小程序数据
*/
- (void)clearMemoryCache;
1.5 删除小程序
由于小程序的运行,会将小程序包和小程序信息缓存在本地,以后打开时速度会非常快。 所以,如果想要将小程序的所有信息都删除,那么可以调用以下api删除某个小程序或者删除所有小程序。
1.5.1 删除单个小程序
/**
从本地缓存中删除小程序
@param appletId 小程序id
@return BOOL 结果
*/
- (BOOL)removeAppletFromLocalCache:(NSString *)appletId;
1.5.2 删除所有小程序
/// 删除本地缓存的小程序
- (void)clearLocalApplets;
1.6 搜索小程序
要搜索小程序,需要两步:
- 确保在初始化SDK的时候,配置了该服务器信息;
- 调用该搜索接口搜索小程序
/// 搜索小程序
/// @param request 搜索的request
/// @param completion 搜索结果
- (void)searchAppletsWithRequest:(FATSearchAppletRequest *)request
completion:(void (^)(NSDictionary *result, FATError *aError))completion;
搜索小程序的示例:
FATSearchAppletRequest *searchRequest = [[FATSearchAppletRequest alloc] init];
searchRequest.apiServer = @"https://api.finclip.com";
searchRequest.text = @"小程序";
[[FATClient sharedClient] searchAppletsWithRequest:searchRequest completion:^(NSDictionary *result, FATError *aError) {
NSLog(@"");
}];
1.7 获取小程序对象信息
/// 获取当前正在运行的小程序对象
- (FATAppletInfo *)currentApplet;
1.8 获取小程序当前WebView信息
1.8.1 获取当前webView的URL
如果当前页面加载的不是H5,则会返回nil;如果加载的是H5,则会返回H5对应的NSURL。
/**
获取当前加载H5的URL
如果小程序当前页面加载的不是H5,则返回nil
*/
- (NSURL *)getCurrentWebViewURL;
1.8.2 获取当前webView的UserAgent
/**
获取小程序当前页面webView的userAgent
*/
- (void)getCurrentWebViewUserAgentWithCompletion:(void (^)(NSString *userAgent, NSError * error))completionHandler;
1.9 获取小程序页面截图
注意:这里生成的截图的宽高比是5:4。会从导航栏以下(0,0)绘制开始截取。
/**
生成当前页面截图
*/
- (UIImage*)getCurrentAppletImage;
1.10 获取使用过的小程序列表
获取打开过的所有小程序列表,已删除的小程序不包含。
/**
获取本地的小程序
@return 小程序数组<FATAppletInfo>
*/
- (NSArray *)getAppletsFromLocalCache;
1.11 微信小程序二维码信息转换为FinClip小程序
/// 解析微信小程序二维码,得到凡泰小程序信息
/// @param qrCode 微信二维码
/// @param apiServer 解析服务器url
/// @param completion 结果回调
- (void)parseAppletInfoFromWXQrCode:(NSString *)qrCode apiServer:(NSString *)apiServer completion:(void (^)(FATAppletSimpleInfo *appInfo, FATError *aError))completion;
该API的使用场景比较特别,当某小程序在微信和FinClip服务上都上架之后,可以在FinClip平台关联微信的小程序。这时FinClip平台上的线上版二维码,既可以用微信扫码打开,也可以用凡泰助手或其他集成了FinClip SDK的APP扫码打开。
流程是先扫描该二维码,得到二维码内容,然后调用该接口获取FinClip 小程序id,最后调用打开小程序的API即可。
1.12 代理方法
小程序的部分功能,需要原生端去实现才能调用,比如转发和获取主体App的用户信息等。
这些代理方法都声明在FATAppletDelegate中
/** 转发事件
当你点击小程序右上角更多里的转发菜单时,会触发小程序里shareAppMessage方法,然后回调到原生该方法
@param contentInfo 小程序相关信息,里面包含小程序id、小程序名称、小程序图标、小程序截图(5:4)等。
{
appAvatar = "小程序图标地址";
appDescription = "小程序的描述信息";
appId = "小程序id";
appInfo = {}; // 客户可在appInfo中自定义字段,appInfo内容会透传
appStartParams = {
path = "点击转发时的小程序页面路径";
};
appThumbnail = "小程序封面图的路径,可能是网络路径或者本地路径,宽高比是5:4";
appTitle = "小程序名称";
userId = "小程序开发者id";
}
@param completion 执行完后的回调,如果你转发操作执行完后,希望告知小程序端转发结果,就需要调用该block。
*/
- (void)forwardAppletWithInfo:(NSDictionary *)contentInfo completion:(void (^)(FATExtensionCode code, NSDictionary *result))completion;
/// 获取用户信息
/// @param appletInfo 小程序信息
- (NSDictionary *)getUserInfoWithAppletInfo:(FATAppletInfo *)appletInfo;
/// 更多按钮中自定义的菜单,会在页面弹出菜单时调用该api
/// @param appletInfo 小程序信息
/// @param path 页面路径
- (NSArray<id<FATAppletMenuProtocol>> *)customMenusInApplet:(FATAppletInfo *)appletInfo atPath:(NSString *)path;
/// 点击自定义菜单时,会触发的事件
/// @param customMenu 自定义菜单对象
/// @param appletInfo 小程序信息
/// @param path 当前页面路径
- (void)customMenu:(id<FATAppletMenuProtocol>)customMenu inApplet:(FATAppletInfo *)appletInfo didClickAtPath:(NSString *)path;
代理实现示例:
1.在合适的位置赋值实现代理方法的实例对象
[FATClient sharedClient].delegate = [FATClientHelper shareInstance];
2.创建实现代理方法的类
#import <Foundation/Foundation.h>
#import <FinApplet/FinApplet.h>
@interface FATClientHelper : NSObject<FATAppletDelegate>
+ (instancetype)shareInstance;
@end
3.在实现类(比如FATClientHelper)中实现对应的代理方法。
1.13 处理Open URL
/// 处理URL
/// @param URL 具体的URL路由
- (BOOL)handleOpenURL:(NSURL *)URL;
如果希望在Safari浏览器或其他App中打开自己的APP中的小程序,需要实现- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
方法。
示例代码:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
if ([[FATClient sharedClient] handleOpenURL:url]) {
return YES;
}
return YES;
}
1.14 处理Universal Link URL
/// 处理Universal Link
/// @param URL Universal Link URL
- (BOOL)handleOpenUniversalLinkURL:(NSURL *)URL;
同上面的handleOpenURL一样,如果想要支持universal link 的方式打开小程序。也得实现- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler
方法。
示例代码:
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
NSLog(@"url = %@",url.absoluteString);
return [[FATClient sharedClient] handleOpenUniversalLinkURL:url];
}
return YES;
}
1.15 保存文件至当前小程序临时目录
SDK支持原生保存文件到小程序的缓存目录,然后返回文件的本地路径,以供小程序使用。
/**
保存文件到小程序的缓存路径
@param fileData 文件的二进制数据
@param fileName 文件名,需要保证文件名唯一,否则可能会覆盖
@return 文件的本地路径,例如:finfile://tmp_fdfdkfjdkfjdkjfdkjf.jgp
*/
- (NSString *)saveFile:(NSData *)fileData fileName:(NSString *)fileName;
1.16 小程序文件路径转换为绝对路径
在有些场景下,我们拿到小程序的文件路径,无法获取到文件数据,这时可以用该方法转换为绝对路径。
比如,在使用小程序的转发功能时,返回的图片路径是小程序文件路径,可以用该方法转换为绝对路径,然后获取到图片数据再去调起第三方分享。 再比如,自定义api里,可以传递小程序文件路径的参数,宿主app用该方法转换为绝对路径后,即可拿到文件数据。
/**
将文件路径转为绝对路径
如果是 网络文件路径,则直接返回。
如果是小程序中的路径,比如finfile://tmp_fdfdkfjdkfjdkjfdkjf.jpg ,则会转为本地绝对路径
如果是小程序包中的文件路径,比如image/xxx.jpg,也会转为绝对路径
其他情况则返回传入的路径
@param path 文件路径
@return 文件的绝对路径
*/
- (NSString *)fat_absolutePathWithPath:(NSString *)path;
2. 高级API
2.1 注册自定义API
如果小程序里需要调用一些宿主app提供的能力,而FinClip SDK未实现或无法实现时,就可以注册一些自定义API。然后小程序里就可以像调用其他API一样调用注册的API了。
注册自定义API分两个场景:1.注册给原生小程序使用的自定义API;2.注册给小程序中web-view组件加载的H5使用的自定义API。
2.1.1 注册小程序API
注册自定义的小程序API的函数
/**
注册扩展Api
@param extApiName 扩展的api名称
@param handler 回调
@return 返回注册结果
*/
- (BOOL)registerExtensionApi:(NSString *)extApiName handle:(void (^)(id param, FATExtensionApiCallback callback))handler;
比如,我这里注册一个小程序APIcustomEvent
:
[[FATClient sharedClient] registerExtensionApi:@"customEvent" handle:^(id param, FATExtensionApiCallback callback) {
// xxxx
callback(FATExtensionCodeSuccess, nil);
}];
然后,在小程序的根目录创建 FinClipConf.js
文件,配置实例如下:
module.exports = {
extApi:[
{ //普通交互API
name: 'customEvent', //扩展api名 该api必须Native方实现了
params: { //扩展api 的参数格式,可以只列必须的属性
url: ''
}
}
]
}
extApi 是个数组,所以,您可以注册多个自定义API。
最后,在小程序里调用自定义的API,示例代码:
ft.customEvent({
url:'https://www.baidu.com',
success: function (res) {
console.log("调用customEvent success");
console.log(res);
},
fail: function (res) {
console.log("调用customEvent fail");
console.log(res);
}
});
2.1.2 注册小程序web-view组件API
小程序里加载的H5,如果也想调用宿主API的某个能力,就可以利用该方法注册一个API
/// 为HTML 注册要调用的原生 api
/// @param webApiName 原生api名字
/// @param handler 回调
- (BOOL)fat_registerWebApi:(NSString *)webApiName handle:(void (^)(id param, FATExtensionApiCallback callback))handler;
我这里为小程序里的H5注册了一个叫js2AppFunction
的方法,
[[FATClient sharedClient] fat_registerWebApi:@"js2AppFunction" handle:^(id param, FATExtensionApiCallback callback) {
NSString *name = param[@"name"];
// id params = param[@"data"];
if ([name isEqualToString:@"getLocation"]) {
// 执行定位逻辑
// 返回结果给HTML
NSDictionary *dict = @{@"errno":@"403", @"errmsg":@"无权限", @"result": @{@"address":@"广东省深圳市南山区航天科技广场"}};
callback(FATExtensionCodeSuccess, dict);
} else if ([name isEqualToString:@"getColor"]) {
// 执行其他逻辑
// 返回结果给HTML
NSDictionary *dict = @{@"r":@"110",@"g":@"150",@"b":@"150"};
callback(FATExtensionCodeSuccess, dict);
}
}];
在H5内引用我们的桥接JSSDK (opens new window)文件,即可调用上面的注册的方法了。
HTML内调用注册的方法示例:
window.FinChatJSBridge.invoke('js2AppFunction', {name:'getLocation'}, (result) => {
console.log(result)
});
2.2 原生调用JS API
同样的如果宿主App想要调用小程序加载的H5中的某个方法,就可以使用该API。
/// 原生调用HTML中的JS函数
/// @param eventName 函数名
/// @param paramString 函数的参数字典转成的json
/// @param pageId webView ID,可不传,默认调用最顶层页面里H5的函数
/// @param hanler 调用结果回调
- (void)fat_callWebApi:(NSString *)eventName paramString:(NSString *)paramString pageId:(NSNumber *)pageId handler:(void (^)(id result, NSError *error))hanler;
首先,在H5内引用我们的桥接JSSDK (opens new window)文件。
然后,在HTML里注册好方法,比如方法名叫app2jsFunction
。
window.FinChatJSBridge.webSubscribe('app2jsFunction', function(res) {
// app2jsFunction callback
})
最后,原生端调用如下API来调用HTML中的JS函数:
NSString *jsonParams = @""; //这里应该是参数字典转换成的json字符串。
NSNumber *pageId = @(1234); //这里是HTML中传过来的pageId
[[FATClient sharedClient] fat_callWebApi:@"app2jsFunction" paramString:jsonParams pageId:pageId handler:^(id result, NSError *error) {
}];
2.3 注册原生组件
由于资源有限,livePusher 和livePlayer等原生组件的实现可能需要借助外部的第三方控件,这时候就可以注册原生组件。我们现在支持注册的原生组件有三个:Camera、LivePlayer、LivePusher。
首先,创建组件视图,实现其协议方法。
.h
#import <UIKit/UIKit.h>
#import <FinApplet/FATAppletNativeProtocol.h>
NS_ASSUME_NONNULL_BEGIN
@interface FATNativeView : UIView <FATAppletNativeViewProtocol>
@property (nonatomic, strong) NSNumber *nativeViewId;
@property (nonatomic, strong) NSString *type;
@end
@interface FATNativeCameraView : FATNativeView <FATAppletNativeCameraProtocol>
@end
@interface FATNativeLivePlayerView : FATNativeView <FATAppletNativeLivePlayerProtocol>
@end
@interface FATNativeLivePusherView : FATNativeView <FATAppletNativeLivePusherProtocol>
@end
NS_ASSUME_NONNULL_END
.m
@implementation FATNativeView
+ (UIView *)onCreateView:(NSDictionary *)param {
return [[self alloc] initWithParam:param];
}
- (instancetype)initWithParam:(NSDictionary *)param {
CGRect frame = CGRectZero;
NSDictionary *style = [param objectForKey:@"style"];
if (style) {
CGFloat x = [[style objectForKey:@"left"] floatValue];
CGFloat y = [[style objectForKey:@"top"] floatValue];
CGFloat height = [[style objectForKey:@"height"] floatValue];
CGFloat width = [[style objectForKey:@"width"] floatValue];
frame = CGRectMake(x, y, width, height);
}
self = [super initWithFrame:frame];
if (self) {
_type = param[@"type"];
_nativeViewId = param[@"nativeViewId"];
}
return self;
}
- (void)onUpdateView:(NSDictionary *)param {
NSDictionary *style = [param objectForKey:@"style"];
if (style) {
CGRect frame = CGRectZero;
CGFloat x = [[style objectForKey:@"left"] floatValue];
CGFloat y = [[style objectForKey:@"top"] floatValue];
CGFloat height = [[style objectForKey:@"height"] floatValue];
CGFloat width = [[style objectForKey:@"width"] floatValue];
frame = CGRectMake(x, y, width, height);
self.frame = frame;
}
}
- (void)onDestroyView:(NSDictionary *)param {
NSLog(@"销毁了%@",param);
}
@end
@implementation FATNativeCameraView
- (void)setCameraZoom:(NSDictionary *)param success:(FATNativeCallback)callBack {
}
@end
@implementation FATNativeLivePlayerView
@end
@implementation FATNativeLivePusherView
@end
然后,设置组件的视图class
[FATClient sharedClient].nativeViewManager.cameraClass = [FATNativeCameraView class];
[FATClient sharedClient].nativeViewManager.livePlayerClass = [FATNativeLivePlayerView class];
[FATClient sharedClient].nativeViewManager.livePusherClass = [FATNativeLivePusherView class];
原生给nativeView发送消息
[[FATClient sharedClient].nativeViewManager sendEvent:@"eventName" nativeViewId:@(1234) detail:@{} completion:^(id result, NSError *error) {
}];
原生给小程序发送全局消息
[[FATClient sharedClient].nativeViewManager sendCustomEventWithDetail:@{} completion:^(id result, NSError *error) {
}];
2.4 注册自定义菜单
如果,您想往右上角的更多菜单中添加一些自己业务相关的菜单,那么就可以注入自定义的菜单。
首先,自定义一个FATClientHelper
类,实现FATAppletDelegate
协议。
#import <Foundation/Foundation.h>
#import <FinApplet/FinApplet.h>
@interface FATClientHelper : NSObject<FATAppletDelegate>
+ (instancetype)shareInstance;
@end
然后,在SDK初始化成功后后,设置SDK的代理为 FATClientHelper
对象。
示例代码
[[FATClient sharedClient] initWithConfig:config error:nil];
[FATClient sharedClient].delegate = [FATClientHelper shareInstance];
最后,在FATClientHelper
中实现,如下协议方法:
// 返回要注入的菜单对象,菜单对象是要实现 FATAppletMenuProtocol 协议的
// 菜单对象分为两种类型(默认为Common类型):
// 1.OnMiniProgram类型:需要后台配置+小程序配置,取相同menuId的集合显示
// 2.Common类型:配置则显示
// PS: 这里兼容旧版本,若后台未升级版本,或后台升级版本后未配置,则仅需要适配菜单对象的menuId为NSString类型
- (NSArray<id<FATAppletMenuProtocol>> *)customMenusInApplet:(FATAppletInfo *)appletInfo atPath:(NSString *)path
{
FATCustomMenuModel *favModel1 = [[FATCustomMenuModel alloc] init];
favModel1.menuId = @"WXShareAPPFriends";
favModel1.menuTitle = @"微信好友";
favModel1.menuIconImage = [UIImage imageNamed:@"minipro_list_wx_chat"];
favModel1.menuType = FATAppletMenuStyleOnMiniProgram;
FATCustomMenuModel *favModel2 = [[FATCustomMenuModel alloc] init];
favModel2.menuId = @"WXShareAPPMoments";
favModel2.menuTitle = @"微信朋友圈";
favModel2.menuIconImage = [UIImage imageNamed:@"minipro_list_wx_monents"];
favModel2.menuType = FATAppletMenuStyleOnMiniProgram;
FATCustomMenuModel *favModel3 = [[FATCustomMenuModel alloc] init];
favModel3.menuId = @"Restart";
favModel3.menuTitle = @"重启";
favModel3.menuIconImage = [UIImage imageNamed:@"minipro_list_restart"];
favModel3.menuType = FATAppletMenuStyleCommon;
return @[favModel1, favModel2, favModel3];
}
// 点击自定义菜单时的事件(旧版,后台未升级或升级后未配置菜单时使用)
- (void)customMenu:(id<FATAppletMenuProtocol>)customMenu inApplet:(FATAppletInfo *)appletInfo didClickAtPath:(NSString *)path
{
NSLog(@"点击了%@",customMenu.menuTitle);
NSLog(@"path = %@",path);
}
// 点击自定义菜单时的事件(新版,后台与小程序配置时使用)
- (void)clickCustomItemMenuWithInfo:(NSDictionary *)contentInfo completion:(void (^)(FATExtensionCode, NSDictionary *))completion
{
/**
contentInfo 中包含
{
@"title": @"标题",
@"description": @"描述",
@"imageUrl": @"图片路径",
@"path": @"点击时的小程序页面路径"",
@"menuId": @"点击的菜单按钮标识",
@"params": self.params // 原始参数数据,由小程序提供
}
*/
// 小程序回调调用,通知小程序点击事件处理情况
completion(FATExtensionCodeSuccess, contentInfo);
}
2.5 隐藏导航栏
如果想要将小程序页面的导航栏完全隐藏,自己实现导航栏,FinClip小程序SDK也是支持的。
像微信、支付宝、百度等小程序的navigationStyle
有 default/custom
两个值,而FinClip小程序SDK在此基础上,新增了一个hide
,即有default/custom/hide
三个值。
所以在需要隐藏导航栏的页面,设置navigationStyle
为hide
即可。
2.6 设置灰度发布自定义规则
小程序SDK的FATAppletDelegate
中一个协议方法:
- (NSDictionary *)grayExtensionWithAppletId:(NSString *)appletId
实现这个协议方法即可。
示例代码如下:
/// 小程序灰度扩展参数
/// @param appletId 小程序id
- (NSDictionary *)grayExtensionWithAppletId:(NSString *)appletId
{
NSDictionary *grayExtension = @{@"key1":@"value1"};
// if ([appletId isEqualToString:@"5e017a61c21ecf0001343e31"]) {
// grayExtension = @{@"fckey1":@"fcvalue1"};
// }
return grayExtension;
}
然后,小程序SDK在加载小程序时,会调用该协议方法获取小程序的灰度扩展参数,透传给后台服务匹配相关规则。
2.7 使用路由的形式打开小程序
有些时候,我们希望能在safari加载的网页里或者其第三方app打开自己app中的小程序,就需要实现对应的配置。
首先,确保集成SDK时,配置了URL Type,就是URL Schemes(fat+sdkKey的md5)那里。
然后,确保实现了handleOpenURL
。
最后,在H5里调用fat{sdkKey的md5}://applet/appid/{小程序id}
。
示例:fat705b46f78820c7a8://applet/appid/5e017a61c21ecf0001343e31
您可以在safari浏览器的地址栏中输入完成的url(比如:fat705b46f78820c7a8://applet/appid/5e017a61c21ecf0001343e31),然后回车即可打开您的app,然后打开小程序。
2.8 原生给小程序发送消息
[[FATClient sharedClient].nativeViewManager sendCustomEventWithDetail:@{} completion:^(id result, NSError *error) {
}];
3. 扩展SDK
扩展SDK 是对核心SDK的补充,所以要使用扩展SDK,也必须依赖核心SDK。 为了保证 SDK 的安全稳定性,将需要权限的API尽可能放到扩展SDK,FinClip 将 SDK 拆分为核心 SDK 与拓展 SDK,后者是前者的补充,因此使用拓展 SDK 也必须依赖核心 SDK。
在拓展 SDK 中,主要包含的功能见 # 3.2 小程序api一览
小节
3.1 注册扩展API
扩展SDK中的API,需要注册,否则小程序中也无法调用扩展SDK中的API。
[[FATExtClient sharedClient] fat_prepareExtensionApis];
3.2 小程序api一览
部分与权限相关的小程序api的是在扩展SDK中实现的,扩展SDK中包含的小程序api如下:
api名称 | api描述信息 |
---|---|
chooseLocation | 选择位置。 |
getLocation | 获取位置信息。 |
startRecord | 开始录音。 |
stopRecord | 停止录音。 |
getClipboardData | 获取剪贴板内容。 |
setClipboardData | 设置剪贴板内容。 |
RecorderManager | 全局唯一的录音管理器 |