iOS

集成 IM UIKit

更新时间: 2026/08/12 17:57:27

网易云信 IM UIKit 是基于 网易云信即时通讯 SDK(简称 NIM SDK)V10 开发的一款 即时通讯 UI 组件库,包括聊天、会话列表、通讯录、群管理等组件。

IM UIKit 同时提供 Swift、Objective-C、SwiftUI 多套 UI 组件。SwiftUI 组件名称以 SwiftUI 结尾,支持通过 CocoaPods 在线依赖或源码依赖接入。

本文介绍如何快速跑通 IM UIKit(V10)的集成流程。

前提条件

在开始集成 IM UIKit 前,请确保您已完成了以下准备工作:

  • 已在 网易云信控制台 上,创建应用,并获取 App Key。
  • 注册网易云信 IM 账号,获取账号 ID(account_id)和授权(token)。
  • 已获取示例项目:
    • Swift&Objective-C 版本请前往 GitHubGitee 获取。
    • SwiftUI 版本请前往 GitHub获取。
  • 已准备如下开发环境和工具:
    • Swift&Objective-C 组件:iOS 13.0 及以上版本、Xcode 11.0 及以上版本。
    • SwiftUI 组件:iOS 16.0 及以上版本、Xcode 16.0 及以上版本。

注意事项

由于 IM UIKit 的初始化与登录是通过底层调用 NIM SDK 接口来实现的,因此重复调用 IM UIKit 和 NIM SDK 的初始化与登录接口会相互覆盖传入的信息(包括 推送配置信息)。

所以若用户同时集成 IM UIKit 和 NIM SDK,只需要调用一次初始化与登录接口即可。

实现流程

graph LR
按需导入组件 --> 初始化 --> 登录 --> 初始化路由 --> 页面搭建

步骤 1:按需导入组件

  1. 根据业务需要,在 Podfile 文件中,以添加依赖的形式添加相应的 IM UIKit 组件。

    例如,需要会话聊天功能,Swift&Objective-C 项目可添加 pod 'NEChatUIKit',SwiftUI 项目可添加 pod 'NEChatUIKitSwiftUI'。对应 Pod 会自动引入所需的数据层和基础组件。

    Swift
    Swift# Uncomment the next line to define a global platform for your project
    platform :ios, '13.0'
    
    # 请使用您的真实项目名称替换 your project name
    target 'your project name' do
    # Comment the next line if you don't want to use dynamic frameworks
    use_frameworks!
    
    # UI 组件
    pod 'NEChatUIKit', '10.9.20'               # 会话(聊天)组件
    pod 'NEContactUIKit', '10.9.20'            # 通讯录组件
    pod 'NEConversationUIKit', '10.9.20'       # 云端会话列表组件如果使用云端会话,则不需要依赖下面本地会话列表组件,与本地会话组件二者选其一
    pod 'NELocalConversationUIKit', '10.9.20'  # 本地会话列表组件,如果使用本地会话,则不需要依赖上面云端会话列表组件,与云端会话组件二者选其一
    pod 'NETeamUIKit', '10.9.20'               # 群相关设置组件
    
    # 扩展库-地理位置组件
    pod 'NEMapKit', '10.9.20'
    
    # 扩展库 - AI 划词搜索
    pod 'NEAISearchKit', '10.9.20'
    
    # 扩展库 - 呼叫组件
    pod 'NERtcSDK/RtcBasic'                   #  RTC 音视频基础组件
    pod 'NERtcSDK/Nenn'                       #  RTC 音视频神经网络组件(使用背景虚化功能需要集成)
    pod 'NERtcSDK/Segment'                    #  RTC 音视频背景分割组件(使用背景虚化功能需要集成)
    pod 'NERtcCallKit/NOS_Special', '4.3.0'
    pod 'NERtcCallUIKit/NOS_Special', '4.3.0'             # (源码地址:https://github.com/netease-kit/NEVideoCall-1to1/tree/main/NLiteAVDemo-iOS-ObjC/CallKit)
    
    # 可选 - 图片选择库
    pod 'ZLPhotoBrowser'
    end
    
    Objective-C
    Objective-C# Uncomment the next line to define a global platform for your project
    platform :ios, '13.0'
    
    # 请使用您的真实项目名称替换 your project name
    target 'your project name' do
    # Comment the next line if you don't want to use dynamic frameworks
    use_frameworks!
    
    # UI 组件
    pod 'NEChatUIKitOC', '10.9.20'               # 会话(聊天)组件
    pod 'NEContactUIKitOC', '10.9.20'            # 通讯录组件
    pod 'NEConversationUIKitOC', '10.9.20'       # 会话列表组件
    pod 'NETeamUIKitOC', '10.9.20'               # 群相关设置组件
    
    # 扩展库-地理位置组件
    pod 'NEMapKitOC', '10.9.20'
    
    # 扩展库 - AI 划词搜索
    pod 'NEAISearchKitOC', '10.9.20'
    
    # 扩展库 - 呼叫组件
    pod 'NERtcSDK/RtcBasic'                   #  RTC 音视频基础组件
    pod 'NERtcSDK/Nenn'                       #  RTC 音视频神经网络组件(使用背景虚化功能需要集成)
    pod 'NERtcSDK/Segment'                    #  RTC 音视频背景分割组件(使用背景虚化功能需要集成)
    pod 'NERtcCallKit/NOS_Special', '4.3.0'
    pod 'NERtcCallUIKit/NOS_Special', '4.3.0'             # (源码地址:https://github.com/netease-kit/NEVideoCall-1to1/tree/main/NLiteAVDemo-iOS-ObjC/CallKit)
    
    # 可选 - 图片选择库
    pod 'ZLPhotoBrowser'
    end
    
    SwiftUI
    ruby# Uncomment the next line to define a global platform for your project
    platform :ios, '16.0'
    
    # 请使用您的真实项目名称替换 your project name
    target 'your project name' do
    # Comment the next line if you don't want to use dynamic frameworks
    use_frameworks!
    
    # UI 组件
    pod 'NEChatUIKitSwiftUI', '10.9.30-beta'               # 会话(聊天)组件
    pod 'NEContactUIKitSwiftUI', '10.9.30-beta'            # 通讯录组件
    pod 'NEConversationUIKitSwiftUI', '10.9.30-beta'       # 会话列表组件
    pod 'NETeamUIKitSwiftUI', '10.9.30-beta'               # 群相关设置组件
    
    # 扩展库 - AI 划词搜索
    pod 'NEAISearchKitSwiftUI', '10.9.30-beta'
    
    # 扩展库 - 呼叫组件
    pod 'NERtcSDK/RtcBasic'                   #  RTC 音视频基础组件
    pod 'NERtcSDK/Nenn'                       #  RTC 音视频神经网络组件(使用背景虚化功能需要集成)
    pod 'NERtcSDK/Segment'                    #  RTC 音视频背景分割组件(使用背景虚化功能需要集成)
    pod 'NERtcCallKit/NOS_Special', '4.3.0'
    pod 'NERtcCallUIKit/NOS_Special', '4.3.0'             # (源码地址:https://github.com/netease-kit/NEVideoCall-1to1/tree/main/NLiteAVDemo-iOS-ObjC/CallKit)
    
    # 可选 - 图片选择库
    pod 'ZLPhotoBrowser'
    end
    

    默认引入最新版本的第三方库,若需要指定版本,请参考 组件导入

  2. 配置完 Podfile 文件后执行 pod install 命令导入组件。

    • 各 UI 组件相互独立,添加或删除均不影响项目编译。
    • 如果出现类似 版本不存在 的报错,可执行 pod update 命令,然后双击 .xcworkspace 文件,启动项目即可。
    • 暂不支持 bitcode。

步骤 2:初始化

  1. 在项目中引入需要的组件。

    示例代码

    Swift
    Swiftimport NECoreKit
    import NECoreIM2Kit
    import NEChatKit
    import NEChatUIKit
    ...
    
    Objective-C
    Objective-C#import <NEChatKitOC/Router.h>
    #import <NEChatKitOC/NECoreIM2KitOC.h>
    #import <NEChatUIKitOC/NEChatUIConstant.h>
    #import <NEChatUIKitOC/NETeamUserManager.h>
    ...
    
    SwiftUI
    swiftimport SwiftUI
    import NEChatKit
    import NIMSDK
    import NECommonUIKitSwiftUI
    import NEChatUIKitSwiftUI
    import NEConversationUIKitSwiftUI
    import NEContactUIKitSwiftUI
    import NETeamUIKitSwiftUI
    ...
    
  2. 在应用启动后,调用 setupIM2 方法进行初始化。

    NIMSDKOption 参数说明如下:

    NIMSDKOption 参数 是否必传 说明
    appKey 网易云信控制台获取到的 App Key。
    apnsCername APNs 推送证书名,如不需要实现离线推送可不配置。
    pkCername PushKit 推送证书名,如不需要实现离线推送可不配置。
    avoidNosAccelerationBuckets 不走 NOS 域名加速的桶名集合。
    v2 启用 V2 版本的 API。该字段自 V10.6.1 版本起废弃。若仍需要使用 V1 的登录接口,请设置 V2NIMSDKOption.useV1Login 字段。

    V2NIMSDKOption 参数说明如下:

    V2NIMSDKOption 参数 是否必传 说明
    useV1Login 是否使用旧的登录接口,默认 NO,不使用
    enableV2CloudConversation 是否使用 V2 云端会话,默认 NO,不使用

    SDK 默认使用本地会话,若需要使用云端会话功能,除了在组件导入时,引入云端会话外,还需要在初始化时,将 enableV2CloudConversation 设置为 YES。只有设置为 YES 后,才能正常使用云端会话服务。

    示例代码

    Swift/SwiftUI
    swift// init
    // 设置IM SDK的配置项,包括AppKey,推送配置和一些全局配置等
    let option = NIMSDKOption()
    option.appKey = "your app key"
    option.apnsCername = "网易云信控制台配置的 APNS 推送证书名称"
    option.pkCername = "网易云信控制台配置的 PushKit 推送证书名称"
    
    // 设置IM SDK V2的配置项,包括是否使用旧的登录接口和是否使用云端会话
    let v2Option = V2NIMSDKOption()
    v2Option.enableV2CloudConversation = false
    
    // 初始化IM UIKit,初始化Kit层和IM SDK,将配置信息透传给IM SDK。无需再次初始化IM SDK
    IMKitClient.instance.setupIM2(option, v2Option)
    
    Objective-C
    Objective-C// 设置IM SDK的配置项,包括AppKey,推送配置和一些全局配置等
    NIMSDKOption *option = [NIMSDKOption optionWithAppKey:AppKey];
    
    // 设置IM SDK V2的配置项,包括是否使用旧的登录接口和是否使用云端会话
    V2NIMSDKOption *v2Option = [[V2NIMSDKOption alloc] init];
    v2Option.enableV2CloudConversation = NO;
    
    // 初始化IM UIKit,初始化Kit层和IM SDK,将配置信息透传给IM SDK。无需再次初始化IM SDK
    [IMKitClient.instance setupIM2:option :v2Option];
    

更多初始化说明,请参考 初始化

步骤 3:登录

在完成初始化后,调用 login 方法登录 IM。

示例代码

Swift/SwiftUI
swiftIMKitClient.instance.login(account, token, nil) { error in
    if let err = error {
        print("IMKitClient login error : ", err)
    }else {
        //在登录成功回调中初始化路由以及配置各个模块首页
        /*
            weakSelf?.setupTabbar()
            */
    }
}
Objective-C
Objective-C[[IMKitClient instance] login:@"account" :@"token" :nil :^(NSError * _Nullable error) {
    if (error != nil) {
        NSLog(@"IMKitClient login error : %@", [error description]);
    } else {
        //在登录成功回调中初始化路由以及配置各个模块首页
        /*
        [weakSelf setupTabbar];
        */
    }
}];

调用登录的方法时,将示例代码中的 accounttoken 分别替换为您的网易云信账号 ID 和 Token。

步骤 4:初始化路由

如果未在登录成功回调中初始化路由,需要单独初始化路由,才能进行后续的界面搭建。在初始化路由时可同时初始化地图 Map,初始化后,您的应用即可实现地理位置消息功能。具体请参考 实现地理位置消息功能

示例代码

Swift
Swift func loadService() {
        // 注册路由
        // isFun: 是否使用通用版皮肤
        ChatKitClient.shared.setupInit(isFun: false)
        
        // 注册【个人信息】页面,用于实现单击头像后跳转至个人信息页面功能
        Router.shared.register(MeSettingRouter) { param in
            if let nav = param["nav"] as? UINavigationController {
                let me = PersonInfoViewController()
                nav.pushViewController(me, animated: true)
            }
        }
    }
Objective-C
Objective-C- (void)registerRouter {
    // 注册路由
    // isFun: 是否使用通用版皮肤
    [[ChatKitClient shared] setupInit:NO];

    // 注册【个人信息】页面,用于实现单击头像后跳转至个人信息页面功能
    [[Router shared] register:MeSettingRouter closure:^(NSDictionary *param) {
        id navParam = param[@"nav"];
        if (![navParam isKindOfClass:[UINavigationController class]]) {
            return;
        }
        UINavigationController *nav = (UINavigationController *)navParam;
        [nav pushViewController:[[PersonInfoViewController alloc] init] animated:YES];
    }];
}
SwiftUI
swift@MainActor
func setupSwiftUIModules(useFunSkin: Bool) {
    // 普通版皮肤使用 .normal,通用版皮肤使用 .fun。
    let chatStyle: ChatStyleMode = useFunSkin ? .fun : .normal
    let conversationStyle: ConversationStyleMode = useFunSkin ? .fun : .normal
    let contactStyle: ContactStyleMode = useFunSkin ? .fun : .normal
    let teamStyle: NETeamSwiftUIStyleMode = useFunSkin ? .fun : .normal

    // 注册 UIKit 字符串路由到 SwiftUI 类型化路由的兼容转换。
    let chatRouter = NEChatUIKitSwiftUIClient.shared.router
    NEChatUIKitSwiftUIClient.shared.setup(
        config: ChatSwiftUIConfig(styleMode: chatStyle),
        router: chatRouter,
        registerLegacyRoutes: true
    )
    NEChatUIKitSwiftUIClient.shared.installPushRoutePayloadBeforeSend()

    NEConversationUIKitSwiftUIClient.shared.setup(
        config: ConversationSwiftUIConfig(styleMode: conversationStyle)
    )
    NEContactUIKitSwiftUIClient.shared.setup(
        config: ContactSwiftUIConfig(styleMode: contactStyle)
    )

    NETeamUIKitSwiftUIClient.shared.setup()
    NETeamSwiftUIConfigCenter.shared.update(
        NETeamSwiftUIConfig(styleMode: teamStyle)
    )
}
  • SwiftUI 的 registerLegacyRoutes: true 只负责将 Router.shared 发出的 UIKit 字符串路由转换为 NEChatSwiftUIRoute。宿主应用仍需监听 NEChatUIKitSwiftUIClient.shared.router.onRoute(或 onRouteRequest),并通过 NavigationStacknavigationDestination 等 SwiftUI 导航 API 展示目标页面。
  • 普通版皮肤对应 .normal,通用版皮肤对应 .fun。请在创建各模块页面前完成配置;运行时切换皮肤时,需要同步更新 Chat、Conversation、Contact 和 Team 四个模块的配置。

SwiftUI 路由宿主的最简实现如下:

swift@MainActor
struct ChatRouteHost: View {
    @State private var path = [NEChatSwiftUIRoute]()
    private let router = NEChatUIKitSwiftUIClient.shared.router

    var body: some View {
        NavigationStack(path: $path) {
            Text("首页")
                .navigationDestination(for: NEChatSwiftUIRoute.self) { route in
                    switch route {
                    case let .p2pChat(context), let .teamChat(context):
                        let config = ChatSwiftUIConfigCenter.shared.current()
                        ChatView(viewModel: ChatSessionViewModel(
                            context: context,
                            config: config
                        ))
                    default:
                        EmptyView()
                    }
                }
        }
        .onAppear {
            router.onRouteRequest = { request in
                Task { @MainActor in
                    path.append(request.route)
                    router.complete(request.id)
                }
            }
        }
        .onDisappear {
            router.onRouteRequest = nil
        }
    }
}

若需要注册【个人信息】页面,实现单击头像后跳转至个人设置页面的功能,首先需要在 Xcode 中拖入相关的源码文件至您的工程。相关的源码文件包括:

  • Swift:
    • app 下的 Mine 文件
    • app 下 Assets 中的 Mine 文件
  • Objective-C:
    • app 下的 Mine 文件
    • app 下 Assets 中的 Mine 文件
  • SwiftUI:

步骤 5:界面搭建

搭建基础版 UI 界面

以搭建单聊群聊页面为例,示例代码如下(更多详情请参考下文的 界面集成详情):

示例代码

  • Swift 示例:

    Swiftfunc chatExample(){
        // 单聊
        let p2pChatVC = P2PChatViewController(conversationId: "会话 ID", anchor: nil)
    
        // 群聊
        let groupVC = TeamChatViewController(conversationId: "会话 ID", anchor: nil)
    }
    
  • Objective-C 示例:

    Objective-C- (void)chatExample {
        // 单聊
        P2PChatViewController *p2pChatVC = [[P2PChatViewController alloc] initWithConversationId:@"会话 ID" anchor:nil];
    
        // 群聊
        TeamChatViewController *groupVC = [[TeamChatViewController alloc] initWithConversationId:@"会话 ID" anchor:nil];
    }
    
  • SwiftUI 示例:

    swift@MainActor
    func makeNormalChatView(
        conversationId: String,
        isTeam: Bool,
        anchor: V2NIMMessage? = nil
    ) -> some View {
        let context = ChatSessionContext(
            kind: isTeam ? .team : .p2p,
            conversationId: conversationId,
            anchorMessage: anchor
        )
        var config = ChatSwiftUIConfigCenter.shared.current()
        config.styleMode = .normal
        return ChatView(viewModel: ChatSessionViewModel(
            context: context,
            config: config
        ))
    }
    

参数说明

参数 说明
conversationId 会话 ID,拼接方式如下:
发送者用户账号(accountId)| 会话类型(V2NIMConversationType)| 聊天对象账号(accountId)或群组 ID
isTeam 是否为群聊。true 表示群聊,false 表示单聊。仅用于上述 SwiftUI 示例。
anchor 锚点消息。SwiftUI 中对应 ChatSessionContext.anchorMessage

效果参考

搭建通用版 UI 界面

以搭建单聊群聊页面为例,示例代码如下:

示例代码

  • Swift 示例:

    Swiftfunc chatExample(){
        // 单聊
        let p2pChatVC = FunP2PChatViewController(conversationId: "会话 ID", anchor: nil)
    
        // 群聊
        let groupVC = FunTeamChatViewController(conversationId: "会话 ID", anchor: nil)
    }
    
  • Objective-C 示例:

    Objective-C- (void)chatExample {
        // 单聊
        FunP2PChatViewController *p2pChatVC = [[FunP2PChatViewController alloc] initWithConversationId:@"会话 ID" anchor:nil];
    
        // 群聊
        FunTeamChatViewController *groupVC = [[FunTeamChatViewController alloc] initWithConversationId:@"会话 ID" anchor:nil];
    }
    
  • SwiftUI 示例:

    swift@MainActor
    func makeFunChatView(
        conversationId: String,
        isTeam: Bool,
        anchor: V2NIMMessage? = nil
    ) -> some View {
        let context = ChatSessionContext(
            kind: isTeam ? .team : .p2p,
            conversationId: conversationId,
            anchorMessage: anchor
        )
        var config = ChatSwiftUIConfigCenter.shared.current()
        config.styleMode = .fun
        return ChatView(viewModel: ChatSessionViewModel(
            context: context,
            config: config
        ))
    }
    

参数说明

参数 说明
conversationId 会话 ID,拼接方式如下:
发送者用户账号(accountId)| 会话类型(V2NIMConversationType)| 聊天对象账号(accountId)或群组 ID
isTeam 是否为群聊。true 表示群聊,false 表示单聊。仅用于上述 SwiftUI 示例。
anchor 锚点消息。SwiftUI 中对应 ChatSessionContext.anchorMessage

效果参考

后续步骤

为保障通信安全,如果您在调试环境中的使用的是网易云信控制台生成的测试用 IM 账号和 token,请确保在后续的正式生产环境中,将其替换为通过 IM 服务端 API 生成的正式 IM 账号(account_id)和 token。

相关参考

界面集成详情

IM UIKit 中提供的常用业务场景界面及相关集成说明如下:

页面 所属组件 描述
ConversationController NEConversationUIKit 云端会话列表页面(创建或者跳转到该界面需要传入参数,请参考 集成会话列表界面)。
修改界面 UI 请参考 自定义会话列表 UI
LocalConversationController NELocalConversationUIKit 本地会话列表页面(创建或者跳转到该界面需要传入参数,请参考 集成会话列表界面)。
修改界面 UI 请参考 自定义会话列表 UI
ContactViewController NEContactUIKit 通讯录页面(创建或者跳转到该界面需要传入参数,请参考 集成通讯录界面)。
修改界面 UI 请参考 自定义通讯录 UI
P2PChatViewController
TeamChatViewController
NEChatUIKit 单聊、群聊会话页面(创建或者跳转到该界面需要传入参数,请参考 集成会话消息界面)。
修改界面 UI 请参考 自定义会话消息 UI
TeamSettingViewController NETeamKit 群组设置页面。
NormalConversationListView
FunConversationListView
NEConversationUIKitSwiftUI SwiftUI 会话列表页面,分别对应普通版和通用版皮肤。
NormalContactListView
FunContactListView
NEContactUIKitSwiftUI SwiftUI 通讯录页面,分别对应普通版和通用版皮肤。
ChatView NEChatUIKitSwiftUI SwiftUI 单聊、群聊页面。通过 ChatSessionContext.kind 指定 .p2p.team,通过 conversationId 指定会话,通过 ChatSwiftUIConfig.styleMode 设置皮肤。
NormalTeamSettingView
FunTeamSettingView
NETeamUIKitSwiftUI SwiftUI 群组设置页面,分别对应普通版和通用版皮肤。

音视频通话

集成会话界面后,如果需要在会话消息界面实现音视频通话功能,请参考 实现音视频通话功能

常见问题

此文档是否对你有帮助?
有帮助
去反馈
  • 前提条件
  • 注意事项
  • 实现流程
  • 步骤 1:按需导入组件
  • 步骤 2:初始化
  • 步骤 3:登录
  • 步骤 4:初始化路由
  • 步骤 5:界面搭建
  • 后续步骤
  • 相关参考
  • 界面集成详情
  • 音视频通话
  • 常见问题