本文介绍如何集成并使用 RTM SDK 快速构建一个简单的实时消息 app。
开始前,你需要阅读核心概念了解更多 RTM 产品中的概念。
本节展示 app 中实现发送和接收的基本工作流程:
createStreamChannel 创建一个 StreamChannel 类型实例,再调用 joinWithOption 加入频道。joinTopic 加入任意一个 Topic。publishMessage 发布消息,调用 subscribeTopic 订阅远端用户的消息。onMessageEvent 事件通知接收远端用户的消息。Xcode 9.0 或以上版本
iOS 9.0 或以上版本的设备
可以访问互联网的计算机。请确保你的网络环境未部署防火墙,否则可能无法正常使用声网服务。
参考以下步骤创建一个声网项目:
声网会给每个项目自动分配一个 App ID 作为项目唯一标识。
在声网控制台的项目管理页面,找到你的项目,点击 App ID 右侧的 图标,即可获取项目的 App ID。
在服务端生成 Token 并用于客户端鉴权,详见使用 Token 鉴权。
在 Xcode 中进行以下操作,在你的 app 中实现收发消息功能:
创建一个新的项目,Application 选择 App,Interface 选择 Storyboard,Language 选择 Swift。
为你的项目设置自动签名。
设置部署你的 app 的目标设备。
将声网 RTM 2 SDK 集成到你的项目。
开始前请确保你已安装 Cocoapods,如尚未安装 Cocoapods,参考 Getting Started with CocoaPods 安装说明。
在终端里进入项目根目录,并运行 pod init 命令。项目文件夹下会生成一个 Podfile 文本文件。
打开 Podfile 文件,修改文件为如下内容。注意将 Your App 替换为你的 Target 名称。
platform :ios, '9.0'
target 'Your App' do
pod 'AgoraRtcEngine_Special_iOS', '4.0.1.205'
end在终端内运行 pod install 命令安装声网 SDK。成功安装后,Terminal 中会显示 Pod installation complete!。
成功安装后,项目文件夹下会生成一个后缀为 .xcworkspace 的文件,通过 Xcode 打开该文件进行后续操作。
参考如下步骤实现消息收发逻辑。
导入类
import AgoraRtcKit
初始化 AgoraRtmClientKit 并添加事件回调
在调用 RTM 的任何 API 之前,你需要先调用 initWithConfig 创建并初始化一个 RtmClientKit 实例,并通过 RtmConfig 添加事件监听。你需要将 <RTM_USER_ID> 替换为对应的 User ID,将 <APP_ID> 替换为你的声网项目的 App ID。
let rtcKit = AgoraRtcEngineKit.sharedEngine(withAppId: "<APP_ID>", delegate: nil)
let rtm_config = AgoraRtmClientConfig();
rtm_config.userId = "<RTM_USER_ID>"
rtm_config.appId = "<APP_ID>"
class Handler : NSObject {
}
extension Handler: AgoraRtmClientDelegate {
func rtmKit(_ rtmKit: AgoraRtmClientKit, on event: AgoraRtmMessageEvent) {
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, on event: AgoraRtmPresenceEvent) {
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, onUser userId: String, joinChannel channelName: String, result errorCode: AgoraRtmStreamChannelErrorCode) {
print("user: " + userId + "join channel: " + channelName + "errorcoode:" + String(errorCode.rawValue))
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, onUser userId: String, leaveChannel channelName: String, result errorCode: AgoraRtmStreamChannelErrorCode) {
print("user: " + userId + "leave channel: " + channelName + "errorcoode:" + String(errorCode.rawValue))
}
func rtmKit(_ kit: AgoraRtmClientKit, channel channelName: String, connectionStateChanged state: AgoraRtmClientConnectionState, result reason: AgoraRtmClientConnectionChangeReason) {
print("connectionStateChanged : channel: " + channelName + " state:" + String(state.rawValue) + " reason" + String(state.rawValue))
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, onUser userId: String, joinTopic topic: String, inChannel channelName: String, withMeta meta: Date?, result errorCode: AgoraRtmStreamChannelErrorCode) {
print("user: " + userId + "joinTopic: " + topic + "channel: " + channelName + "errorcoode:" + String(errorCode.rawValue))
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, onUser userId: String, leaveTopic topic: String, inChannel channelName: String, withMeta meta: Date?, result errorCode: AgoraRtmStreamChannelErrorCode) {
print("user: " + userId + "leaveTopic: " + topic + "channel: " + channelName + "errorcoode:" + String(errorCode.rawValue))
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, onUser userId: String, inTopic topic: String, inChannel channelName: String, withSubscribeSuccess succeedUsers: [String], withSubscribeFailed failedUsers: [String], result errorCode: AgoraRtmStreamChannelErrorCode) {
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, onUser userId: String, inTopic topic: String, inChannel channelName: String, withUnsubscribeSuccess succeedUsers: [String], withUnsubscribeFailed failedUsers: [String], result errorCode: AgoraRtmStreamChannelErrorCode) {
}
let handler = Handler()
var rtm_kit = AgoraRtmClientKit(config: rtm_config,delegate: handler )
创建 Stream Channel 并加入频道
在使用 streamChannel 类中的任何 API 之前,你需要先调用 createStreamChannel 创建 Stream Channel。
// 创建一个频道名为 MyChannel 的 Stream Channel
var channel = kit?.createStreamChannel("MyChannel")
// 加入频道时使用 <RTM_TOKEN> token
let join_channel_config = AgoraRtmJoinChannelOption()
join_channel_config.token = "<RTM_TOKEN>"
// 加入频道
let ret1 = channel?.join(with: join_channel_config);
加入频道中的 Topic 并发布消息
成功加入 Topic 后,SDK 会自动将你注册为该 Topic 的消息发布者,你可以在该 Topic 中发送消息。成功发送后,SDK 会把该消息分发给该 Topic 的所有订阅者。
// 加入名为 MyTopic 的 Topic
let join_topic_config = AgoraRtmJoinTopicOption()
let ret2 = channel?.joinTopic("MyTopic", with: join_topic_config)
// 在 MyTopic 中发布内容为 data 的消息
let data = NSData.init()
let ret3 = channel?.publishMessage(data as Data, inTopic: "MyTopic")
订阅用户,获取已订阅用户列表,取消订阅用户
调用 subscribeTopic 订阅一个 Topic 中的一位或多位消息发布者,在一个 Topic 中最多只能订阅 64 位消息发布者。你也可以通过 getSubscribedUserList 查询当前已订阅的消息发布者列表。
// 订阅 My Topic 中 User ID 为 <OTHER_USER> 的用户
let topic_opt = AgoraRtmTopicOption()
topic_opt .users = ["<OTHER_USER>"]
channel?.subscribeTopic("MyTopic", with: topic_opt)
// 获取 My Topic 中你已经订阅的用户列表
var userss = NSMutableArray.init();
channel?.getSubscribedUserList(userss , inTopic: "MyTopic")
// 取消订阅 My Topic 中 User ID 为 <OTHER_USER> 的用户
let topic_opt = AgoraRtmTopicOption()
topic_opt .users = ["OTHER_USER"]
channel?.unsubscribeTopic("MyTopic", with: topic_opt)
离开 Topic,离开频道,并销毁 AgoraRtmClientKit 实例
如果你不需要在该 Topic 中发送消息,调用 leaveTopic 离开该 Topic。离开某个 Topic 不会影响你订阅其他 Topic 中的消息。
如果你不再需要发送或接收该频道中的消息,调用 leave 离开该频道。
如果你不再需要该频道,调用 destroy 销毁对应的 StreamChannel 实例以释放资源。
如果你不再需要使用 RTM 客户端,调用 destroy 销毁对应的 RtmClientKit 实例以释放资源。
// 离开 MyTopic
channel?.leaveTopic("MyTopic")
// 退出频道
let ret4 = channel?.leave();
// 销毁频道
channel?.destroy();
//销毁 AgoraRtmClientKit 实例
rtm_kit?.destroy()
AgoraRtcEngineKit.destroy()
userId 为不超过 64 位的任意字符串序列,且具有唯一性。不同用户、同一用户的不同终端设备需要通过不同的 userId 进行区分,所以你需要处理终端用户和 userId 的映射关系,确保终端用户的 userId 唯一且可以被复用。此外,项目中的 userId 数量还会影响最大连接数(PCU)的计量,从而影响计费。leave 之前自行记录相关信息,以便后续重新调用 join、joinTopic 和 subscribeTopic 进行相关设置。下图展示实现发送和接收消息的 API 调用时序,图中括号表示方法中设置的或回调中收到的用户 ID。
在实现发送和接收消息的过程中,你可以参考如下 API 文档: