SMH UIKit 是一套开箱即用的云盘文件管理 UI Kit,底层对接腾讯云 SMH(智能媒体托管)服务。接入方只需提供几个配置参数和一个 Token 获取函数,即可在自己的应用中嵌入完整的云盘能力——无需从零开发文件管理。
iOS & Android
iOS

Android

鸿蒙(OHOS)& 微信小程序 & H5
| 鸿蒙(OHOS) | 微信小程序 | H5 |
|---|---|---|
![]() | ![]() | ![]() |
在接入之前,你需要准备以下内容:
在 智能媒资托管控制台 创建媒体库,获取:
| 参数 | 说明 | 示例 |
|---|---|---|
host | SMH API 服务地址 | https://xxx.api.tencentsmh.cn |
libraryId | 媒体库 ID | smhxxx-xxxxx |
librarySecret | 媒体库密钥(仅后端持有) | your_secret |
spaceId | 空间 ID(每个用户/租户一个) | spaceyyyyyy |
UI Kit 在客户端通过 SDK 直连 SMH API 完成所有文件操作。每次请求都需要携带一个 accessToken 作为身份凭证。但签发 Token 需要 librarySecret(媒体库密钥),密钥绝不能暴露给客户端。因此必须由你的后端持有密钥,调用 SMH API 签发 Token,再返回给前端使用。
Node.js 示例:
app.post('/api/generate-space-token', async (req, res) => {
const { spaceId } = req.body;
const params = new URLSearchParams({
library_id: process.env.SMH_LIBRARY_ID,
library_secret: process.env.SMH_LIBRARY_SECRET, // ⚠️ 仅后端持有
Grant: 'space_admin',
Period: '7200',
spaceId,
});
const response = await fetch(`${process.env.SMH_BASE_PATH}/api/v1/token?${params}`);
const tokenData = await response.json();
res.json({
token: tokenData.accessToken,
startTime: Date.now(),
expiresIn: 7200,
});
});
后端 SDK 可使用 smh-node-sdk 快速搭建:
npm install smh-node-sdk
SDK 产物在根目录中:
| 平台 | 下载地址 |
|---|---|
| Android | android目录 |
| iOS | ios目录 |
| OHOS(鸿蒙) | ohos目录 |
| H5 | h5目录 |
| 微信小程序 | miniapp目录 |
💡 根目录中的 demo 目录为示例项目,其中已经依赖了产物 SDK,可以直接运行。
所有平台遵循统一的接入心智:配置 → Token → 打开页面。
环境要求
| 项目 | 要求 |
|---|---|
| minSdk | 21 |
| JDK | 17 |
| Kotlin | 2.1.21 |
Step 1 — 添加仓库和依赖
从 COS 下载本地 Maven 仓库目录,放到项目中(例如 libs/repo):
your-project/ ├── app/ ├── libs/ │ └── repo/ ← 将下载的 repo 目录放到这里 ├── build.gradle.kts └── settings.gradle.kts
在 settings.gradle.kts 中添加仓库:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
// AgentStorage UIKit 本地 Maven 仓库
maven { url = uri("${rootProject.projectDir}/libs/repo") }
// 运行时依赖仓库(必须)
maven { url = uri("https://mirrors.tencent.com/nexus/repository/maven-tencent/") }
}
}
在 App 模块的 build.gradle.kts 中添加:
dependencies {
implementation("com.qcloud.cos:smh-ui-kit:<version>")
}
Step 2 — 打开文件管理页面
import com.tencent.qcloud.smh.uikit.internal.SmhUiKit
import com.tencent.qcloud.smh.uikit.smh.AccessToken
import com.tencent.qcloud.smh.uikit.smh.SmhAccessTokenProvider
import com.tencent.qcloud.smh.uikit.smh.SmhConfig
// 1. 配置
val smhConfig = SmhConfig(
host = "https://xxx.api.tencentsmh.cn",
libraryId = "your-library-id",
spaceId = "your-space-id",
downloadPath = getExternalFilesDir("SMHDownload")?.absolutePath ?: filesDir.absolutePath + "/SMHDownload",
identifier = "identifier"
)
// 2. 实现 Token 提供者
val tokenProvider = object : SmhAccessTokenProvider {
override suspend fun getAccessToken(): AccessToken {
// 从您的服务端获取 Token(在后台线程调用,可进行网络请求)
val result = YourApi.getSmhToken()
return AccessToken(
token = result.token,
startTime = System.currentTimeMillis(),
expiresIn = result.expiresIn // 有效时长(秒)
)
}
}
// 3. 创建 Fragment 并添加到 Activity
val fragment = SmhUiKit.newFragment(smhConfig, tokenProvider)
supportFragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null)
.commit()
完成!Fragment 会自动处理 Token 复用、文件操作、UI 交互等所有逻辑。
权限说明
SDK 已内置声明网络和存储权限,会自动合并到您的应用中。如果 targetSdk >= 33,建议额外声明:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
环境要求
| 项目 | 要求 |
|---|---|
| iOS | 12.0+ |
| Xcode | 15+ |
| CocoaPods | 1.11+ |
Step 1 — 添加 Pod 依赖
在 Podfile 中添加:
target 'YourApp' do
use_frameworks!
platform :ios, '12.0'
// cnb 根目录下 ios 为 sdk 产物,可以直接依赖
pod 'QCloudSMHUIKit', :path => '../../ios'
end
执行安装:
pod install
Step 2 — 打开文件管理页面
Swift 示例:
import QCloudSMHUIKit
// 1. 配置
let config = SMHConfig(
host: "https://xxx.api.tencentsmh.cn",
libraryId: "your-library-id",
spaceId: "your-space-id",
downloadPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/SMHDownload",
identifier: "identifier"
)
// 2. 实现 Token 提供者
class MyTokenProvider: NSObject, SMHAccessTokenProvider {
func getAccessToken() -> SMHAccessToken? {
let result = YourApi.fetchSmhTokenSync()
return SMHAccessToken(
token: result.token,
startTime: Int64(Date().timeIntervalSince1970 * 1000),
expiresIn: result.expiresIn
)
}
}
// 3. 打开文件管理页面
let vc = SMHUIKitSDK.fileListViewController(
with: config,
accessTokenProvider: MyTokenProvider()
)
navigationController?.pushViewController(vc, animated: true)
SwiftUI 示例:
import SwiftUI
import QCloudSMHUIKit
struct SmhFileView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UINavigationController {
let config = SMHConfig(
host: "https://xxx.api.tencentsmh.cn",
libraryId: "your-library-id",
spaceId: "your-space-id",
downloadPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/SMHDownload",
identifier: "identifier"
)
let vc = SMHUIKitSDK.fileListViewController(
with: config,
accessTokenProvider: MyTokenProvider()
)
return UINavigationController(rootViewController: vc)
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
}
权限说明
在 Info.plist 中添加以下权限描述:
<key>NSPhotoLibraryUsageDescription</key>
<string>用于从相册选择图片上传文件</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>用于将下载的图片或视频保存到相册</string>
环境要求
| 项目 | 要求 |
|---|---|
| HarmonyOS | 5.0+ |
| DevEco Studio | 5.0+ |
Step 1 — 添加 HAR 依赖
从 cnb 根目录下 ohos 目录复制 OHOS 产物 smh-ui-kit.har 到工程中,例如:
your-ohos-project/ ├── entry/ │ ├── libs/ │ │ └── smh-ui-kit.har │ └── src/ └── oh-package.json5
在 entry/oh-package.json5 中添加依赖:
{ "dependencies": { "smh-ui-kit": "file:./libs/smh-ui-kit.har" } }
Step 2 — 初始化 SDK
在 UIAbility 的 onWindowStageCreate() 中调用:
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import { SmhUiKit } from 'smh-ui-kit';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
SmhUiKit.init();
windowStage.loadContent('pages/Index');
}
}
Step 3 — 打开文件管理页面
import { AccessToken, SmhAccessTokenProvider, SmhUiKit } from 'smh-ui-kit';
const smhConfig = {
host: 'https://xxx.api.tencentsmh.cn',
libraryId: 'your-library-id',
spaceId: 'your-space-id'
};
class MyTokenProvider implements SmhAccessTokenProvider {
getAccessToken(): AccessToken {
const result = YourApi.getSmhTokenSync();
return {
token: result.token,
startTime: Date.now(),
expiresIn: result.expiresIn
};
}
}
SmhUiKit.openPage(smhConfig, new MyTokenProvider());
环境要求
| 项目 | 要求 |
|---|---|
| 浏览器 | 支持 ES6 的现代浏览器(Chrome、Safari、Firefox、Edge 等) |
产物说明
从 cnb 根目录下 h5 目录复制产物到工程中,产物包含以下文件:
h5/ ├── index.html # 入口页面 ├── h5App.js # SDK 核心 JS ├── page/ │ └── smh_ui_kit.js # 业务逻辑 JS └── assets/ # 资源文件
Step 1 — 部署静态文件
将产物中的所有文件部署到您的 Web 服务器,保持目录结构不变。例如部署到 https://your-domain.com/smh/:
https://your-domain.com/smh/ ├── index.html ├── h5App.js ├── page/smh_ui_kit.js └── assets/...
Step 2 — 加载 SDK 脚本
按您的部署目录选择对应路径。
如果 H5 产物直接部署在当前页面同级目录下,请使用:
<script src="./page/smh_ui_kit.js" type="text/javascript"></script>
<script src="./h5App.js" type="text/javascript"></script>
如果您将整套产物放在 sdk/ 子目录下,请使用:
<script src="./sdk/page/smh_ui_kit.js" type="text/javascript"></script>
<script src="./sdk/h5App.js" type="text/javascript"></script>
💡 发布产物自带的
index.html默认使用根目录相对路径:page/smh_ui_kit.js与h5App.js。
Step 3 — 打开文件管理页面
调用 window.SmhUiKit.openPage(smhConfig, accessTokenProvider, pageName):
smhConfig:SMH 配置对象accessTokenProvider:需要实现 getAccessToken(callback)pageName:可选,默认为 smh_netdisk<script>
function buildAccessTokenProvider() {
return {
getAccessToken: function(callback) {
fetch('https://your-server.com/api/smh/token')
.then(function(res) { return res.json(); })
.then(function(data) {
callback({
accessToken: data.token,
token: data.token,
startTime: data.startTime,
expiresIn: data.expiresIn
});
})
.catch(function() {
callback({ errorMsg: '获取 Token 失败' });
});
}
};
}
var smhConfig = {
host: 'https://xxx.api.tencentsmh.cn',
libraryId: 'your-library-id',
spaceId: 'your-space-id'
};
window.SmhUiKit.openPage(smhConfig, buildAccessTokenProvider(), 'smh_netdisk');
</script>
嵌入到已有页面(iframe 方式)
如果您希望将文件管理嵌入到已有页面中,可以使用 iframe 承载部署后的 H5 页面,再由 iframe 内宿主页面主动调用 window.SmhUiKit.openPage(...)。
环境要求
| 项目 | 要求 |
|---|---|
| 微信开发者工具 | 最新稳定版 |
| 基础库 | 3.6.1+ |
集成方式:分包引入
SMH UI Kit 以分包形式集成到您的小程序中,不影响主包体积。
Step 1 — 拷贝分包目录
从 cnb 根目录下 miniapp 目录拿到 SDK 产物,将所有文件拷贝到您小程序项目根目录下的 smh-ui-kit/ 目录:
your-miniapp-project/ ├── pages/ # 您的主包页面 │ └── index/ ├── smh-ui-kit/ # ← 将产物文件放到这里(整个目录) ├── app.js ├── app.json └── project.config.json
⚠️ 请保持
smh-ui-kit/内部的文件结构不变,不要移动或删除其中的文件。
Step 2 — 配置分包路由
在 app.json 中添加分包配置:
{
"pages": [
"pages/index/index"
],
"subPackages": [
{
"root": "smh-ui-kit",
"pages": ["index"]
}
],
"window": {
"navigationStyle": "custom"
}
}
Step 3 — 注册 AccessTokenProvider
当前发布产物中的 smh-ui-kit/index.js 已经内置完成 SDK 初始化、全局方法挂载和页面注册;宿主侧不需要再手动 require('./smh-ui-kit/lib/miniApp.js') 或调用 initSDK() / initApp()。
宿主只需要在打开页面前,将 AccessTokenProvider 注册到全局表:
if (!global._smhAccessTokenProviders) {
global._smhAccessTokenProviders = {};
}
function createSmhAccessTokenProvider() {
return function(callback) {
wx.request({
url: 'https://your-server.com/api/smh/token',
success: function(res) {
callback({
token: res.data.token,
accessToken: res.data.token,
startTime: res.data.startTime,
expiresIn: res.data.expiresIn
});
},
fail: function() {
callback({ errorMsg: '获取 Token 失败' });
}
});
};
}
Step 4 — 跳转到分包页面
通过路由参数传入 SmhConfig 和 smh_access_token_provider_key:
function openSmhPage() {
var providerKey = 'provider_' + Date.now();
var smhConfig = {
host: 'https://xxx.api.tencentsmh.cn',
libraryId: 'your-library-id',
spaceId: 'your-space-id'
};
global._smhAccessTokenProviders[providerKey] = createSmhAccessTokenProvider();
wx.navigateTo({
url: '/smh-ui-kit/index?SmhConfig='
+ encodeURIComponent(JSON.stringify(smhConfig))
+ '&smh_access_token_provider_key='
+ encodeURIComponent(providerKey)
+ '&page_name=smh_netdisk'
});
}
其中:
SmhConfig:SMH 配置对象,SDK 会自动从路由参数中读取smh_access_token_provider_key:用于在全局 provider 注册表中定位当前页面实例对应的 TokenProviderpage_name:可选,默认值为 smh_netdisk⚠️ 不要修改发布产物中的
smh-ui-kit/index.js,也不要在app.js中重复初始化 SDK,否则可能导致页面注册冲突。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
host | String | ✅ | SMH API 地址,如 https://xxx.api.tencentsmh.cn |
libraryId | String | ✅ | 媒体库 ID |
spaceId | String | ✅ | 空间 ID |
downloadPath | String | ✅ | 默认下载根路径 |
identifier | String | ✅ | 业务层标识,一般用于不同业务的 SDK 层数据隔离 |
path | String | ❌ | 初始 space 目录路径,默认根目录 |
userId | String | ❌ | 用户 ID(SMH 服务端概念) |
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
token | String | ✅ | 访问凭证 |
startTime | Long/Int64/number | ✅ | Token 起始时间(毫秒时间戳) |
expiresIn | Int/number | ✅ | 有效时长(秒) |
💡
startTime和expiresIn用于描述 Token 有效期。SDK 内部会优先复用未过期 Token,接入方无需额外管理 Token 生命周期。
librarySecret 绝不能暴露给客户端,Token 的生成必须在后端完成必须在你的服务端生成,客户端通过网络请求获取。不要在客户端硬编码 Token。
SMH UI Kit 需要基础库 3.6.1 及以上。在微信开发者工具中:「设置 → 项目设置 → 调试基础库」中选择 3.6.1+。
请检查:
page/smh_ui_kit.js、assets/ 等需和 index.html 在同一目录层级)| 资源 | 链接 |
|---|---|
| 后端 SDK(smh-node-sdk) | https://www.npmjs.com/package/smh-node-sdk |
| SMH 文档 | https://cloud.tencent.com/document/product/1339 |