IM 登录最佳实践

更新时间: 2025/09/05 15:02:07

登录对于 IM 产品来说至关重要,是后续业务顺利进行的前提条件。开发者集成 NIM SDK 的各项能力时,如果未能正确使用登录接口或处理登录状态,将引发不必要的问题,影响开发进度。本文详细介绍如何以最佳方式实现 IM 登录功能。

注意事项

准备工作

根据本文操作前,请确保您已经完成了以下设置:

  • 已在 网易云信控制台 上,创建应用,获取 App Key。

  • 集成 SDK

  • 已通过服务端 注册 IM 账号,获取 IM 账号和对应的静态 token

    如果仅需要测试和调试,您可通过控制台注册 IM 测试账号。测试账号及对应的静态 token 仅适用于调试环境,线上生产环境必须将测试账号及其 token 替换为云信服务端生成的正式 account_idtoken

Demo 体验

您可以参考 登录 Demo 体验完整登录流程。

登录流程

常见的登录流程一般分为三个部分,首次登录、自动登录以及登录状态处理。

首次登录

用户首次打开应用进行登录时,一般需要用户输入账号密码,进行用户自身业务系统的登录,成功后再使用云信返回的 IM 账号和 token 进行 IM 登录。

首次登录流程:

graph LR
    A[应用登录界面] --> B[应用业务系统登录]
    B -->|成功| C[IM 账号登录]
    B -->|失败| D[提示登录错误]
    C -->|成功| E[保存 IM 账号信息]
    C -->|失败| D
    D --> A
    
    %% 样式定义
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px;
    classDef success fill:#dfd,stroke:#333;
    classDef error fill:#fdd,stroke:#333;
    
    class E success;
    class D error;

接口调用:

  1. 调用 login 方法手动登录 IM。

在登录时 关闭离线模式

  1. 调用后处理逻辑:

    • 如果登录成功,保存 IM 账号和 token 到本地,便于下次应用启动时使用。
    • 如果登录失败,提示用户登录失败。

示例代码:

安卓
JavaV2NIMLoginOption option = new V2NIMLoginOption();
//关闭离线模式
option.setOfflineMode(false);

IMKitClient.login(
        account,
        token,
        option,
        new FetchCallback<Void>() {
            @Override
            public void onError(int errorCode, @NonNull String errorMsg) {
                //登录失败
                Toast.makeText(LoginActivity.this, R.string.tip_login_fail, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onSuccess(@Nullable Void data) {
                //保存accid、token,用于下次自动登录。
                Preferences.saveUserAccount(accid);
                Preferences.saveUserToken(token);
                // TODO: 登录成功跳转到主页面
            }
        }
);
iOS
Objective-Clet loginOption = V2NIMLoginOption()
        loginOption.offlineMode = false;
        IMKitClient.instance.login("ceshi3", "123456", loginOption) { [weak self] error in
          if let err = error {
            //登录失败
          } else {
            //登录成功保存账号密码
          }
        }

自动登录

用户登录成功后,再次打开应用,一般无需用户输入账号密码,而是程序内部获取上次登录的 IM 的账号和 token,通过离线方式登录 IM,此次登录会优先打开本地数据库,即使无网络的情况下也可以正常访问本地数据。

自动登录流程:

graph LR
    A[应用启动] --> B[自动登录]
    B -->|成功| C[读取上次登录信息] --> D[离线模式登录 IM] --> E[登录成功进入主界面]
    B -->|失败| F[打开登录页面使用手动登录] --> G[用户输入账号和 token] --> H[验证登录] --> E[登录成功进入主界面]
    H -->|失败| F[打开登录页面使用手动登录]

    %% 样式定义
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px;
    classDef success fill:#dfd,stroke:#333;
    classDef error fill:#fdd,stroke:#333;
    
    class D,E success;
    class F error;

接口调用:

  1. 获取上次登录的 IM 账号和 token

  2. 调用 login 方法登录 IM。

在登录时 开启离线模式

  1. 开启离线模式后,登录会统一走失败回调,当状态码为 191008 时表示进入离线模式,可以进入主页面。

示例代码:

安卓
JavaV2NIMLoginOption option = new V2NIMLoginOption();
//本次登录采用离线登录,无网络下也可以登录成功,后面 SDK 内部会自动重连
option.setOfflineMode(true);
IMKitClient.login(
        account,
        token,
        option,
        new FetchCallback<Void>() {
            @Override
            public void onError(int errorCode, @NonNull String errorMsg) {
                Log.e(TAG, "login  onFailure:" + errorCode + "," + errorMsg);
                if (191008 == errorCode) {
                    //进入离线模式,数据已经打开,跳转到主页面
                } else {
                    //自动登录失败,清理登录缓存信息,返回登录页面
                    Preferences.saveUserAccount("");
                    Preferences.saveUserToken("");
                }
            }

            @Override
            public void onSuccess(@Nullable Void data) {
                Log.e(TAG, "login  onSuccess");
                // 登录成功跳转到主页面
            }
        }
);
iOS
Objective-Clet loginOption = V2NIMLoginOption()
        loginOption.offlineMode = true;
        IMKitClient.instance.login("ceshi3", "123456", loginOption) { error in
          if let err = error {
              if (err.code == 191008) {
                  //进入离线模式,数据已经打开,跳转到主页面
              } else {
                  //自动登录失败,清理登录缓存信息,返回登录页面
              }
          } else {
              // 登录成功跳转到主页面
          }
        }

登录状态处理

在 IM 初始接口调用之后,可以在应用的主页面注册 IM 的登录回调,处理一些业务逻辑,如 UI 层提示用户当前连接状态、被踢、多端登录等。

登录状态处理流程:

graph LR
    A[应用主页面启动] --> B[注册登录状态回调]
    B --> C[收到登录状态事件] --> D[UI 提示用户]
    B --> E[收到被踢事件] --> F[打开登录页面使用手动登录]
    B --> G[收到登录失败事件] --> F[打开登录页面使用手动登录]

    %% 样式定义
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px;
    classDef success fill:#dfd,stroke:#333;
    classDef error fill:#fdd,stroke:#333;
    
    class D success;
    class F error;

接口调用:

  1. 进入应用主页面。

  2. 调用 addLoginListener 添加登录状态监听。

  3. 收到被踢、登录失败等事件后,清理当前登录信息,并返回登录页面。

示例代码:

安卓
JavaIMKitClient.addLoginListener(
        new V2NIMLoginListener() {
            @Override
            public void onLoginStatus(V2NIMLoginStatus status) {
                switch (status) {
                    case V2NIM_LOGIN_STATUS_LOGOUT:
                        //用户登出,清理登录缓存信息返回登录页面
                        Preferences.saveUserAccount("");
                        Preferences.saveUserToken("");
                        break;
                    case V2NIM_LOGIN_STATUS_UNLOGIN:
                        tvLoginStatus.setText("未登录");
                        break;
                    case V2NIM_LOGIN_STATUS_LOGINING:
                        tvLoginStatus.setText("登录中");
                        break;
                    case V2NIM_LOGIN_STATUS_LOGINED:
                        tvLoginStatus.setText("登录成功");
                        break;
                }
                Log.e(TAG, "loginListener onLoginStatus:" + status.toString());
            }

            @Override
            public void onLoginFailed(V2NIMError error) {
                //登录失败,清理登录缓存信息,返回登录页面
                Preferences.saveUserAccount("");
                Preferences.saveUserToken("");
            }

            @Override
            public void onKickedOffline(V2NIMKickedOfflineDetail detail) {
                //用户被踢,清理登录缓存信息返回登录页面
                Preferences.saveUserAccount("");
                Preferences.saveUserToken("");
            }

            @Override
            public void onLoginClientChanged(
                    V2NIMLoginClientChange change, List<V2NIMLoginClient> clients) {
            }
        });
iOS
Objective-Cpublic func onLoginFailed(_ error: V2NIMError) {
    //登录失败,清理登录缓存信息,返回登录页面
}

public func onKickedOffline(_ detail: V2NIMKickedOfflineDetail) {
    //用户被踢,清理登录缓存信息返回登录页面
}

public func onLoginStatus(_ status: V2NIMLoginStatus) {
    //根据返回的登录状态做页面轻提示
}

获取登录状态

通过调用 getLoginStatus 获取登录状态,如果用户已经处于已登录和登录中状态,请勿再频繁调用登录接口登录。

登录状态 说明
V2NIM_LOGIN_STATUS_LOGOUT(0) 已登出
V2NIM_LOGIN_STATUS_LOGINED(1) 已登录
V2NIM_LOGIN_STATUS_LOGINING(2) 正在登录
V2NIM_LOGIN_STATUS_UNLOGIN(3) 未登录
安卓
JavaV2NIMLoginStatus status = NIMClient.getService(V2NIMLoginService.class).getLoginStatus();
iOS
Objective-C- (void)printLoginStatus:(V2NIMLoginStatus)status
{
    switch (status) {
        case V2NIM_LOGIN_STATUS_LOGOUT:
            NSLog(@"login status = logout");
            break;
        case V2NIM_LOGIN_STATUS_LOGINING:
            NSLog(@"login status = logining");
            break;
        case V2NIM_LOGIN_STATUS_LOGINED:
            NSLog(@"login status = logined");
            break;
        default:
            NSLog(@"login status = %ld", status);
    }
}

V2NIMLoginStatus status = [[[NIMSDK sharedSDK] v2LoginService] getLoginStatus];
此文档是否对你有帮助?
有帮助
去反馈
  • 注意事项
  • 准备工作
  • Demo 体验
  • 登录流程
  • 首次登录
  • 自动登录
  • 登录状态处理
  • 获取登录状态