iOS SDK 开发指南
本文介绍如何在 iOS 原生项目中,于已进入房间后使用自定义消息或帧同步传输对战数据。
接入房间和连接前,请先完成快速入门。
状态同步
自定义消息同步
通过自定义消息在房间内同步玩家操作或状态,适合回合制、棋牌等对实时性要求不高的场景。流程可概括为:一方发送自定义消息,服务端转发后,房间内对应玩家在回调中解析并更新游戏状态。

适合的游戏类型包括:
- 棋牌类:五子棋、象棋、斗地主、麻将等
- 回合制:战棋、策略、回合制 RPG 等
- 休闲类:你画我猜、狼人杀、问答等
- 合作类:简单多人闯关、合作解谜等
发送自定义消息
该接口 和 更新玩家自定义状态(UpdatePlayerCustomStatus)、更新玩家自定义属性(UpdatePlayerCustomProperties)、更新房间信息(UpdateRoomProperties)共享每秒15次调用限制
开始游戏后,开发者通过将玩家操作数据封装为自定义消息内容同步给其他玩家,每秒最多 15 次,调用示例如下:
- Swift
- Objective-C
import TapOnlineBattleSDK
class CustomMessageSender: SendCustomMessageListener {
func onSuccess() {
print("发送自定义消息 成功")
// 房间内对应玩家通过 onCustomMessageReceived 回调收到通知
}
func onFailure(error: ErrorResponse) {
print("发送自定义消息 error \(error.code) \(error.msg)")
}
}
// customMsg:消息内容,最大2048字节;customMsgType:0 广播,1 指定玩家;playerIds:type==1 时有效
TapTapOnlineBattle.sendCustomMessage(msg: customMsg, type: customMsgType, receivers: playerIds, listener: CustomMessageSender())
#import <TapOnlineBattleSDK/TapOnlineBattleSDK-Swift.h>
// customMsg:消息内容,最大2048字节;customMsgType:0 广播,1 指定玩家;playerIds:type==1 时有效
[TapTapOnlineBattle sendCustomMessageWithMsg:customMsg type:customMsgType receivers:playerIds listener:[[MySendCustomMessageListener alloc] init]];
发送成功后,房间内对应玩家会通过 SDK 的 OnCustomMessageReceived 回调收到通知:
- Swift
- Objective-C
// 实现 TapOnlineBattleCallback 协议后,重写以下方法接收自定义消息
func onCustomMessageReceived(playerId: String, msg: String) {
// playerId 为消息发送者玩家 ID,msg 为消息内容
// TODO: 解析 msg,渲染对战状态或其他信息
}
// 实现 TapOnlineBattleCallback 协议后,重写以下方法接收自定义消息
- (void)onCustomMessageReceivedWithPlayerId:(NSString *)playerId msg:(NSString *)msg {
// playerId 为消息发送者玩家 ID,msg 为消息内容
// TODO: 解析 msg,渲染对战状态或其他信息
}
帧同步
帧数据同步
高实时性游戏,如格斗、MOBA、FPS,可使用帧同步:房主开始帧同步后,各端发送帧输入同步操作,房主停止帧同步或超时后结束本局。

- 开始对战:房主调用开始帧同步,房间内所有玩家进入帧同步状态
- 对战进行中:玩家发送帧输入进行帧数据同步
- 结束对战:房主调用停止帧同步,或超过 30 分钟后服务端强制结束
- 帧率为每秒 30 帧
- 开始帧同步后,最大支持 30 分钟,超过时间后服务端会强制停止帧同步
- 每个玩家每帧最多允许发送 5 次操作数据
开始帧同步
当房间内所有玩家状态就绪后,房主开启对战时,调用开始帧同步接口:
- Swift
- Objective-C
import TapOnlineBattleSDK
class StartFrameSyncHandler: StartFrameSyncListener {
func onSuccess() {
print("开始帧同步 成功")
// 房间内所有玩家会通过 onFrameSyncStarted 回调收到通知
}
func onFailure(error: ErrorResponse) {
print("开始帧同步 error \(error.code) \(error.msg)")
}
}
// 开始帧同步,仅房主可调用
TapTapOnlineBattle.startFrameSync(listener: StartFrameSyncHandler())
#import <TapOnlineBattleSDK/TapOnlineBattleSDK-Swift.h>
[TapTapOnlineBattle startFrameSyncWithListener:[[MyStartFrameSyncListener alloc] init]];
此时房间内所有玩家会通过 SDK 的 OnFrameSyncStarted 回调收到通知:
- Swift
- Objective-C
// 实现 TapOnlineBattleCallback 协议后,重写以下方法
func onFrameSyncStarted(frameSyncInfo: FrameSyncInfo) {
print("receive onFrameSyncStarted \(frameSyncInfo)")
// frameSyncInfo.seed 是随机数种子,用于初始化随机数生成器
}
// 实现 TapOnlineBattleCallback 协议后,重写以下方法
- (void)onFrameSyncStartedWithFrameSyncInfo:(FrameSyncInfo *)frameSyncInfo {
NSLog(@"receive onFrameSyncStarted frameSyncId:%ld seed:%ld", (long)frameSyncInfo.frameSyncId, (long)frameSyncInfo.seed);
// frameSyncInfo.seed 是随机数种子,用于初始化随机数生成器
}
回调中会返回本次帧同步的基础信息 (FrameSyncInfo),主要包含房间信息(roomInfo) 、随机种子(seed)等
注意:开启帧同步后,禁止执行管理房间的所有操作,包括更新房间信息、更新玩家属性、离开房间、踢出玩家等,否则会收到错误码 26 的异常
发送玩家操作数据
对战过程中,玩家的操作数据可通过调用如下接口进行同步:
- Swift
- Objective-C
import TapOnlineBattleSDK
class FrameInputSender: SendFrameInputListener {
func onSuccess() {
print("发送玩家 Input 数据 成功")
// 房间内其他玩家通过 onFrameReceived 回调收到通知
}
func onFailure(error: ErrorResponse) {
print("发送玩家 Input 数据 error \(error.code) \(error.msg)")
}
}
// playData 玩家操作数据,utf8字符串格式,最大1024字节
TapTapOnlineBattle.sendFrameInput(data: playData, listener: FrameInputSender())
#import <TapOnlineBattleSDK/TapOnlineBattleSDK-Swift.h>
// playData 玩家操作数据,utf8字符串格式,最大1024字节
[TapTapOnlineBattle sendFrameInputWithData:playData listener:[[MySendFrameInputListener alloc] init]];
房间内其他玩家会通过 SDK 的 OnFrameReceived 回调收到通知:
- Swift
- Objective-C
// 实现 TapOnlineBattleCallback 协议后,重写以下方法
func onFrameReceived(frameData: FrameData) {
if !frameData.inputs.isEmpty {
print("receive onFrameReceived frameId:\(frameData.id) inputs:\(frameData.inputs.count)")
}
}
// 实现 TapOnlineBattleCallback 协议后,重写以下方法
- (void)onFrameReceivedWithFrameData:(FrameData *)frameData {
if (frameData.inputs.count > 0) {
NSLog(@"receive onFrameReceived frameId:%ld inputs:%lu", (long)frameData.id, (unsigned long)frameData.inputs.count);
}
}
回调中返回的参数 frameData 会包括当前帧 ID 及多个玩家的多个操作数据,其中 inputs 字段为玩家操作数据集合,集合中每条数据包含了玩家 ID、玩家操作数据、发送时间等信息。
停止帧同步
当房主结束对战时,开发者通过调用停止帧同步接口结束同步玩家数据:
- Swift
- Objective-C
import TapOnlineBattleSDK
class StopFrameSyncHandler: StopFrameSyncListener {
func onSuccess() {
print("停止帧同步 成功")
// 房间内其他玩家通过 onFrameSyncStopped 回调收到通知
}
func onFailure(error: ErrorResponse) {
print("停止帧同步 error \(error.code) \(error.msg)")
}
}
// 停止帧同步,仅房主可调用
TapTapOnlineBattle.stopFrameSync(listener: StopFrameSyncHandler())
#import <TapOnlineBattleSDK/TapOnlineBattleSDK-Swift.h>
[TapTapOnlineBattle stopFrameSyncWithListener:[[MyStopFrameSyncListener alloc] init]];
其他玩家会通过 OnFrameSyncStopped 回调收到通知:
- Swift
- Objective-C
// 实现 TapOnlineBattleCallback 协议后,重写以下方法
// reason: 0 房主主动结束,1 因30分钟超时结束
func onFrameSyncStopped(roomId: String, frameSyncId: Int, reason: Int) {
print("receive onFrameSyncStopped \(roomId):\(frameSyncId):\(reason)")
}
// 实现 TapOnlineBattleCallback 协议后,重写以下方法
// reason: 0 房主主动结束,1 因30分钟超时结束
- (void)onFrameSyncStoppedWithRoomId:(NSString *)roomId frameSyncId:(NSInteger)frameSyncId reason:(NSInteger)reason {
NSLog(@"receive onFrameSyncStopped %@:%ld:%ld", roomId, (long)frameSyncId, (long)reason);
}
随机数生成器
为保证玩家对战过程中,对于随机掉落物品或其他奖励的概率保持一致,不同玩家可使用该生成器生成相同序列的随机数。
建议在收到开始帧同步( OnFrameSyncStarted) 的回调中,使用返回的帧同步基础信息 FrameSyncInfo 参数的 seed 字段来初始化随机数生成器。
- Swift
- Objective-C
import TapOnlineBattleSDK
// 在 onFrameSyncStarted 回调中使用服务端下发的随机种子
let seed = frameSyncInfo.seed
// 创建生成器(deinit 会自动释放,也可手动调用 free())
let rng = TapTapOnlineBattle.NewRandomNumberGenerator(seed: seed)
// 生成随机数(返回 [0, 0x7fffffff])
let value = rng.randomInt()
print("生成随机数 成功 \(value)")
// 对战结束后手动释放
rng.free()
#import <TapOnlineBattleSDK/TapOnlineBattleSDK-Swift.h>
// 在 onFrameSyncStarted 回调中使用服务端下发的随机种子
NSInteger seed = frameSyncInfo.seed;
// 创建生成器(dealloc 会自动释放,也可手动调用 free)
RandomNumberGenerator *rng = [TapTapOnlineBattle NewRandomNumberGeneratorWithSeed:seed];
// 生成随机数(返回 [0, 0x7fffffff])
NSInteger value = [rng randomInt];
NSLog(@"生成随机数 成功 %ld", (long)value);
// 对战结束后手动释放
[rng free];