集成 IM UIKit
更新时间: 2024/10/31 17:50:12
网易云信 IM UIKit 是基于鸿蒙版本 网易云信 IM SDK(简称 NIM SDK) 开发的一款 即时通讯 UI 组件库,功能涵盖了聊天、会话、群管理。本文介绍鸿蒙项目如何按照以下流程集成 IM UIKit。
graph LR
classDef default fill:#337EFF,stroke:#337EFF,stroke-width:0px,color:#FFFFFF;
导入组件 --> 添加权限 --> 初始化 --> 登录 --> 搭建界面
准备工作
在开始集成 IM UIKit 前,请确保您已完成以下操作:
-
注册 IM 账号,获取账号 ID(
account_id
)和凭证(token
)。 -
访问 GitHub 网易云信 IM UIKit 鸿蒙源码项目。
-
准备如下开发环境:
环境 版本要求 DevEco Studio NEXT Beta1(Build Version: 5.0.3.810) 及以上 OpenHarmony SDK API API Version 12 及以上
注意事项
由于 IM UIKit 的初始化与登录是通过底层调用 NIM SDK 接口实现的,因此重复调用 IM UIKit 和 NIM SDK 的初始化与登录接口会相互覆盖传入的信息(包括 推送配置信息)。
所以,若您同时集成 IM UIKit 和 NIM SDK,只需要调用一次 初始化 与 登录 接口即可。
第一步:按需导入组件
根据业务需要,将 源码模块 复制到您的工程目录中,并在您的主工程的 oh-package.json5
中,以添加依赖的形式添加相应的 IM UIKit 组件。
源码中组件目录如下:
目录 | 组件 | 说明 | 是否必须依赖 |
---|---|---|---|
corekit |
底层架构组件 | 底层框架 | 是 |
common |
通用 UI 组件 | 公用 UI 库 | 是 |
chatkit |
业务接口组件 | 业务逻辑层,依赖 NIM SDK 提供各个业务数据接口 | 是 |
chatkit_ui |
聊天 UI 组件 | 聊天模块,包括单聊和群聊页面,以及消息发送、消息接受和消息 UI 等 | 否 |
contactkit_ui |
通讯录 UI 组件 | 通讯录、黑名单、系统通知组件 | 否 |
conversationkit_ui |
会话 UI 组件 | 会话列表组件 | 否 |
teamkit_ui |
群管理 UI 组件 | 群管理组件,群聊设置、群管理等 | 否 |
imkit_sample |
组件 Demo | Demo 源码,组件初始化、登录和设置相关功能 | 否 |
libs |
SDK 依赖 | NIM SDK har 包,可以替换更新 NIM SDK | 是 |
例如,如果您的业务中需要会话列表、聊天和通讯录功能,那么您需要依赖所有组件,具体可参考源码 imkit_sample/oh-package.json5 文件,如下所示:
JSON "dependencies": {
"@nimkit/conversationkit_ui": "file:../conversationkit_ui",
"@nimkit/contactkit_ui": "file:../contactkit_ui",
"@nimkit/teamkit_ui": "file:../teamkit_ui",
"@nimkit/chatkit": "file:../chatkit",
"@nimkit/chatkit_ui": "file:../chatkit_ui",
"@nimkit/common": "file:../common",
"@nimkit/corekit": "file:../corekit",
"@nimsdk/conversation": "file:../libs/conversation.har",
"@nimsdk/conversationgroup": "file:../libs/conversationgroup.har",
"@nimsdk/message": "file:../libs/message.har",
"@nimsdk/team": "file:../libs/team.har",
"@nimsdk/user": "file:../libs/user.har",
"@nimsdk/friend": "file:../libs/friend.har",
"@nimsdk/nim": "file:../libs/nim.har",
"@nimsdk/base": "file:../libs/base.har"
}
第二步:添加权限
在即时通讯应用场景中,在鸿蒙系统中所需的权限申请相机和麦克风权限,其他文件和图片权限官方推荐不需要单独申请。具体请参考 chatkit_ui
目录中 /src/main/module.json5,您需要添加所需权限的文件配置如下所示:
JSON"requestPermissions": [
{
"name": "ohos.permission.CAMERA",
"reason": "$string:chat_permission_camera_desc",
"usedScene": {
"abilities": [
"FormAbility"
],
"when": "always"
}
},
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:chat_permission_micro_phone_desc",
"usedScene": {
"abilities": [
"FormAbility"
],
"when": "always"
}
}
]
第三步:初始化
在应用启动时候,注册和初始化 NIM SDK,然后使用初始化后的 NIM 实例,再初始化 UI 组件。初始化需要使用到您在 准备工作 阶段获取的网易云信应用 App Key。
具体请参考源码工程 NimRepository.ets 文件。您可以在 UIAbility
中进行初始化,示例代码如下:
TypeScriptexport default class DefaultAbility extends UIAbility {
//NIM 示例,全局使用可以放在全局的类中,参考源码中'NimRepository'类
private _nim: NIMInterface | undefined
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 初始化参数
let initializeOptions: NIMInitializeOptions = {
appkey: '',// 网易云信应用密钥(App Key)
logLevel: LogLevel.Debug, //日志级别配置
isOpenConsoleLog: true // 打开后可以将 nimsdk 的日志输出到控制台
// ...其他属性
};
// 服务参数
let serviceOptions: NIMServiceOptions = {
loginServiceConfig: {
lbsUrls: ['https://lbs.netease.im/lbs/webconf.jsp'],
linkUrl: 'weblink.netease.im:443'
},
pushServiceConfig: {
harmonyCertificateName: '' // 推送证书配置,参考 NIM SDK 推送配置
}
}
//初始化 NIM SDK
NIMSdk.registerCustomServices(V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_TEAM,
(core, serviceName, serviceConfig) => new V2NIMTeamServiceImpl(core, serviceName, serviceConfig))
NIMSdk.registerCustomServices(V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_CLIENT_ANTISPAM_UTIL,
(core, serviceName, serviceConfig) => new V2NIMClientAntispamUtil(core, serviceName, serviceConfig));
NIMSdk.registerCustomServices(V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_CONVERSATION,
(core, serviceName, serviceConfig) => new V2NIMConversationServiceImpl(core, serviceName, serviceConfig));
NIMSdk.registerCustomServices(V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_CONVERSATION_GROUP,
(core, serviceName, serviceConfig) => new V2NIMConversationGroupServiceImpl(core, serviceName, serviceConfig));
NIMSdk.registerCustomServices(V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_MESSAGE,
(core, serviceName, serviceConfig) => new V2NIMMessageServiceImpl(core, serviceName, serviceConfig));
NIMSdk.registerCustomServices(V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_USER,
(core, serviceName, serviceConfig) => new V2NIMUserServiceImpl(core, serviceName, serviceConfig));
NIMSdk.registerCustomServices(V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_FRIEND,
(core, serviceName, serviceConfig) => new V2NIMFriendServiceImpl(core, serviceName, serviceConfig));
this._nim = NIMSdk.newInstance(this._context, initializeOptions, serviceOptions)
// 始化 NIM SDK 之后,您需要初始化 UI 组件(`ChatKitClient.init()`)才能正常使用 UI 组件。
ChatKitClient.init(this._nim, initializeOptions.appkey)
}
}
第四步:登录
调用登录的方法时,将如下示例代码中的 accountId
和 token
分别替换为您在 准备工作 阶段获取的账号 ID (即 accountId
)和 Token。
TypeScriptasync login(accountId: string, token: string) {
try {
await this._nim.loginService.login(accountId, token);
promptAction.showToast({
message: "登录成功",
alignment: Alignment.Center
})
} catch (error) {
console.log('----------- 登录失败 -----------', error)
AlertDialog.show(
{
title: '登录失败',
message: '登录失败',
autoCancel: true,
alignment: DialogAlignment.Bottom,
offset: { dx: 0, dy: -20 },
gridCount: 3,
confirm: {
value: 'OK',
action: () => {
console.info('Button-clicking callback')
}
},
cancel: () => {
console.info('Closed callbacks')
}
}
)
}
}
第五步:搭建 UI 界面
网易云信 IM UIKit 提供通用的 UI 组件库。
IM UIKit 为鸿蒙项目提供的常用业务场景界面及相关详细集成说明如下:
界面 | 所属组件 | 说明 |
---|---|---|
ConversationPage |
conversationkit_ui |
会话列表界面 |
ContactPage |
contactkit_ui |
通讯录界面 |
ChatP2PPage |
chatkit_ui |
单聊会话界面 |
ChatTeamPage |
chatkit_ui |
群聊会话界面 |
以搭建 Demo 中 会话列表、通讯录、我的 界面为例,在您应用中创建新的 ETS(Entry Table Source)类,声明为界面。示例代码如下:
TypeScript// tab 数据结构
@ObservedV2
class TabBarItem {
title: ResourceStr = "";
targetIndex: number = 0;
@Trace showRedPoint: boolean = false;
normalIcon: Resource;
selectedIcon: Resource;
constructor(title: ResourceStr, targetIndex: number, normalIcon: Resource, selectedIcon: Resource,
showRedPoint: boolean = false) {
this.title = title;
this.targetIndex = targetIndex;
this.showRedPoint = showRedPoint;
this.normalIcon = normalIcon;
this.selectedIcon = selectedIcon;
}
}
// 界面
@Entry
@ComponentV2
struct TabIndex {
//导航
pathStack: NavPathStack = new NavPathStack()
@Local currentIndex: number = 0;
// 创建三个界面
@Local tabs: Array<TabBarItem> = [
new TabBarItem($r('app.string.tab_conversation'), 0, $r('app.media.tab_conversation'),
$r('app.media.tab_conversation_light')),
new TabBarItem($r('app.string.tab_contact'), 1, $r('app.media.tab_contact'), $r('app.media.tab_contact_light')),
new TabBarItem($r('app.string.tab_mine'), 2, $r('app.media.tab_mine'), $r('app.media.tab_mine_light'))
];
loadUnreadApplication = async () => {
try {
const unreadCount = await ContactRepo.getAddApplicationUnreadCount()
this.tabs[1].showRedPoint = unreadCount > 0
} catch (err) {
console.log(err)
}
}
onUnreadApplicationChange = (unreadCountString?: string) => {
this.tabs[1].showRedPoint = unreadCountString !== undefined
}
//未读消息回调
onUreadMessageChange = (unreadCount?: number) => {
this.tabs[0].showRedPoint = (unreadCount ?? 0) > 0
}
//获取会话列表未读数
loadUnreadMessageCount = () => {
const unreadCount = ConversationRepo.getTotalUnreadCount()
if (unreadCount) {
this.tabs[0].showRedPoint = unreadCount > 0
}
}
async aboutToAppear(): Promise<void> {
ChatKitClient.nim.friendService?.on("onFriendAddApplication", async (application: V2NIMFriendAddApplication) => {
await this.loadUnreadApplication()
})
try {
await this.loadUnreadApplication()
} catch (err) {
console.log(err)
}
this.loadUnreadMessageCount()
}
@Builder
TabBarBuilder(item: TabBarItem) {
Stack() {
Column() {
Image(this.currentIndex === item.targetIndex ? item.selectedIcon : item.normalIcon)
.size({ width: 28, height: 28 })
.margin({ top: 8 })
Text(item.title)
.fontColor(this.currentIndex === item.targetIndex ? '#337EFF' : '#999999')
.margin({ top: 4 })
}
.justifyContent(FlexAlign.Center)
if (item.showRedPoint) {
Column()
.width(6)
.height(6)
.borderRadius(3)
.backgroundColor('#F24957')
.margin({
top: 7
})
}
}
.alignContent(Alignment.TopEnd)
}
// 界面构建
build() {
Navigation(this.pathStack) {
Tabs({ barPosition: BarPosition.End, index: 0 }) {
ForEach(this.tabs, (item: TabBarItem) => {
TabContent() {
if (item.targetIndex == 0) {
// 创建会话列表界面
ConversationPage({
pathStack: this.pathStack,
onUreadMessageChange: this.onUreadMessageChange
})
} else if (item.targetIndex == 1) {
// 创建通讯录界面
ContactPage({
pathStack: this.pathStack,
onUnreadApplicationChange: this.onUnreadApplicationChange
})
} else if (item.targetIndex == 2) {
// 创建我的界面
MinePage({
pathStack: this.pathStack
})
}
}
.tabBar(this.TabBarBuilder(item))
})
}
.barHeight(60)
.backgroundColor("#F6F8FA")
.barPosition(BarPosition.End)
.onChange((index: number) => {
this.currentIndex = index
})
}
.backgroundColor(Color.Transparent)
.mode(NavigationMode.Auto)
.hideTitleBar(true)
}
}
下一步
为保障通信安全,如果您在调试环境中的使用的是网易云信控制台生成的测试用 IM 账号 和 token
,请确保在后续的正式生产环境中,将其替换为通过 IM 服务端 API 生成的正式 IM 账号(accout_id
)和 token
。