Skip to content

模型、枚举与错误

1. 模型命名

原生端公开模型统一以 XHIM 开头。iOS 与 macOS 使用 Swift struct/enum,Android 使用 Kotlin data class/sealed interface,Windows 使用 C# class/record/enum, HarmonyOS 使用 ArkTS interface/class/enum。字段采用各语言惯例:

text
iOS/macOS  serverMessageID
Android    serverMessageId
Windows    ServerMessageId
HarmonyOS  serverMessageId

同名语义、空值规则和单位保持一致。

2. 生命周期与配置模型

类型关键字段 / 用途
XHIMEvent状态、消息、会话、社交、媒体、Presence 和 Typing 事件联合类型
XHIMAccountStateChange账号状态、固定剔除原因、revision、account epoch 与连接代次
XHIMProjectionChangedurable 本地投影的轻量失效通知
XHIMProjectionKindmessage upsert/state/local delete、conversation、social、sync
XHIMProjectionOriginlocal、remoteSync、outbox、未来值
XHIMSocialProjectionScopefriend requests、friendships、groups、members、blocks、join requests
XHIMClientConfigurationappID、账号存储、事件容量、运行策略、部署发现结果
XHIMRuntimePolicyrequest timeout、sync page size、reconnect backoff/attempts
XHIMDeploymentbootstrap URL、Endpoint signing key ID/public key
XHIMClientModeproduction 或仅测试构建允许的 local preview
XHIMAuthenticationdevelopment、accessToken、business provider
XHIMCompatibilitySnapshotclient/server protocol、最低客户端协议、capabilities
XHIMDiagnostics无敏感信息的容量、队列、请求和回调计数
XHIMDeviceSessionPolicy多端登录策略、设备上限和当前 session

3. 消息与会话模型

类型关键字段
XHIMOutgoingMessagecontentType、contentVersion、payload、fallbackText、deliveryPolicy
XHIMMessageDeliveryPolicydurable 或 1 秒到 30 天的 burnAfterRead
XHIMMessagelocal/server identity、sender、state、内容、mutation revision、isLocalOnly
XHIMLocalMessageResultchanged、deletedCount、localExtension、message、isLocalOnly
XHIMSendReceiptSDK 接受操作的 opaque payload
XHIMMessagePagemessages、nextCursor
XHIMMessageHistoryContinuationbeforeServerSequence
XHIMMessageHistoryPagemessages、continuation、latestServerSequence、view
XHIMMessageSearchQuerytext、conversation、sender、content types、时间范围
XHIMMessageVisibility当前账号是否删除、revision、mutation ID
XHIMMessageVisibilityMutationvisibility、idempotent replay
XHIMConversationID、类型/标题、last message、unread、read sequence、revision
XHIMConversationPageconversations、nextCursor
XHIMConversationViewcleared/hidden watermark、revision
XHIMConversationViewMutationview、idempotent replay
XHIMConversationPreferencepinned、notifications muted、服务端规范化 applicationExtensionJSON、可选 messageRetentionSeconds(unknown/null 与权威 0 分离)、revision、mutation ID、updated time
XHIMConversationDraftconversation、optional outgoing message、updated time
XHIMDirectConversationconversationID、participant user IDs
XHIMConversationReadReceiptread sequence、unread count、updated time
XHIMConversationReadSnapshotconversation、read server sequence
XHIMMarkAllConversationsReadResultchanged count、changed reads、truncation flags
XHIMHideAllConversationsResultchanged count、idempotent replay、Sync projection state
XHIMConversationPeerReadreader、read sequence、revision、updated time
XHIMConversationPeerReadPageconversation、reads、truncated
XHIMGroupMessageReadDetailserver message ID、server sequence、reader IDs、派生 read count
XHIMGroupMessageReadPageconversation、逐消息 details、peer reads 是否截断
XHIMGroupMemberMessageTombstoneconversation、target user、through server sequence、revision、mutation/actor/time
XHIMGroupMemberMessageModerationResult权威 sender-watermark 墓碑和幂等重放标志

消息的 payload 始终保持原始不可变字节。未知 contentType 不能丢弃,必须使用 fallbackText 安全降级。

4. 用户、关系链与群组模型

XHIMSocialSummary 使用同一账号加密投影计算有效好友数、收到的 待处理好友申请数、已加入群数和可见的待处理入群申请数,适合直接 驱动通讯录和申请入口角标。

类型关键字段
XHIMUserProfile内部 userID、前端展示 publicUserID、displayName、avatarURL、bio、created/updated time;保持已发布的旧模型前缀,不在其中伪造扩展
XHIMUserProfileBatchprofiles、missingUserIDs
XHIMUserProfileUpdate可选 displayName/avatarURL 等更新字段;可选 applicationExtensionJSON 省略不改、空 bytes 清除
XHIMUserProfileExtension与 profile userID 精确对齐的公开、服务端规范 JSON;空值为权威清除
XHIMUserProfileEnvelope一份基础 profile + 一份同 ID extension;Native Wrapper 已在回调内深拷贝
XHIMUserProfileBatchWithExtensionsprofiles、等长/同下标 extensions、missing user IDs
XHIMFriendRequest基础 requestID、from/to、introduction、source、sourceConversationID、state、revision;旧 Core 兼容模型不表示扩展可用性
XHIMSocialRequestExtension / XHIMFriendRequestEnvelope与好友申请 requestID 精确对齐的参与双方可见扩展
XHIMFriendshippeer profile/remark、当前账号私有置顶、受限业务扩展 JSON、共享属性 CAS revision、created/updated time
XHIMFriendRequestResolution / extension-aware variantrequest、可选 friendship;扩展感知结果另返回原申请的权威扩展
XHIMFriendshipDeletionpeer、deleted、idempotent replay
XHIMFriendRemarkChangepeer、remark、revision、idempotent replay
XHIMRelationshipStatususerID、isFriend、blockedByMe
XHIMGroupconversationID、title、avatar、owner、member count、memberProfileVisible、memberFriendRequestsAllowed、newMemberHistoryVisible、群公开业务扩展、revision
XHIMGroupMembergroup、user、群内 nickname、实时 displayName/avatarURL、成员级 applicationExtensionJSON、role、state、mute、revision
XHIMGroupJoinRequest / extension-aware variantrequest、group、applicant、state、revision;扩展感知结果携带只对申请人与管理者可见的审批 metadata
XHIMGroupChangegroup、revision、changed member count、idempotent replay
XHIMGroupLifecycleResultgroup、left/dismissed、idempotent replay
XHIMGroupJoinMutationrequest、membership result、idempotent replay
XHIMBlock / extension-aware variantblocked user、active、revision、updated time;扩展感知结果携带当前账号私有的方向扩展
XHIMSocialPage<T>items、nextCursor、可选 group revision fence
XHIMSocialProjectionIntegritykind/reason、complete、marker/revision/count/checkpoint/scope,用于证明加密本地群投影完整性

applicationExtensionJSON 在用户资料上是对陌生人也可见的公开业务 元数据,不受 privateProfileVisible 隐藏。它只能容纳非敏感、非认证、 非凭证的小型 JSON object。好友申请扩展只对申请双方可见; 入群申请扩展只对申请人和群主/管理员可见;黑名单扩展只对 当前账号可见;群扩展对可读取群资料的成员可见。

扩展可用性和扩展值必须分开:

  • 旧/基础模型没有扩展字段,或 Android 兼容模型中为 null, 都表示 unknown/unavailable
  • 扩展感知方法成功后的空 Data/空字符串表示服务端 authoritative clear
  • 非空值是服务端 canonical JSON,不保证与请求原文字节相同。

Apple、Android、Windows 的基础关系模型使用 nullable applicationExtensionJSON/Json 表达 unknown;显式 extension-aware 入口 成功后保证该字段 non-null。HarmonyOS 用独立强类型 extension-aware 模型;Flutter 保留 Dart nullable 表达能力不可用;Electron 基础模型字段 可缺失,显式结果则是 required string。Web 直接服务端 Facade 的扩展 字段是 canonical 权威值。

5. Presence、Typing、Push 和设备

类型关键字段
XHIMPresenceUpdateeventID、userID、status、activePlatforms、sequence、expiresAt
XHIMPresenceSnapshot / XHIMPresencePublication授权查询或服务端接受后的 Presence 快照
XHIMTypingUpdateeventID、conversationID、userID、isTyping、activePlatforms、sequence、expiresAt
XHIMTypingSnapshot / XHIMTypingPublication纯读或发布后的 Typing 快照;纯读可返回 sequence 0
XHIMCustomSignalevent/conversation/sender/client signal ID、content type/version、payload、sequence、expiresAt
XHIMPushDeviceplatform、deviceID、秘密 token、environment、locale
XHIMPushDeviceRegistrationenabled、token reassigned、device limit/evictions
XHIMPushDeviceDisableResultdisabled、changed
XHIMDeviceSessionsession/device/platform、current/active、时间、revoke reason
XHIMDeviceSessionPagesessions、policy
XHIMDeviceSessionRevocationsession、revoked、idempotent replay

Push Token 的 description/debug output 会被替换为 <redacted>

6. Call Session 与 RTC 凭证

类型关键字段 / 用途
XHIMCallMediaKindaudio、video、未来值
XHIMCallSessionStateringing、active、ended(终态)、未来值
XHIMCallSignalKindinvite、accepted、rejected、ended、未来值
XHIMCallSessioncall/conversation/inviter/participants、media/state、sequence、时间和结束原因
XHIMRTCCredentialLeaseprovider、room、短期 token/endpoint、expiresAt;禁止持久化和日志
XHIMCallAcceptResultactive session 与一次短期 RTC credential lease
XHIMCallSignaldurable offset、per-call sequence、actor、participants、state 及可选短期凭证
XHIMCallSignalPagesignals、recovery active sessions、next offset、hasMore、server time

Call 的数据顺序和凭证安全合同见 Call Session、RTC Provider 与崩溃恢复

7. 媒体模型

类型用途
XHIMMediaEncryptionscheme、keyID、nonce、wrappedKey
XHIMMediaRef不可变服务端媒体身份和内容哈希
XHIMMediaTaskdurable upload/download 状态快照
XHIMMediaTaskUpdate轻量事件载荷;用 taskID 重查完整任务
XHIMMediaUploadIntent本地上传文件和依赖消息元数据
XHIMMediaDownloadIntentmedia ref、cache key 和下载目的
XHIMMediaUploadRequest兼容旧 uploader 的直接上传请求
XHIMMediaUploadProgressphase、completed bytes、total bytes
XHIMMediaCacheReaderSDK 缓存对象的有界读取句柄
XHIMMediaMessageContent图片、视频、语音、文件消息的强类型接收端内容
XHIMMediaDownloadProgress授权/下载/校验阶段和字节进度
XHIMDownloadedMedia已完成大小与 SHA-256 校验的私有缓存文件
XHIMLocationContent标准位置消息的经纬度、名称与地址
XHIMContactCardContent标准名片消息的内部路由 ID、昵称与头像;UI 不直接展示内部 ID

Android/HarmonyOS 在文件或 URI 模型上使用平台原生类型,但进入 Core 后语义 相同。

XHIMSDKMetadata

进程内 SDK 构建身份:versionsourceCommitabiVersion。 该类型不含运行时会话数据,可用于客服工单、崩溃元数据和制品验收; 不应将其与 Server XHIMCompatibilitySnapshot 混淆。Web 端的 abiVersionnull,并额外标注 metadataSource=package-build

8. 自定义消息模型

类型用途
XHIMMessagePlugin / IXHIMMessagePlugin版本校验与展示适配协议
XHIMMessagePluginRegistry注册、反注册、校验和 presentation 查询
XHIMMessagePresentationconversation preview、notification preview、renderer key
XHIMMentionContent标准 @ 消息解码结果
XHIMForwardItem合并转发中一个不可变消息条目
XHIMQuoteContent引用回复的源消息 ID、发送者、摘要和回复正文
XHIMMergedForwardContent合并转发标题和最多 100 个不可变消息条目

9. 主要枚举值

XHIMClientState

含义
created已创建,Core 未启动
startedCore 已启动,未登录
authenticating正在认证
connecting正在建立实时连接
synchronizing正在同步本地投影
ready可读写
credentialRequired需要续凭
loggingOut正在退出
closed已不可逆关闭
fatal不可恢复错误

XHIMAccountState 与 XHIMKickedReason

  • XHIMAccountStateunknown(0)active(1)suspended(2)unregistered(3)
  • XHIMKickedReasonnone(0)accountSuspended(1)accountUnregistered(2) 以及各平台的未知值保留形式。

XHIMAccountStateChange.revision > 0 才是服务端权威版本;0 是旧实时 frame 没有 tag 19 的兼容值。强类型事件不包含管理员填写 的治理原因。对 suspended / unregistered 客户端只依赖 account_suspended / account_unregistered 这两个固定 stable code。

XHIMMessageState

pendingsendingretryingserverAcceptedfailedcancelled, 以及平台用于前向兼容的 unknown

XHIMMessageContentKind

text(1)image(2)audio(3)video(4)file(5)custom(1000)unknown。业务判断优先使用 contentType,不要只依赖这个旧式 粗粒度 kind。

XHIMMarkdownContent

text/markdown@1 的强类型解码结果,包含 sourceplainTextFallback。两者都必须是非空、无 NUL 且不超过 64 KiB UTF-8 的 文本。该模型不代表已净化 HTML;SDK 不负责渲染,宿主必须使用安全 Markdown Renderer,无法渲染时显示 fallback。

XHIMMessageMutationKind

noneeditTextrecallunknown

XHIMMediaTaskState

pendingauthorizingtransferringpausedverifyingcompletedfailedcancelledunknown

XHIMMediaTaskDirectionuploaddownloadunknown

Projection 与短暂状态

  • XHIMProjectionKind:messageUpserted、messageStateChanged、 conversationChanged、socialChanged、syncApplied、unknown;
  • XHIMProjectionOrigin:local、remoteSync、outbox、unknown;C ABI 也保留 realtime 原始值供未来 Facade 使用;
  • XHIMSocialProjectionScope:none、friendRequests、friendships、groups、 groupMembers、blocks、groupJoinRequests、unknown;
  • XHIMPresenceStatus:online、away、offline、unknown。

Presence 主动查询快照和 presenceChanged 实时事件的 activePlatforms 是同一份 protobuf repeated enum。参考 Server Product Adapter 必须同时接受 protobuf 标准的 packed 编码和历史 unpacked 编码,并对数量及枚举范围做边界校验。应用层不解析 WebSocket 原始字节,只消费 SDK 给出的类型化在线端列表。

关系链与群组

  • XHIMFriendRequestState:pending、accepted、rejected、unknown;
  • XHIMFriendRequestDecision:accept、reject;
  • XHIMFriendRequestSource:profile、card、phone、account、qrCode、group;
  • XHIMGroupMemberRole:owner、administrator、member、unknown;
  • XHIMGroupMemberState:joined、removed、unknown;
  • XHIMGroupJoinRequestState:pending、accepted、rejected、unknown;
  • XHIMGroupJoinDecision:accept、reject;
  • XHIMGroupGovernanceChange:setAdministrator、setMute、setAllMute、 transferOwnership、setJoinApprovalRequired、setProfile、setOwnNickname、 setAccessPolicy、setNewMemberHistoryVisible、setMemberApplicationExtension、 setApplicationExtension;
  • XHIMSocialProjectionIntegrityKind:joinedGroups、groupMembers、unknown;
  • XHIMSocialProjectionIntegrityReason:complete、markerMissing、 replayIncomplete、checkpointMismatch、revisionMismatch、 memberCountMismatch、ownerMismatch、unknown;
  • XHIMMultiLoginPolicy:由服务端 capability snapshot 给出稳定策略名。

Flutter Facade 为了保持 Alpha 期存量代码兼容,仍保留原始 state / role 数值,同时提供 resolvedState / resolvedRole 强类型访问器。UI 和二次开发 应使用强类型访问器,不要在页面里散落 1 / 2 / 3 数字判断。

XHIMPushPlatform

apns(1)fcm(2)huawei(3)web(4)

XHIMDevicePlatform:iOS、Android、macOS、Windows、HarmonyOS、Web、Linux 和 unknown。

XHIMUserAction

noneretryupdateCredentialcheckNetworkcontactSupport

10. 稳定错误模型

iOS/macOS/HarmonyOS 暴露 XHIMNativeError,Android/Windows 暴露 XHIMException。业务分支使用这些字段:

字段稳定性用途
codeABI 稳定粗粒度状态
domain + stableCode跨语言稳定推荐的业务判断键
nativeCode透传HTTP、系统或服务端原始码
retryable稳定是否允许自动/手动重试
retryAfterMilliseconds稳定最早重试等待
userAction稳定UI 建议动作
operationID + traceID稳定诊断服务端链路排查
message不稳定文本仅日志和开发提示,禁止业务字符串匹配

Reference Server 返回非 2xx 时,Apple 与 Reference Product Adapter 会严格解析 服务端 ErrorEnvelope,保留 code、可读 messageretryableretry_after。Envelope 非法、字段重复、超长或不是 UTF-8 时安全降级为通用 后端错误,不能把未经验证的服务端字节直接显示给用户。UI 至少展示 stableCode + message;不应只把 ABI 数值显示成“错误 1”。

消息撤回需要区分两个业务错误:forbidden 表示当前用户没有撤回该消息的权限; recall_window_expired 表示消息属于当前用户,但已超过服务端允许的撤回窗口。 两者都不应自动重试,客户端分别展示“只能撤回自己发送的消息”和“已超过撤回时间”。

ABI code

数值名称常见处理
0OK成功
1INVALID_ARGUMENT修正调用参数,不重试
2INVALID_STATE等待 ready 或修正生命周期
3NOT_INITIALIZED先 start/connect
4ALREADY_CLOSED新建 Client
5BACKEND_NOT_CONFIGURED当前发行包缺少 Product Adapter
100STORAGE_ERROR检查空间/数据库 Key,必要时联系支持
101IDEMPOTENCY_CONFLICT重查实体,不盲目换 mutation ID
102NOT_FOUND刷新列表或提示对象不存在
103UNSUPPORTED检查 capability/version
104FORBIDDEN按服务端权限提示
105ACCOUNT_SUSPENDED停止续凭/重试,销毁当前账号容器并回到登录
106ACCOUNT_UNREGISTERED停止续凭/重试,清理登录态;账号不可恢复
200CANCELLED调用被取消
201SDK_SHUTDOWNClient 正在/已经关闭
202CALLBACK_QUEUE_FULL降低请求洪峰并收集诊断
203CREDENTIAL_REQUIRED由账号层 Provider 续凭
900INTERNAL_ERROR记录 operation/trace ID 并联系支持

application-extension 便利入口在加载旧 Core 时使用 103 UNSUPPORTED fail-closed;不得抓住该错误后回退基础写入入口。 新 Core 与未声明对应 extension capability 的旧 Server 组合也使用 103 在 mutation 前 fail-closed;符号存在不代表服务能力已协商。 基础列表仍可成功,但其扩展状态是 unknown。群成员完整投影刷新中 group_member_projection_revision_stale 是可重试的 revision 竞态; complete=false + 强类型 reason 是成功检查结果,不是错误。

105/106 的 retryable 固定为 false,stableCode 分别固定为 account_suspended / account_unregistered。Facade 不显示或转发服务端 管理厘由,也不得将这两类错误交给凭证 Provider 自动续凭。恢复 停用账号也不会恢复旧 Token,必须重新走购买方身份认证。

推荐处理:

swift
catch let error as XHIMNativeError {
    switch (error.domain, error.stableCode, error.userAction) {
    case (_, _, .updateCredential):
        accountSession.requireLogin()
    case (_, _, .checkNetwork):
        banner.showOffline()
    default:
        logger.error("XHIM \(error.operationID) \(error.traceID)")
    }
}

11. 一键连接错误

一键连接异常专用于 Server URL 验证、公开发现和首个凭证获取:iOS、macOS 和 HarmonyOS 为 XHIMConnectionError,Android 为 XHIMConnectionException, Windows 为 XHIMConnectionException。其错误类别包括:

  • invalid server URL / identity / server configuration;
  • insecure transport not allowed;
  • development login disabled;
  • credential unavailable;
  • server rejected(含 HTTP status);
  • response too large。

它发生在 Client 完全建立之前,与运行期 XHIMNativeError 分开处理。

XHIM 客户端 SDK 与服务端文档