| name | hai-capacitor |
| description | 使用 @h-ai/capacitor 桥接 Capacitor 原生能力(Token 安全存储、设备信息、推送通知、相机、状态栏),构建 Android/iOS 原生应用;当需求涉及原生 App 开发、Capacitor 集成、安全存储或原生设备功能时使用。 |
hai-capacitor
能力契约
| 项目 | 契约 |
|---|
| 能力 | 使用 @h-ai/capacitor 桥接 Capacitor 原生能力(Token 安全存储、设备信息、推送通知、相机、状态栏),构建 Android/iOS 原生应用;当需求涉及原生 App 开发、Capacitor 集成、安全存储或原生设备功能时使用。 |
| 适用场景 | 当任务与 hai-capacitor 的能力描述匹配,并且需要遵循本 Skill 的流程和边界时 |
| 输入 | 用户目标、仓库与运行环境上下文、现有配置、授权范围和质量门禁 |
| 输出 | 与目标匹配的配置/代码/文档或审查结论,以及可复现的验证结果 |
| 限制 | 不扩张用户授权,不输出或固化密钥,不跳过失败门禁,不假定外部服务状态 |
@h-ai/capacitor 是 hai-framework 的 Capacitor 原生桥接模块,封装常用原生能力为统一 API,返回 HaiResult<T>。与 @h-ai/api-client 配合时,Token 仅存于原生安全存储,不回退到 Web localStorage。
运行环境
浏览器端 / 原生 App 专用。 在 Capacitor 原生环境(Android/iOS)中提供完整能力;createCapacitorTokenStorage() 仅在原生环境持久化 token,纯 Web 不做不安全回退。capacitor.preferences 仍可用于普通偏好数据。
适用场景
- Android/iOS 原生应用开发(Svelte 5 + Vite + Capacitor)
- Token 安全存储(
@aparajita/capacitor-secure-storage)
- 设备信息获取(平台、型号、版本)
- 推送通知注册与监听(FCM / APNs)
- 原生相机拍照 / 相册选取
- 状态栏配置(沉浸式、颜色、样式)
使用步骤
1. 初始化与关闭
import { capacitor } from '@h-ai/capacitor'
const result = await capacitor.init()
if (!result.success) {
}
capacitor.isInitialized
capacitor.getPlatform()
capacitor.isNative()
await capacitor.close()
2. Token 安全存储(与 api-client 配合)
import { apiClient } from '@h-ai/api-client'
import { createCapacitorTokenStorage } from '@h-ai/capacitor'
await apiClient.init({
baseUrl: import.meta.env.PUBLIC_API_BASE,
auth: {
storage: createCapacitorTokenStorage(),
refreshPath: '/api/v1/auth/refresh',
},
})
createCapacitorTokenStorage() 返回 TokenStorage 实例(兼容 @h-ai/api-client),底层使用 @aparajita/capacitor-secure-storage:
- Android → Android KeyStore + 加密 SharedPreferences
- iOS → Keychain
- Web → 不回退到 localStorage;
get*() 返回 null,set*() / clear() 为 no-op
所有方法内置 try-catch;原生安全存储异常时 get 返回 null、set/clear 静默失败并记录日志。
Preferences 子操作
import { capacitor } from '@h-ai/capacitor'
const result = await capacitor.preferences.get('my_key')
if (result.success) {
}
await capacitor.preferences.set('my_key', 'value')
await capacitor.preferences.remove('my_key')
3. 设备信息
import { capacitor } from '@h-ai/capacitor'
const info = await capacitor.device.getInfo()
if (info.success) {
info.data.platform
info.data.model
info.data.osVersion
info.data.manufacturer
info.data.isVirtual
}
const version = await capacitor.device.getAppVersion()
if (version.success) {
version.data.version
version.data.build
}
4. 推送通知
import { capacitor } from '@h-ai/capacitor'
const reg = await capacitor.push.register()
if (reg.success) {
await api.post('/push/register', { token: reg.data.token })
}
const listenResult = await capacitor.push.listen({
onReceived: (notification) => {
},
onActionPerformed: (notification) => {
},
})
if (listenResult.success) {
await listenResult.data()
}
5. 相机
import { capacitor } from '@h-ai/capacitor'
const photo = await capacitor.camera.takePhoto({
quality: 80,
source: 'camera',
resultType: 'base64',
width: 800,
height: 600,
})
if (photo.success) {
const imgSrc = `data:image/${photo.data.format};base64,${photo.data.data}`
}
6. 状态栏
import { capacitor } from '@h-ai/capacitor'
await capacitor.statusBar.configure({
backgroundColor: '#ffffff',
style: 'dark',
overlay: true,
})
await capacitor.statusBar.hide()
await capacitor.statusBar.show()
核心 API
| API | 用途 | 返回值 |
|---|
capacitor.init() | 初始化模块(检测环境) | HaiResult<void> |
capacitor.close() | 关闭模块,重置状态 | Promise<void> |
capacitor.getPlatform() | 获取当前平台 | 'android' | 'ios' | 'web' |
capacitor.isNative() | 是否为原生环境 | boolean |
capacitor.isInitialized | 是否已初始化 | boolean |
createCapacitorTokenStorage() | 创建 Token 存储 | TokenStorage(兼容 api-client) |
capacitor.preferences.get(key) | 安全读取 Preference | HaiResult<string | null> |
capacitor.preferences.set(key, value) | 安全写入 Preference | HaiResult<void> |
capacitor.preferences.remove(key) | 安全删除 Preference | HaiResult<void> |
capacitor.device.getInfo() | 设备信息 | HaiResult<DeviceInfo> |
capacitor.device.getAppVersion() | 应用版本 | HaiResult<{ version, build }> |
capacitor.push.register() | 注册推送 | HaiResult<PushRegistration> |
capacitor.push.listen(callbacks) | 监听推送事件 | HaiResult<() => Promise<void>>(async 清理函数) |
capacitor.camera.takePhoto(options?) | 拍照 / 选取图片 | HaiResult<PhotoResult> |
capacitor.statusBar.configure(config) | 配置状态栏 | HaiResult<void> |
capacitor.statusBar.show() | 显示状态栏 | HaiResult<void> |
capacitor.statusBar.hide() | 隐藏状态栏 | HaiResult<void> |
错误码 — HaiCapacitorError
| 错误码 | code | 说明 |
|---|
HaiCapacitorError.INIT_FAILED | hai:capacitor:001 | 初始化失败 |
HaiCapacitorError.NOT_AVAILABLE | hai:capacitor:002 | Capacitor 不可用 |
HaiCapacitorError.INIT_IN_PROGRESS | hai:capacitor:003 | 正在初始化中 |
HaiCapacitorError.NOT_INITIALIZED | hai:capacitor:010 | 模块未初始化 |
HaiCapacitorError.PREFERENCES_GET_FAILED | hai:capacitor:011 | Preferences 读取失败 |
HaiCapacitorError.PREFERENCES_SET_FAILED | hai:capacitor:012 | Preferences 写入失败 |
HaiCapacitorError.PREFERENCES_REMOVE_FAILED | hai:capacitor:013 | Preferences 删除失败 |
HaiCapacitorError.DEVICE_INFO_FAILED | hai:capacitor:020 | 获取设备信息失败 |
HaiCapacitorError.APP_VERSION_FAILED | hai:capacitor:021 | 获取应用版本失败 |
HaiCapacitorError.PUSH_REGISTER_FAILED | hai:capacitor:030 | 推送注册失败 |
HaiCapacitorError.PUSH_LISTEN_FAILED | hai:capacitor:031 | 推送监听失败 |
HaiCapacitorError.CAMERA_FAILED | hai:capacitor:040 | 拍照/相册失败 |
HaiCapacitorError.STATUS_BAR_FAILED | hai:capacitor:050 | 状态栏配置失败 |
常见模式
Mobile App 标准初始化
import { capacitor } from '@h-ai/capacitor'
export async function initCapacitor() {
const result = await capacitor.init()
if (!result.success) {
return
}
if (capacitor.isNative()) {
await capacitor.statusBar.configure({
backgroundColor: '#ffffff',
style: 'light',
overlay: false,
})
}
}
<!-- src/App.svelte -->
<script lang='ts'>
import { onMount } from 'svelte'
import { initCapacitor } from './lib/capacitor'
onMount(() => { initCapacitor() })
</script>
SPA 模式配置(必需)
Capacitor 应用使用 Vite 构建 SPA,并让原生壳读取 dist:
import type { CapacitorConfig } from '@capacitor/cli'
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'Example App',
webDir: 'dist',
}
export default config
Token 存储 + 认证流程
import { apiClient } from '@h-ai/api-client'
import { createCapacitorTokenStorage } from '@h-ai/capacitor'
export async function initApi() {
return apiClient.init({
baseUrl: `${import.meta.env.PUBLIC_API_BASE}/api/v1`,
auth: {
storage: createCapacitorTokenStorage(),
refreshPath: '/auth/refresh',
},
})
}
export { apiClient }
推送通知完整流程
import { capacitor } from '@h-ai/capacitor'
export async function setupPush() {
if (!capacitor.isNative()) {
return
}
const reg = await capacitor.push.register()
if (!reg.success) {
return
}
await api.post('/push/register', {
token: reg.data.token,
platform: capacitor.getPlatform(),
})
const listenResult = await capacitor.push.listen({
onReceived: (n) => {
},
onActionPerformed: (n) => {
},
})
}
拍照上传
import { capacitor } from '@h-ai/capacitor'
async function captureAndUpload() {
const photo = await capacitor.camera.takePhoto({
source: 'camera',
resultType: 'base64',
quality: 80,
width: 1024,
})
if (!photo.success) {
return
}
await api.post('/files/upload', {
data: photo.data.data,
format: photo.data.format,
})
}
插件依赖
| 插件 | 类型 | 用于 |
|---|
@capacitor/core | peerDependency(必需) | 核心运行时 |
@aparajita/capacitor-secure-storage | 可选 peerDependency(原生 token 存储必需) | createCapacitorTokenStorage() |
@capacitor/preferences | peerDependency(必需) | capacitor.preferences.* 普通偏好数据 |
@capacitor/device | 可选 | getDeviceInfo() |
@capacitor/app | 可选 | getAppVersion() |
@capacitor/push-notifications | 可选 | registerPush() / listenPush() |
@capacitor/camera | 可选 | takePhoto() |
@capacitor/status-bar | 可选 | configureStatusBar() / show/hide |
可选插件未安装时,对应 API 调用会返回 err(动态 import 失败被 catch)。
相关 Skills
hai-api-client:HTTP 客户端(Token 管理依赖 capacitor 存储)
hai-iam:认证流程(登录获取 Token → 存储到 Capacitor)
hai-ui:移动端 UI 组件(SafeArea、BottomNav 等)