iOS 集成
集成样例代码
可以在这里获取集成样例代码https://github.com/finogeeks/mop-ios-demo (opens new window)
1. 获取 SDK KEY 及 SDK SECRET
使用SDK需要申请 SDK KEY 及 SDK SECRET ,只有在SDK初始化的时候配置了正确的 SDK KEY 及 SDK SECRET ,才能初始化成功并正常使用。
1.1 创建应用
注册用户需要登录「应用管理-新增合作应用」,完成应用创建;
1.2 获取 SDK KEY 及 SDK SECRET
创建应用并添加Bundle ID后,若需要导出对应的SDK KEY与SDK SECRET,请选择对应 Bundle ID 后的「复制」,即可通过ctrl+v或command+v进行粘贴操作;
其中:
- SDK KEY:是合作应用能使用小程序SDK的凭证,如果SDK Key校验失败,则SDK的所有Api都无法使用。
- SDK SECERT:是访问服务的安全证书,不要给第三方。
提示
关于创建应用与获取 SDK KEY 及 SDK SECRET 的详细操作,见「介绍-操作指引-企业端操作指引-7.关联移动应用」一节。
2. 集成SDK
FinClip小程序SDK 目前支持pod集成或者手动集成。
注意
为了降低SDK导致的app体积的增长,我们做了各种裁剪和优化,从2.30.1(含2.30.1)开始,SDK从动态库调整为静态库,这样集成SDK后打出来的ipa安装包体积增长不会超过2M。pod集成,过程没有任何变化;手动集成,步骤有调整。
2.1 Pod集成
2.1.1 安装pod环境
Cocoapods 提供了一个非常简单的依赖管理系统,避免手动导入产生的错误。 如果您没有安装过Cocoapods,可以查看官方安装指南(英文) (opens new window)或史上最详细的CocoaPods安装教程(中文) (opens new window)。
sudo gem install cocoapods
pod setup
2.1.2 创建Podfile文件
注意
从2.8.5版本开始,FinClip小程序SDK分为核心SDK(FinApplet)和扩展SDK(FinAppletExt)。把部分需要权限的api移到了扩展SDK中,核心SDK中只包含一些必要权限的api和不需要权限的api。核心SDK只包含相册、摄像头、麦克风三个权限,其他需要申请权限的api都会移动到扩展SDK中。
所以,如果你不需要使用扩展SDK,那么在podfile中只依赖FinApplet
即可。如果你需要使用扩展SDK中的api,那么你还需要依赖FinAppletExt
。
在 Xcode 项目的根目录下,新建一个Podfile文件,在Podfile文件中添加对小程序SDK的依赖:
pod 'FinApplet'
pod 'FinAppletExt'
Podfile示例:
platform :ios, "9.0"
inhibit_all_warnings!
target "FinoAppletDemo" do
pod 'FinApplet'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_STRICT_OBJC_MSGSEND'] = 'NO'
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
end
end
end
2.1.3 安装或更新依赖
然后,执行 pod update
或者 pod install
即可。
2.1.4 打开工程
执行完 pod update
或者 pod install
,打开工程目录,找到xxx.xcworkspace文件,双击打开即可。
2.2 手动集成
为了方便开发者快速体验运行以及使用模拟器开发调试,我们的SDK中包含x86_64架构,所以在上架 AppStore 之前,一定要记得删除x86_64架构。您可以自己手动删除,也可以自己网上找脚本删除,或者按照3.2.4给工程配置脚本。工程配置脚本,开发调试依然可以使用模拟器,但是archive 时,会自动去除模拟器架构。
当然,你也可以说明只需要真机架构,那么我们就只交付包含真机架构的SDK。
注意
- 版本号 低于 2.30.1 的全部为动态库。
- 版本号在2.30.1(含2.30.1) ~ 2.32.1(含2.32.1)之间的全部为静态库。
- 版本号 高于 2.32.1 的全部为动态库。
2.2.1 集成动态库
2.2.1.1 添加SDK至工程
将FinApplet.framework拖进工程。
当然,如果你需要用到FinAppletExt.framework中的api,那么,你还得把FinAppletExt.framework也拖进工程。
2.2.1.2 修改工程配置
则需要按照如下配置即可:
如果你需要用到FinAppletExt.framework中的api,那么,你还得把FinAppletExt.framework也添加进Copy Files中。
2.2.1.3 打开工程
双击xxxx.xcodeproj,打开工程。
2.2.1.4 配置archive脚本
SDK中包含x86_64架构,便于我们开发时用模拟器调试。但是x86_64架构的SDK,打包上传应用市场时会报错,所以配置一个打包时自动去除模拟器架构的脚本,可以让我们既可以用模拟器开发调试,又能正常提交应用市场。
当然,你也可以找我们要一个不包含模拟器的SDK。
脚本内容如下:
#!/bin/sh
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
echo "current binary ${binary}"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
if [ -f "$binary" ]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
fi
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
}
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
strip_invalid_archs "$FRAMEWORK_EXECUTABLE_PATH"
done
2.2.2 集成静态库
2.2.2.1 添加SDK至工程
将FinClip SDK 拖进工程。
当然,如果你不需要用到FinAppletExt.framework中的api,那么,你也可以不添加FinAppletExt.framework 和 FinAppletExt.bundle。
2.2.2.2 修改工程配置
1)添加依赖的系统动态库:
2)Build Setting ->Other Linker Flags中添加-ObjC。
2.2.2.3 打开工程
双击xxxx.xcodeproj,打开工程。
2.2.2.4 配置archive脚本
SDK中包含x86_64架构,便于我们开发时用模拟器调试。但是x86_64架构的SDK,打包上传应用市场时会报错,所以配置一个打包时自动去除模拟器架构的脚本,可以让我们既可以用模拟器开发调试,又能正常提交应用市场。
当然,你也可以找我们要一个不包含模拟器的SDK。
脚本内容如下:
#!/bin/sh
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
echo "current binary ${binary}"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
if [ -f "$binary" ]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
fi
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
}
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
strip_invalid_archs "$FRAMEWORK_EXECUTABLE_PATH"
done
3. 增加隐私权限
在工程info.plist文件中增加隐私权限
如果您使用的小程序中使用到了相册、摄像头、位置、录音等功能,您需要配置如下隐私权限:
- Privacy - Photo Library Usage Description 需要访问您的相册
- Privacy - Microphone Usage Description 需要访问您的麦克风
- Privacy - Camera Usage Description 需要访问您的摄像机
- Privacy - Location Always Usage Description 需要您的同意,才能始终访问位置
- Privacy - Location When In Use Usage Description 需要您的同意,才能在使用期间访问位置
注意
如果你的工程里已经配置过这些权限,那就不用再添加了。 另外,如果您仅需要核心SDKFinApplet,那么您只需要配置相册、摄像头的权限描述信息。 如果,您也需要用到扩展SDKFinAppletExt,那么您就需要再配置上位置、录音等权限的描述信息。
另外,如果你的小程序中的请求或者网页有使用到http协议的,还需要在工程里配置如下参数:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
也就是【App Transport Security Settings】-> 【Allow Arbitrary Loads】设置为YES。
4. 添加URL Type
注意
第5步和第8步不是必须项,如果您的 App 会通过其他 App(safari、微信等)打开您 App 中的小程序,那么就必须配置第5步和第8步。
选择 Target -> 【Info】 -> 【URL Types】,新增一个URL Schemes(URL Schemes的格式是fat+sdkKey的md5。)
先将sdkKey生成16位小写md5,然后在加上fat前缀。
关于如何使用,可参考使用路由的形式打开小程序。
5. 添加SDK头文件
在需要使用FinClip小程序SDK的地方,添加如下代码:
#import <FinApplet/FinApplet.h>
如果还集成了扩展SDK,那么调用扩展SDK中的api,还需要加上下面的代码:
#import <FinAppletExt/FinAppletExt.h>
当然,最方便的方式是在 pch 文件中添加以上代码,这样在使用的地方就不用再引用了。
6. 初始化 SDK
在工程的 AppDelegate 中的以下方法中,调用 SDK 的初始化方法。
注意
从2.13.109版本开始,FinClip SDK 支持配置多个服务器信息,可以同时打开多个不同服务器上的小程序,所以初始化方式有所变更,您可以将服务器配置信息写入plist文件,然后按照如下示例初始化。
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];
也可以这样初始化:
NSMutableArray *storeArrayM = [NSMutableArray array];
FATStoreConfig *storeConfig = [[FATStoreConfig alloc] init];
storeConfig.sdkKey = @"您的sdkKey信息";
storeConfig.sdkSecret = @"您的sdkSecret信息";
storeConfig.apiServer = @"服务器域名";
storeConfig.apiPrefix = @"/api/v1/mop";
storeConfig.apmServer = @"apm统计事件的域名";
[storeArrayM addObject:storeConfig];
FATStoreConfig *storeConfig2 = [[FATStoreConfig alloc] init];
storeConfig2.sdkKey = @"您的sdkKey信息";
storeConfig2.sdkSecret = @"您的sdkSecret信息";
storeConfig2.apiServer = @"服务器域名";
storeConfig2.apiPrefix = @"/api/v1/mop";
storeConfig2.apmServer = @"apm统计事件的域名";
storeConfig2.cryptType = FATApiCryptTypeSM;
[storeArrayM addObject:storeConfig2];
FATConfig *config = [FATConfig configWithStoreConfigs:storeArrayM];
[[FATClient sharedClient] initWithConfig:config error:nil];
注意
2.21.1 以及之后的版本,不再需要调用配置扩展SDK,SDK 内部会自动判断是否集成扩展SDK,自动触发配置扩展SDK。
当然,如果您需要使用到扩展SDK中的Api,那么您还需要在初始化SDK之后,配置扩展api。 调用一次如下代码即可:
// 准备扩展api
[[FATExtClient sharedClient] fat_prepareExtensionApis];
注意
如果未设置currentUserId,则缓存数据会缓存到默认目录,获取最近打开小程序列表时,获取到的是默认目录下的小程序。如果要不同用户使用不同的缓存目录,请不同用户设置不同的currentUserId。
7. handleOpenURL处理
小程序支持外部通过链接打开小程序,需要做如下处理。
- (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;
}
8. 打开小程序
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(@"关闭小程序");
}];
其他关于FinClip小程序SDK API介绍,请查看 API 说明文档。