跳转到正文

uni-app 接入 ​

需要查某个方法的参数、返回值或回调时,查看 uni-app 方法参考。

uni-app SDK 以 uni_modules/popo-im 模块接入 Vue 2 或 Vue 3 宿主,提供会话、通讯录及完整聊天页面。宿主保留账号系统、TabBar、权限、签名与原生能力配置。

环境与模块目录 ​

使用 HBuilderX 4.51 或更新版本,面向 Android App 与 iOS App;文件选择原生模块要求 iOS 15+。Vue 2、Vue 3 使用同一公开入口。H5、小程序、nvue 和 HarmonyOS 不应直接视为与两个 App 平台具有相同的支持范围;网站优先接入独立 Web SDK。

将完整模块加入宿主,保留 utssdk、共享媒体模块、页面和资源:

text
your-app/
├── App.vue
├── pages.json
└── uni_modules/popo-im/
    ├── js_sdk/
    ├── pages/
    ├── pages_init.json
    ├── static/
    ├── utssdk/
    ├── browser-video/
    └── browser-qr/

安装模块自身声明的依赖:

sh
cd your-app/uni_modules/popo-im
npm ci --omit=dev --ignore-scripts

将模块 pages_init.json 中的页面配置完整合并到宿主 pages.json,保留每页的 style;HBuilderX 导入时如果已完成合并,不要重复注册。不要只注册两个根页而遗漏聊天、媒体或举报等内部页面。

在宿主 App.vue 导入一次样式:

vue
<style>
@import '@/uni_modules/popo-im/static/popo-ui.css';
</style>

原生文件选择器在 utssdk 中。首次安装或原生模块更新后应重新构建 App 或自定义基座,单独更新 WGT 无法新增原生代码。

初始化与 AuthProvider ​

js
import { PopoIM } from '@/uni_modules/popo-im/js_sdk/index.js'

PopoIM.init({
  serverUrl: 'https://example.com',
  webSocketUrl: 'wss://example.com/ws',
  authProvider: async () => {
    // hostRequest 是宿主自己的网络层,负责宿主登录凭证和响应校验。
    const data = await hostRequest('/api/im-auth', { method: 'POST' })
    return {
      user: {
        userId: data.user.user_id,
        username: data.user.username || null,
        nickname: data.user.nickname,
        avatar: data.user.avatar || '',
        signature: data.user.signature || null
      },
      token: data.token,
      expireAt: data.expire_at
    }
  }
})

hostRequest 需先校验 HTTP 状态及 code/msg/data 返回格式,再返回 data;/api/im-auth 由宿主实现,见认证与 Token。Provider 不持有 Secret,也不传宿主 Cookie 给 SDK。webSocketUrl 可省略,默认派生同域 /ws。

两个 UI 入口 ​

宿主可将以下页面设为两个 Tab 根页,顺序和位置自行决定:

json
{
  "tabBar": {
    "list": [
      {
        "pagePath": "uni_modules/popo-im/pages/conversation/index",
        "text": "消息"
      },
      {
        "pagePath": "uni_modules/popo-im/pages/contact/index",
        "text": "通讯录"
      }
    ]
  }
}

从宿主导航切换这两个根页可使用 uni.switchTab;聊天及其他内部页面交给 SDK。宿主不要自行拼接聊天 URL 或使用 uni.reLaunch 处理 SDK 退出。

需要将两个根页嵌入自有持久工作台时,使用公开的 setRootNavigationHandler 和 markRootVisible 协调宿主容器,避免引用内部路由。

登录、退出与切换账号 ​

js
// verifiedUser 来自宿主已确认的当前账号;缓存预热可省略。
await PopoIM.restoreCachedSession(verifiedUser)
await PopoIM.login()

// 宿主完成账号切换,Provider 已返回新用户后:
await PopoIM.login()

// 宿主明确退出时:
PopoIM.logout(true)

初始化只校验并登记配置。login() 在首次同步完成后成功;缓存恢复不获取 Token、不代表就绪。显式登录可切号,自动续期只允许同一身份。页面卸载不应注销进程级 SDK,仅解除本页监听。

将真实 App 生命周期转发一次,放在宿主 App.vue,不要在每个聊天页重复调用:

js
export default {
  onShow() {
    PopoIM.onAppForeground()
  },
  onHide() {
    PopoIM.onAppBackground()
  }
}

网络监听从已断网恢复为联网时再调用 PopoIM.onNetworkAvailable();初次收到“在线”回调不应伪造一次恢复事件。SDK 管理重连与消息补齐,宿主无需增加轮询。

常用公开操作 ​

js
await PopoIM.openConversation({ type: 'friend', id: 'linzhou' })
await PopoIM.openConversation({ type: 'group', id: '6655312956' })

// messageId 为服务端返回的稳定十进制字符串。
await PopoIM.openConversation({
  type: 'friend', id: 'linzhou', messageId
})

const stopUnread = PopoIM.addUnreadListener(count => {
  renderUnread(count.conversation, count.contact)
})

await PopoIM.updateCurrentUser(updatedUser)
const session = PopoIM.getSessionState()
PopoIM.setUiTheme('light') // 'light' | 'dark'

// 宿主监听所属生命周期结束时:
stopUnread()

renderUnread 为宿主角标逻辑,计数是绝对值,100 展示为 99+。getSessionState() 只提供身份、会话状态和前台摘要,不含 Token。昵称、头像等先在宿主保存成功并更新 Provider 来源,再调用 updateCurrentUser。

媒体、主题与通话 ​

在宿主 manifest.json 根据需要配置 Barcode、Camera、Invocation、Record、VideoPlayer 模块。语音消息在 App 原生侧使用 M4A/AAC,需声明 Android 麦克风权限与 iOS NSMicrophoneUsageDescription;拍摄、保存等能力另外按平台配置用途说明。

深浅色由宿主解析后调用 setUiTheme。App 的首帧背景与底部手势区也由宿主管理:APP-PLUS 下的全局 page 背景需允许 SDK 原生画布显示,避免全局浅色背景覆盖夜间页面。保留模块页面自带的样式和安全区配置,不逐页覆盖颜色。

一对一通话中,SDK 管理信令与通话状态,宿主管理腾讯 TRTC 原生插件、设备权限、原生视频视图和通话展示页。接线完成后再通过 setCallPresentationCapabilities({ audio, video }) 声明实际可展示能力;仅调用此方法不会自动安装媒体插件,也不能代替服务端能力开关。普通文字、语音消息和视频消息不要求宿主实现通话页。

本模块没有 U-Push、UniPush 或离线系统消息通知接入入口,不应直接照搬其他平台的推送注册方式。

接入检查 ​

在 Android 和 iOS 的实际 App 包中检查两个根页、聊天返回、未读更新、后台恢复、账号切换及深浅色切换。媒体需要验证录音上传播放、系统文件选择、选择取消和竖屏视频;H5 预览与资源编译通过不能替代 App 真机验收。