互动礼物

互动礼物组件是一款虚拟礼物互动平台,旨在为用户的社交体验增添更多乐趣。借助这一组件,用户能够向自己欣赏的直播主播送上虚拟礼物,以此展示他们的赞赏、喜爱以及支持。
互动礼物组件支持设置礼物素材余额显示、普通礼物播放与全屏礼物播放、充值按钮等。

礼物展示




礼物展示面板



普通礼物播放效果



全屏礼物播放效果

礼物系统







礼物系统结构图
礼物系统时序图
客户端短连接请求到自己的业务服务器,涉及到礼物计费逻辑。
1. 计费后,发送人直接看到 XXX 送了 XXX 礼物(以确保发送人自己看到自己发的礼物,消息量大的时候,可能会触发抛弃策略)。
2. 计费结算后,调用GiftListView.sendGift发送消礼物消息。

快速接入

礼物组件主要提供2个API:
TUIGiftListView:礼物面板,呈现礼物列表,发送礼物及充值。
TUIGiftPlayView:播放礼物的面板,自动监听礼物消息。

设置礼物素材

礼物面板组件 TUIGiftListView 提供了 setGiftList 接口,可用于设置礼物素材。
let giftListView: TUIGiftListView = TUIGiftListView(groupId: xxx) //生成礼物面板对象
let giftList: [TUIGift] = ... //这里可替换成自己的礼物素材数组
giftListView.setGiftList(giftList) //设置礼物面板的素材
说明:
TUIGift的参数及说明如下:
giftId: String:礼物 ID
giftName: String:礼物名称
imageUrl: String:礼物面板展示图像
animationUrl: String:SVGA 动画 Url
price: Int:礼物价格
extInfo: [String: AnyCodable] :自定义扩展信息
互动礼物组件支持设置自己的礼物素材。若animationUrl 为空,则礼物播放效果为普通播放,播放的内容为 imageUrl 所链接的图像;若 animationUrl 不为空,则播放效果为全屏播放,播放的内容为对应的 svga 动画。

赠送礼物

实现 TUIGiftListView 的代理 TUIGiftListViewDelegate 中的 onSendGift 代理函数 ,获取礼物个数和礼物信息,在预处理完后可调用 TUIGiftListView sendGift 函数用于礼物的实际发送。
giftListView.delegate = self

extension ViewController: TUIGiftListViewDelegate {
func onSendGift(giftListView view: TUIGiftListView, giftModel: TUIGift, giftCount: Int) {
//...此处为预处理,如校验当前用户的余额等操作
let receiver = TUIGiftUser()
//...此处设置礼物接受者信息
view.sendGift(giftModel: giftModel, giftCount: giftCount, receiver: receiver)
}
}

接收礼物

礼物展示组件 TUIGiftPlayView 自身会接收并播放礼物消息。
let giftDisplayView: TUIGiftPlayView = TUIGiftPlayView(groupId:xxx)
说明:
TUIGiftPlayView 需要全屏接入
若需要获取接收礼物的回调信息,可将实现 TUIGiftPlayView 的代理 TUIGiftPlayViewDelegate 中的 giftPlayView:onPlayGift 代理函数。

extension ViewController: TUIGiftPlayViewDelegate {
func giftPlayView(_ giftPlayView: TUIGiftPlayView, onPlayGift gift: TUIGift, giftCount: Int, sender: TUIGiftUser, receiver: TUIGiftUser) {
//...可在此处自行处理
}
}

播放礼物动画

需要主动调用 TUIGiftPlayView playGiftAnimation 进行动画播放,调用时机是在收到 TUIGiftPlayViewDelegateonPlayGiftAnimation 回调。

extension ViewController: TUIGiftPlayViewDelegate {
func giftPlayView(_ giftPlayView: TUIGiftPlayView, onPlayGiftAnimation gift: TUIGift) {
//...
}
}
说明:
仅支持 SVGA 动画。

设置余额

礼物面板组件 TUIGiftListView 提供了 setBalance 接口,可用于设置礼物面板上显示的余额值。
giftListView.setBalance(xxx)

充值

实现 TUIGiftListView 的代理 TUIGiftListViewDelegate 中的 onRecharge 代理函数可用于接收礼物展示面板抛出的充值按钮点击事件,在这里对接自己的充值系统。
extension ViewController: TUIGiftListViewDelegate {
func onRecharge(giftListView view: TUIGiftListView) {
//...此处可用于对接自己的充值系统,充值完毕后,可调用view.setBalance(xxx)设置礼物展示面板的余额显示
}
}
注意:
1、礼物余额是个虚拟币的概念,并不是真实货币。
2、礼物充值逻辑,由外部实现,客户可以接入自己的充值系统。充值完毕后再更新礼物余额。

计费统计

实现 TUIGiftListViewTUIGiftListViewDelegate 中的 onSendGift 代理函数,连接客户自己的业务服务器,完成余额校验、礼物计费、消费统计后,再调用 TUIGiftListView sendGift 发送礼物消息。
giftListView.delegate = self

extension ViewController: TUIGiftListViewDelegate {
func onSendGift(giftListView view: TUIGiftListView, giftModel: TUIGift, giftCount: Int) {
//...此处连接客户自己的业务服务器,完成余额校验、礼物计费、消费统计等
let receiver = TUIGiftUser()
//...此处设置礼物接受者信息
view.sendGift(giftModel: giftModel, giftCount: giftCount, receiver: receiver)
}
}

自定义礼物列表

修改观众端礼物面板的礼物列表:
// 源码路径:TUILiveKit/Source/LiveRoom/View/Audience/Component/AudienceLivingView.swift

private lazy var giftPanelView: TUIGiftListView = {
let view = TUIGiftListView(groupId: liveRoomInfo.roomId.value)
giftCloudServer.queryGiftInfoList { [weak self] error, giftList in
guard let self = self else { return }
DispatchQueue.main.async {
if error == .noError {
view.setGiftList(giftList)
} else {
self.makeToast("query gift list error, code = \(error)")
}
}
}
return view
}()

说明:
1、客户自行实现 giftCloudServer.queryGiftInfoList的逻辑,得到一个自定义的礼物列表 [TUIGift] ,通过 view.setGiftList设置礼物列表即可。
2、礼物的animationUrl 要求是一个SVGA动画。

自定义礼物余额充值

// 源码路径:TUILiveKit/Source/LiveRoom/View/Audience/Component/AudienceLivingView.swift

private lazy var giftPanelView: TUIGiftListView = {
let view = TUIGiftListView(groupId: liveRoomInfo.roomId.value)
giftCloudServer.queryBalance { [weak self] error, balance in
guard let self = self else { return }
DispatchQueue.main.async {
if error == .noError {
view.setBalance(balance)
} else {
self.makeToast("query balance error, code = \(error)")
}
}
}
return view
}()
说明:
客户自行实现 giftCloudServer.queryBalance 的逻辑,得到礼物余额,通过view.setBalance更新礼物余额即可。

自定义礼物消费逻辑

// 源码路径:TUILiveKit/Source/LiveRoom/View/Audience/Component/AudienceLivingView.swift

func onSendGift(giftListView view: TUIGiftListView, giftModel: TUIGift, giftCount: Int) {
let receiver = TUIGiftUser()
receiver.userId = liveRoomInfo.anchorInfo.value.userId
receiver.userName = liveRoomInfo.anchorInfo.value.name.value
receiver.avatarUrl = liveRoomInfo.anchorInfo.value.avatarUrl.value
receiver.level = "0"
giftCloudServer.sendGift(sender: TUILogin.getUserID() ?? "",
receiver: receiver.userId,
giftModel: giftModel,
giftCount: giftCount) { [weak self] error, balance in
guard let self = self else { return }
if error == .noError {
view.sendGift(giftModel: giftModel, giftCount: giftCount, receiver: receiver)
view.setBalance(balance)
} else {
self.makeToast(.balanceInsufficientText)
}
}
}

说明:
客户自行实现 giftCloudServer.sendGift 的逻辑,主要流程是,首先连接客户自己的业务服务器,进行余额校验,校验通过后,由服务器进行计费并统计消费记录,最后将结果回调给客户端。客户端收到成功回调后,通过GiftListView sendGift发送礼物消息,之后再通过setBalance更新礼物余额。

自定义加载礼物动画并播放


// 源码路径:
// TUILiveKit/Source/LiveRoom/View/Audience/Component/AudienceLivingView.swift
// TUILiveKit/Source/LiveRoom/View/Anchor/Living/AudienceLivingView.swift

func giftPlayView(_ giftPlayView: TUIGiftPlayView, onPlayGiftAnimation gift: TUIGift) {
giftCacheService.request(urlString: gift.animationUrl) { error, data in
guard let data = data else { return }
if error == 0 {
DispatchQueue.main.async {
giftPlayView.playGiftAnimation(animationData: data)
}
}
}
}

说明:
客户自行实现 giftCacheService.request 的逻辑,加载动画成功得到dataData类型),然后通过TUIGiftPlayView playGiftAnimation播放礼物动画。