本文介绍如何集成并使用 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 文档: