@tencent-rtc/mcp 1.3.4 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/resource/doc/chatuikit/android/features/theme.md +363 -0
- package/resource/doc/chatuikit/{android/client_api_Android.md → faq/android_sdk/client-api.md} +0 -2
- package/resource/doc/chatuikit/faq/common/product.md +8 -0
- package/resource/doc/chatuikit/faq/flutter_sdk/faq.md +53 -0
- package/resource/doc/chatuikit/{iOS/client_api_iOS.md → faq/ios_sdk/client-api.md} +0 -2
- package/resource/doc/chatuikit/flutter/features/theme.md +379 -0
- package/resource/doc/chatuikit/flutter/integration.md +413 -0
- package/resource/doc/chatuikit/flutter/workflow.md +941 -0
- package/resource/doc/chatuikit/iOS/features/theme.md +416 -0
- package/resource/doc/chatuikit/iOS/workflow.md +0 -0
- package/resource/doc/chatuikit/react/components/chat-setting.md +86 -0
- package/resource/doc/chatuikit/react/components/contact-list.md +1093 -0
- package/resource/doc/chatuikit/react/components/search.md +745 -0
- package/resource/doc/chatuikit/vue/components/chat-setting.md +64 -0
- package/resource/doc/chatuikit/vue/components/contact-list.md +679 -0
- package/resource/doc/chatuikit/vue/components/search.md +1384 -0
- package/resource/doc/livekit/live/android/workflow.md +137 -6
- package/resource/doc/livekit/live/ios/live-audience-list.md +339 -0
- package/resource/doc/livekit/live/ios/live-audio-effect.md +370 -0
- package/resource/doc/livekit/live/ios/live-barrage.md +517 -0
- package/resource/doc/livekit/live/ios/live-base-beauty.md +247 -0
- package/resource/doc/livekit/live/ios/live-co-guest-interaction.md +518 -0
- package/resource/doc/livekit/live/ios/live-gift.md +783 -0
- package/resource/doc/livekit/live/ios/live-host-interaction.md +815 -0
- package/resource/doc/livekit/live/ios/live-integration.md +931 -0
- package/resource/doc/livekit/live/ios/live-live-list.md +485 -0
- package/resource/doc/livekit/live/ios/workflow.md +454 -0
- package/resource/doc/rtcengine/web/plugin/20-advanced-customized-capture-rendering.md +87 -0
- package/resource/doc/rtcengine/web/plugin/21-advanced-auto-play-policy.md +87 -0
- package/resource/doc/rtcengine/web/plugin/22-advanced-audio-mixer.md +175 -0
- package/resource/doc/rtcengine/web/plugin/23-advanced-support-detection.md +221 -0
- package/resource/doc/rtcengine/web/plugin/24-advanced-network-quality.md +140 -0
- package/resource/doc/rtcengine/web/plugin/25-advanced-device-change.md +99 -0
- package/resource/doc/rtcengine/web/plugin/26-advanced-publish-cdn-stream.md +451 -0
- package/resource/doc/rtcengine/web/plugin/27-advanced-small-stream.md +151 -0
- package/resource/doc/rtcengine/web/plugin/28-advanced-beauty.md +322 -0
- package/resource/doc/rtcengine/web/plugin/29-advanced-water-mark.md +149 -0
- package/resource/doc/rtcengine/web/plugin/30-advanced-cross-room-link.md +96 -0
- package/resource/doc/rtcengine/web/plugin/31-advanced-plugins-overview.md +330 -0
- package/resource/doc/rtcengine/web/plugin/34-advanced-proxy.md +248 -0
- package/resource/doc/rtcengine/web/plugin/35-advanced-ai-denoiser.md +81 -0
- package/resource/doc/rtcengine/web/plugin/36-advanced-virtual-background.md +242 -0
- package/resource/doc/rtcengine/web/plugin/37-advanced-voice-changer.md +99 -0
- package/resource/doc/rtcengine/web/plugin/39-advanced-video-decoder.md +33 -0
- package/resource/doc/rtcengine/web/plugin/40-advanced-video-mixer.md +379 -0
- package/resource/doc/rtcengine/web/plugin/41-advanced-small-stream-auto-switcher.md +91 -0
- package/resource/doc/rtcengine/web/plugin/42-advanced-realtime-transcriber.md +315 -0
- package/resource/doc/rtcengine/web/plugin/43-advanced-face-detection.md +180 -0
- package/tools/chat/get-native-chat-feature-detail.js +30 -0
- package/tools/chat/get-native-chat-feature-detail.js.map +1 -0
- package/tools/chat/get-native-chat-integration.js +30 -12
- package/tools/chat/get-native-chat-integration.js.map +1 -1
- package/tools/common/get-faq.js +2 -4
- package/tools/common/get-faq.js.map +1 -1
- package/tools/definitions/get_native_chat_feature_detail_def.js +32 -0
- package/tools/definitions/get_native_chat_feature_detail_def.js.map +1 -0
- package/tools/definitions/get_native_chat_uikit_integration_def.js +19 -7
- package/tools/definitions/get_native_chat_uikit_integration_def.js.map +1 -1
- package/tools/definitions/{get_native_live_extra_features_def.js → get_native_live_uikit_extra_features_def.js} +3 -3
- package/tools/definitions/get_native_live_uikit_extra_features_def.js.map +1 -0
- package/tools/definitions/{get_native_live_interaction_def.js → get_native_live_uikit_interaction_def.js} +3 -3
- package/tools/definitions/get_native_live_uikit_interaction_def.js.map +1 -0
- package/tools/definitions/get_web_chat_uikit_component_detail_def.js +49 -10
- package/tools/definitions/get_web_chat_uikit_component_detail_def.js.map +1 -1
- package/tools/index.js +6 -4
- package/tools/index.js.map +1 -1
- package/tools/live/{get_native_live_extra_features.js → get_native_live_uikit_extra_features.js} +4 -4
- package/tools/live/get_native_live_uikit_extra_features.js.map +1 -0
- package/tools/live/{get_native_live_interaction.js → get_native_live_uikit_interaction.js} +4 -4
- package/tools/live/get_native_live_uikit_interaction.js.map +1 -0
- package/tools/rtcengine/get-rtcengine-web-sdk-integration.js.map +1 -1
- package/tools/rtcengine/get-trtc-sdk-faq.js +32 -0
- package/tools/rtcengine/get-trtc-sdk-faq.js.map +1 -0
- package/tools/rtcengine/get-trtc-web-sdk-faq.js +1 -1
- package/tools/rtcengine/get-trtc-web-sdk-integration.js.map +1 -1
- package/tools/rtcengine/get-trtc-web-sdk-plugin.js +45 -0
- package/tools/rtcengine/get-trtc-web-sdk-plugin.js.map +1 -0
- package/utils/handle-component-name.js +0 -16
- package/utils/handle-component-name.js.map +1 -1
- package/utils/report-cls-client.js +1 -1
- package/utils/report-es-client.js +1 -1
- package/resource/doc/chatuikit/android/generate_UserSig.md +0 -306
- package/resource/doc/chatuikit/android/integrarte_only_tuichat_Android.md +0 -290
- package/resource/doc/chatuikit/android/quick_start_Android.md +0 -138
- package/resource/doc/chatuikit/android/show_typing_Android.md +0 -43
- package/resource/doc/chatuikit/flutter/generate_UserSig.md +0 -306
- package/resource/doc/chatuikit/flutter/integrate_tuikit_Flutter.md +0 -133
- package/resource/doc/chatuikit/iOS/generate_UserSig.md +0 -306
- package/resource/doc/chatuikit/iOS/integrate_only_tuichat_iOS.md +0 -748
- package/resource/doc/chatuikit/iOS/quick_start_iOS.md +0 -163
- package/resource/doc/chatuikit/iOS/show_typing_iOS.md +0 -52
- package/tools/definitions/get_native_live_extra_features_def.js.map +0 -1
- package/tools/definitions/get_native_live_interaction_def.js.map +0 -1
- package/tools/live/get_native_live_extra_features.js.map +0 -1
- package/tools/live/get_native_live_interaction.js.map +0 -1
- /package/resource/doc/chatuikit/android/{integrate_tuikit_Android.md → integration.md} +0 -0
- /package/resource/doc/chatuikit/{faq/native_sdk/faq.md → android/workflow.md} +0 -0
- /package/resource/doc/chatuikit/{flutter/client_api_Flutter.md → faq/flutter_sdk/client-api.md} +0 -0
- /package/resource/doc/chatuikit/iOS/{integrate_tuikit_iOS.md → integration.md} +0 -0
- /package/resource/doc/chatuikit/react/components/{chatheader.md → chat-header.md} +0 -0
- /package/resource/doc/chatuikit/vue/components/{chatheader.md → chat-header.md} +0 -0
|
@@ -0,0 +1,783 @@
|
|
|
1
|
+
`GiftStore` is a dedicated module within **AtomicXCore** for managing live room gifting features. It enables you to build a complete gifting system for your live streaming application, supporting robust monetization and interactive experiences.
|
|
2
|
+
<table>
|
|
3
|
+
<tr>
|
|
4
|
+
<td rowspan="1" colSpan="1" >**Gift Panel**</td>
|
|
5
|
+
|
|
6
|
+
<td rowspan="1" colSpan="1" >**Barrage Gift**</td>
|
|
7
|
+
|
|
8
|
+
<td rowspan="1" colSpan="1" >**Full-Screen Gift**</td>
|
|
9
|
+
</tr>
|
|
10
|
+
|
|
11
|
+
<tr>
|
|
12
|
+
<td rowspan="1" colSpan="1" ></td>
|
|
13
|
+
|
|
14
|
+
<td rowspan="1" colSpan="1" ></td>
|
|
15
|
+
|
|
16
|
+
<td rowspan="1" colSpan="1" ></td>
|
|
17
|
+
</tr>
|
|
18
|
+
</table>
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Core Features
|
|
22
|
+
- **Gift List Retrieval**: Retrieve gift panel data from the server, including gift categories and details.
|
|
23
|
+
|
|
24
|
+
- **Send Gift**: Viewers can send virtual gifts to the host.
|
|
25
|
+
|
|
26
|
+
- **Gift Event Broadcasting:** Real-time synchronization of gift events across all clients in the room to trigger animations and barrage notifications.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## Core Concepts
|
|
30
|
+
<table>
|
|
31
|
+
<tr>
|
|
32
|
+
<td rowspan="1" colSpan="1" >**Core Concept**</td>
|
|
33
|
+
|
|
34
|
+
<td rowspan="1" colSpan="1" >**Type**</td>
|
|
35
|
+
|
|
36
|
+
<td rowspan="1" colSpan="1" >**Core Responsibilities & Description**</td>
|
|
37
|
+
</tr>
|
|
38
|
+
|
|
39
|
+
<tr>
|
|
40
|
+
<td rowspan="1" colSpan="1" >`Gift`</td>
|
|
41
|
+
|
|
42
|
+
<td rowspan="1" colSpan="1" >`struct`</td>
|
|
43
|
+
|
|
44
|
+
<td rowspan="1" colSpan="1" >Represents a gift data model, including ID, name, icon URL, animation resource URL (resourceURL), price (coins), and more.</td>
|
|
45
|
+
</tr>
|
|
46
|
+
|
|
47
|
+
<tr>
|
|
48
|
+
<td rowspan="1" colSpan="1" >`GiftCategory`</td>
|
|
49
|
+
|
|
50
|
+
<td rowspan="1" colSpan="1" >`struct`</td>
|
|
51
|
+
|
|
52
|
+
<td rowspan="1" colSpan="1" >- Represents a grouping of gifts (e.g., "Popular", "Luxury"). <br>- Contains a category name and an array of Gift objects.</td>
|
|
53
|
+
</tr>
|
|
54
|
+
|
|
55
|
+
<tr>
|
|
56
|
+
<td rowspan="1" colSpan="1" >`GiftState`</td>
|
|
57
|
+
|
|
58
|
+
<td rowspan="1" colSpan="1" >`struct`</td>
|
|
59
|
+
|
|
60
|
+
<td rowspan="1" colSpan="1" >- Represents the current state of the gift module. <br>- The core property, usableGifts, is a StateFlow containing the full gift list from the server.</td>
|
|
61
|
+
</tr>
|
|
62
|
+
|
|
63
|
+
<tr>
|
|
64
|
+
<td rowspan="1" colSpan="1" >`GiftEvent`</td>
|
|
65
|
+
|
|
66
|
+
<td rowspan="1" colSpan="1" >`enum`</td>
|
|
67
|
+
|
|
68
|
+
<td rowspan="1" colSpan="1" >Defines the event listener for gift events in the live room. Currently, only `onReceiveGift` is available. This event is broadcast to all users in the room (including the sender) whenever a gift is successfully sent.</td>
|
|
69
|
+
</tr>
|
|
70
|
+
|
|
71
|
+
<tr>
|
|
72
|
+
<td rowspan="1" colSpan="1" >`GiftStore`</td>
|
|
73
|
+
|
|
74
|
+
<td rowspan="1" colSpan="1" >`class`</td>
|
|
75
|
+
|
|
76
|
+
<td rowspan="1" colSpan="1" >- The core management class for gift features. <br>- Used to fetch gift lists, execute send requests, and listen for global gift events.</td>
|
|
77
|
+
</tr>
|
|
78
|
+
</table>
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## Implementation
|
|
82
|
+
|
|
83
|
+
### Step 1: Component Integration
|
|
84
|
+
|
|
85
|
+
> **Note:**
|
|
86
|
+
>
|
|
87
|
+
|
|
88
|
+
> To use the gifting system, activate either the **Free Trial,** or **Pro **edition. The number of configurable gifts depends on the selected package. For details, see the **Gift System** section in [Feature and Billing Description](https://write.woa.com/document/137771241658241024) and choose the package that fits your needs.
|
|
89
|
+
>
|
|
90
|
+
|
|
91
|
+
- **Video Live Streaming**: Please refer to [Quick Start](https://write.woa.com/document/194571606121816064) to integrate AtomicXCore.
|
|
92
|
+
|
|
93
|
+
- **Voice Chat Room**: Please refer to [Quick Start](https://write.woa.com/document/194571595685527552) to integrate AtomicXCore.
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
### Step 2: Initialize and Listen for Gift Events
|
|
97
|
+
|
|
98
|
+
Obtain a `GiftStore` instance and set up subscribers to receive gift events and gift list updates.
|
|
99
|
+
|
|
100
|
+
#### Implementation
|
|
101
|
+
1. **Get Instance**: Call `GiftStore.create(liveID:)` to obtain a `GiftStore` instance bound to the current live room.
|
|
102
|
+
|
|
103
|
+
2. **Subscribe to Events**: Subscribe to `giftStore.giftEventPublisher` to receive `.onReceiveGift` events.
|
|
104
|
+
|
|
105
|
+
3. **Subscribe to State**: Subscribe to `giftStore.state` to obtain the `usableGifts` gift list.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
#### Code Example
|
|
109
|
+
``` swift
|
|
110
|
+
import Foundation
|
|
111
|
+
import AtomicXCore
|
|
112
|
+
import Combine
|
|
113
|
+
|
|
114
|
+
class GiftManager {
|
|
115
|
+
private let liveId: String
|
|
116
|
+
private let giftStore: GiftStore
|
|
117
|
+
private var cancellables = Set<AnyCancellable>()
|
|
118
|
+
|
|
119
|
+
// Expose gift events for the UI layer to subscribe and trigger animations
|
|
120
|
+
let giftEventPublisher = PassthroughSubject<GiftEvent, Never>()
|
|
121
|
+
// Expose gift list externally
|
|
122
|
+
let giftListPublisher = CurrentValueSubject<[GiftCategory], Never>([])
|
|
123
|
+
|
|
124
|
+
init(liveId: String) {
|
|
125
|
+
self.liveId = liveId
|
|
126
|
+
// 1. Obtain GiftStore instance using liveId
|
|
127
|
+
self.giftStore = GiftStore.create(liveID: liveId)
|
|
128
|
+
|
|
129
|
+
subscribeToGiftState()
|
|
130
|
+
subscribeToGiftEvents()
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/// 2. Subscribe to gift events
|
|
134
|
+
private func subscribeToGiftEvents() {
|
|
135
|
+
giftStore.giftEventPublisher
|
|
136
|
+
.receive(on: DispatchQueue.main)
|
|
137
|
+
.sink { [weak self] event in
|
|
138
|
+
// Forward the event to the UI layer for handling
|
|
139
|
+
self?.giftEventPublisher.send(event)
|
|
140
|
+
}
|
|
141
|
+
.store(in: &cancellables)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/// 3. Subscribe to gift list state
|
|
145
|
+
private func subscribeToGiftState() {
|
|
146
|
+
giftStore.state
|
|
147
|
+
.subscribe(StatePublisherSelector(keyPath: \GiftState.usableGifts))
|
|
148
|
+
.receive(on: DispatchQueue.main)
|
|
149
|
+
.assign(to: \.value, on: giftListPublisher)
|
|
150
|
+
.store(in: &cancellables)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### Gift List Struct Parameters
|
|
156
|
+
- **GiftCategory Parameter Description**
|
|
157
|
+
|
|
158
|
+
<table>
|
|
159
|
+
<tr>
|
|
160
|
+
<td rowspan="1" colSpan="1" >**Parameter**</td>
|
|
161
|
+
|
|
162
|
+
<td rowspan="1" colSpan="1" >**Type**</td>
|
|
163
|
+
|
|
164
|
+
<td rowspan="1" colSpan="1" >**Description**</td>
|
|
165
|
+
</tr>
|
|
166
|
+
|
|
167
|
+
<tr>
|
|
168
|
+
<td rowspan="1" colSpan="1" >`categoryID`</td>
|
|
169
|
+
|
|
170
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
171
|
+
|
|
172
|
+
<td rowspan="1" colSpan="1" >Unique ID of the gift category.</td>
|
|
173
|
+
</tr>
|
|
174
|
+
|
|
175
|
+
<tr>
|
|
176
|
+
<td rowspan="1" colSpan="1" >`name`</td>
|
|
177
|
+
|
|
178
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
179
|
+
|
|
180
|
+
<td rowspan="1" colSpan="1" >Display name of the gift category.</td>
|
|
181
|
+
</tr>
|
|
182
|
+
|
|
183
|
+
<tr>
|
|
184
|
+
<td rowspan="1" colSpan="1" >`desc`</td>
|
|
185
|
+
|
|
186
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
187
|
+
|
|
188
|
+
<td rowspan="1" colSpan="1" >Description of the gift category.</td>
|
|
189
|
+
</tr>
|
|
190
|
+
|
|
191
|
+
<tr>
|
|
192
|
+
<td rowspan="1" colSpan="1" >`extensionInfo`</td>
|
|
193
|
+
|
|
194
|
+
<td rowspan="1" colSpan="1" >`[String: String]`</td>
|
|
195
|
+
|
|
196
|
+
<td rowspan="1" colSpan="1" >Extension information field.</td>
|
|
197
|
+
</tr>
|
|
198
|
+
|
|
199
|
+
<tr>
|
|
200
|
+
<td rowspan="1" colSpan="1" >`giftList`</td>
|
|
201
|
+
|
|
202
|
+
<td rowspan="1" colSpan="1" >`[`[Gift](https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore/gift)`]`</td>
|
|
203
|
+
|
|
204
|
+
<td rowspan="1" colSpan="1" >Array of Gift objects contained in this category.</td>
|
|
205
|
+
</tr>
|
|
206
|
+
</table>
|
|
207
|
+
|
|
208
|
+
- **Gift Parameter Description**
|
|
209
|
+
|
|
210
|
+
<table>
|
|
211
|
+
<tr>
|
|
212
|
+
<td rowspan="1" colSpan="1" >**Parameter**</td>
|
|
213
|
+
|
|
214
|
+
<td rowspan="1" colSpan="1" >**Type**</td>
|
|
215
|
+
|
|
216
|
+
<td rowspan="1" colSpan="1" >**Description**</td>
|
|
217
|
+
</tr>
|
|
218
|
+
|
|
219
|
+
<tr>
|
|
220
|
+
<td rowspan="1" colSpan="1" >`giftID`</td>
|
|
221
|
+
|
|
222
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
223
|
+
|
|
224
|
+
<td rowspan="1" colSpan="1" >Unique ID of the gift.</td>
|
|
225
|
+
</tr>
|
|
226
|
+
|
|
227
|
+
<tr>
|
|
228
|
+
<td rowspan="1" colSpan="1" >`name`</td>
|
|
229
|
+
|
|
230
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
231
|
+
|
|
232
|
+
<td rowspan="1" colSpan="1" >Display name of the gift.</td>
|
|
233
|
+
</tr>
|
|
234
|
+
|
|
235
|
+
<tr>
|
|
236
|
+
<td rowspan="1" colSpan="1" >`desc`</td>
|
|
237
|
+
|
|
238
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
239
|
+
|
|
240
|
+
<td rowspan="1" colSpan="1" >Description of the gift.</td>
|
|
241
|
+
</tr>
|
|
242
|
+
|
|
243
|
+
<tr>
|
|
244
|
+
<td rowspan="1" colSpan="1" >`iconURL`</td>
|
|
245
|
+
|
|
246
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
247
|
+
|
|
248
|
+
<td rowspan="1" colSpan="1" >Gift icon URL.</td>
|
|
249
|
+
</tr>
|
|
250
|
+
|
|
251
|
+
<tr>
|
|
252
|
+
<td rowspan="1" colSpan="1" >`resourceURL`</td>
|
|
253
|
+
|
|
254
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
255
|
+
|
|
256
|
+
<td rowspan="1" colSpan="1" >Gift animation resource URL.</td>
|
|
257
|
+
</tr>
|
|
258
|
+
|
|
259
|
+
<tr>
|
|
260
|
+
<td rowspan="1" colSpan="1" >`level`</td>
|
|
261
|
+
|
|
262
|
+
<td rowspan="1" colSpan="1" >`UInt`</td>
|
|
263
|
+
|
|
264
|
+
<td rowspan="1" colSpan="1" >Gift level.</td>
|
|
265
|
+
</tr>
|
|
266
|
+
|
|
267
|
+
<tr>
|
|
268
|
+
<td rowspan="1" colSpan="1" >`coins`</td>
|
|
269
|
+
|
|
270
|
+
<td rowspan="1" colSpan="1" >`UInt`</td>
|
|
271
|
+
|
|
272
|
+
<td rowspan="1" colSpan="1" >Gift price.</td>
|
|
273
|
+
</tr>
|
|
274
|
+
|
|
275
|
+
<tr>
|
|
276
|
+
<td rowspan="1" colSpan="1" >`extensionInfo`</td>
|
|
277
|
+
|
|
278
|
+
<td rowspan="1" colSpan="1" >`[String: String]`</td>
|
|
279
|
+
|
|
280
|
+
<td rowspan="1" colSpan="1" >Extension information field.</td>
|
|
281
|
+
</tr>
|
|
282
|
+
</table>
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
### Step 3: Retrieve Gift List
|
|
286
|
+
|
|
287
|
+
Call the `refreshUsableGifts` method to fetch gift data from the server.
|
|
288
|
+
|
|
289
|
+
#### Implementation
|
|
290
|
+
1. **Call API**: Call `giftStore.refreshUsableGifts` (typically after entering the room).
|
|
291
|
+
|
|
292
|
+
2. **Handle Callback**: Handle the completion block for error checking.
|
|
293
|
+
|
|
294
|
+
3. **Receive Data**: Upon success, the data flows automatically through the giftListPublisher set up in [Step 2](https://write.woa.com/#634828fc-7b2c-4a61-9140-60efc5246431).
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
#### Code Example
|
|
298
|
+
``` swift
|
|
299
|
+
extension GiftManager {
|
|
300
|
+
/// Refresh the gift list from the server
|
|
301
|
+
func fetchGiftList() {
|
|
302
|
+
giftStore.refreshUsableGifts { result in
|
|
303
|
+
switch result {
|
|
304
|
+
case .success:
|
|
305
|
+
print("Gift list fetched successfully")
|
|
306
|
+
// On success, data is automatically updated via the state subscription
|
|
307
|
+
case .failure(let error):
|
|
308
|
+
print("Failed to fetch gift list: \(error.localizedDescription)")
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Step 4: Send Gift
|
|
316
|
+
|
|
317
|
+
Trigger the sending logic when a user interacts with the gift panel.
|
|
318
|
+
|
|
319
|
+
#### Implementation
|
|
320
|
+
1. **Prepare Data**: Retrieve the selected `giftID` and quantity (`count`) from your UI.
|
|
321
|
+
|
|
322
|
+
2. **Call API**: Call `giftStore.sendGift(giftID:count:completion:)`.
|
|
323
|
+
|
|
324
|
+
3. **Handle Result**: Use the completion block only to handle failures (e.g., balance errors). Successful sends are handled via the global `.onReceiveGift` event listener to ensure consistency.
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
#### Code Example
|
|
328
|
+
``` swift
|
|
329
|
+
extension GiftManager {
|
|
330
|
+
/// User sends a gift
|
|
331
|
+
func sendGift(giftID: String, count: UInt) {
|
|
332
|
+
giftStore.sendGift(giftID: giftID, count: count) { result in
|
|
333
|
+
switch result {
|
|
334
|
+
case .success:
|
|
335
|
+
print("Gift \(giftID) sent successfully")
|
|
336
|
+
// After a successful send, everyone in the room, including the sender, will receive the onReceiveGift event
|
|
337
|
+
case .failure(let error):
|
|
338
|
+
print("Failed to send gift: \(error.localizedDescription)")
|
|
339
|
+
// Prompt the user, e.g., "Insufficient balance" or "Network error"
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
#### sendGift API Parameters
|
|
347
|
+
<table>
|
|
348
|
+
<tr>
|
|
349
|
+
<td rowspan="1" colSpan="1" >**Parameter Name**</td>
|
|
350
|
+
|
|
351
|
+
<td rowspan="1" colSpan="1" >**Type**</td>
|
|
352
|
+
|
|
353
|
+
<td rowspan="1" colSpan="1" >**Description**</td>
|
|
354
|
+
</tr>
|
|
355
|
+
|
|
356
|
+
<tr>
|
|
357
|
+
<td rowspan="1" colSpan="1" >`giftID`</td>
|
|
358
|
+
|
|
359
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
360
|
+
|
|
361
|
+
<td rowspan="1" colSpan="1" >The unique ID of the gift to send.</td>
|
|
362
|
+
</tr>
|
|
363
|
+
|
|
364
|
+
<tr>
|
|
365
|
+
<td rowspan="1" colSpan="1" >`count`</td>
|
|
366
|
+
|
|
367
|
+
<td rowspan="1" colSpan="1" >`UInt`</td>
|
|
368
|
+
|
|
369
|
+
<td rowspan="1" colSpan="1" >The number of gifts to send.</td>
|
|
370
|
+
</tr>
|
|
371
|
+
|
|
372
|
+
<tr>
|
|
373
|
+
<td rowspan="1" colSpan="1" >`completion`</td>
|
|
374
|
+
|
|
375
|
+
<td rowspan="1" colSpan="1" >`CompletionClosure?`</td>
|
|
376
|
+
|
|
377
|
+
<td rowspan="1" colSpan="1" >Callback after sending is complete.</td>
|
|
378
|
+
</tr>
|
|
379
|
+
</table>
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
## Advanced Features
|
|
383
|
+
|
|
384
|
+
The `GiftStore` module is designed to work seamlessly with your backend infrastructure. This section outlines how to configure assets and integrate advanced playback features.
|
|
385
|
+
|
|
386
|
+
### Gift Asset Configuration
|
|
387
|
+
|
|
388
|
+
You can fully customize your gift inventory (names, icons, prices, animations) to match your branding.
|
|
389
|
+
|
|
390
|
+
#### Implementation
|
|
391
|
+
1. **Server-Side Configuration**: Use the LiveKit server REST API to manage gift information, categories, and multi-language support. See the [Gift Configuration Guide](https://write.woa.com/document/185130564680273920).
|
|
392
|
+
|
|
393
|
+
2. **Client Fetch**: On the client, call `refreshUsableGifts` to retrieve configuration data.
|
|
394
|
+
|
|
395
|
+
3. **UI Display**: Use the retrieved `List<GiftCategory>` to render the gift panel.
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
#### Configuration Sequence Diagram
|
|
399
|
+
|
|
400
|
+

|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
#### Related REST API Interfaces Overview
|
|
404
|
+
<table>
|
|
405
|
+
<tr>
|
|
406
|
+
<td rowspan="1" colSpan="1" >**Interface Category**</td>
|
|
407
|
+
|
|
408
|
+
<td rowspan="1" colSpan="1" >**Interface**</td>
|
|
409
|
+
|
|
410
|
+
<td rowspan="1" colSpan="1" >**Request Example**</td>
|
|
411
|
+
</tr>
|
|
412
|
+
|
|
413
|
+
<tr>
|
|
414
|
+
<td rowspan="3" colSpan="1" >**Gift Management**</td>
|
|
415
|
+
|
|
416
|
+
<td rowspan="1" colSpan="1" >Add Gift Information</td>
|
|
417
|
+
|
|
418
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185130814885187584)</td>
|
|
419
|
+
</tr>
|
|
420
|
+
|
|
421
|
+
<tr>
|
|
422
|
+
<td rowspan="1" colSpan="1" >Delete Gift Information</td>
|
|
423
|
+
|
|
424
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131021432451072)</td>
|
|
425
|
+
</tr>
|
|
426
|
+
|
|
427
|
+
<tr>
|
|
428
|
+
<td rowspan="1" colSpan="1" >Query Gift Information</td>
|
|
429
|
+
|
|
430
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185130925608591360)</td>
|
|
431
|
+
</tr>
|
|
432
|
+
|
|
433
|
+
<tr>
|
|
434
|
+
<td rowspan="3" colSpan="1" >**Gift Category Management**</td>
|
|
435
|
+
|
|
436
|
+
<td rowspan="1" colSpan="1" >Add Gift Category Information</td>
|
|
437
|
+
|
|
438
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131054187974656)</td>
|
|
439
|
+
</tr>
|
|
440
|
+
|
|
441
|
+
<tr>
|
|
442
|
+
<td rowspan="1" colSpan="1" >Delete Specific Gift Category Information</td>
|
|
443
|
+
|
|
444
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131288984932352)</td>
|
|
445
|
+
</tr>
|
|
446
|
+
|
|
447
|
+
<tr>
|
|
448
|
+
<td rowspan="1" colSpan="1" >Get Specific Gift Category Information</td>
|
|
449
|
+
|
|
450
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131164168736768)</td>
|
|
451
|
+
</tr>
|
|
452
|
+
|
|
453
|
+
<tr>
|
|
454
|
+
<td rowspan="3" colSpan="1" >**Gift Relationship Management**</td>
|
|
455
|
+
|
|
456
|
+
<td rowspan="1" colSpan="1" >Add Relationship between a Specific Gift Category and Gift</td>
|
|
457
|
+
|
|
458
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131388068356096)</td>
|
|
459
|
+
</tr>
|
|
460
|
+
|
|
461
|
+
<tr>
|
|
462
|
+
<td rowspan="1" colSpan="1" >Delete Relationship between a Specific Gift Category and Gift</td>
|
|
463
|
+
|
|
464
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131491225227264)</td>
|
|
465
|
+
</tr>
|
|
466
|
+
|
|
467
|
+
<tr>
|
|
468
|
+
<td rowspan="1" colSpan="1" >Get Gift Relationships under a Specific Gift Category</td>
|
|
469
|
+
|
|
470
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131634710056960)</td>
|
|
471
|
+
</tr>
|
|
472
|
+
|
|
473
|
+
<tr>
|
|
474
|
+
<td rowspan="6" colSpan="1" >**Gift Multi-language Management**</td>
|
|
475
|
+
|
|
476
|
+
<td rowspan="1" colSpan="1" >Add Gift Multi-language Information</td>
|
|
477
|
+
|
|
478
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131766094020608)</td>
|
|
479
|
+
</tr>
|
|
480
|
+
|
|
481
|
+
<tr>
|
|
482
|
+
<td rowspan="1" colSpan="1" >Delete Specific Gift Multi-language Information</td>
|
|
483
|
+
|
|
484
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185132041665441792)</td>
|
|
485
|
+
</tr>
|
|
486
|
+
|
|
487
|
+
<tr>
|
|
488
|
+
<td rowspan="1" colSpan="1" >Get Gift Multi-language Information</td>
|
|
489
|
+
|
|
490
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131910582956032)</td>
|
|
491
|
+
</tr>
|
|
492
|
+
|
|
493
|
+
<tr>
|
|
494
|
+
<td rowspan="1" colSpan="1" >Add Gift Category Multi-language Information</td>
|
|
495
|
+
|
|
496
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185132145524985856)</td>
|
|
497
|
+
</tr>
|
|
498
|
+
|
|
499
|
+
<tr>
|
|
500
|
+
<td rowspan="1" colSpan="1" >Delete Specific Gift Category Multi-language Information</td>
|
|
501
|
+
|
|
502
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185132396568891392)</td>
|
|
503
|
+
</tr>
|
|
504
|
+
|
|
505
|
+
<tr>
|
|
506
|
+
<td rowspan="1" colSpan="1" >Get Gift Category Multi-language Information</td>
|
|
507
|
+
|
|
508
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185132283123777536)</td>
|
|
509
|
+
</tr>
|
|
510
|
+
</table>
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
### Billing and Gift Deduction Process
|
|
514
|
+
|
|
515
|
+
AtomicXCore delegates the billing logic to your backend to ensure security and flexibility.
|
|
516
|
+
|
|
517
|
+
#### Workflow
|
|
518
|
+
1. **Backend Callback Configuration**: Configure your billing system's callback URL in the LiveKit backend. See [Callback Configuration Documentation](https://write.woa.com/document/155612057789870080).
|
|
519
|
+
|
|
520
|
+
2. **Client Request**: The client calls `sendGift`.
|
|
521
|
+
|
|
522
|
+
3. **Backend Verification**: The LiveKit backend calls your callback URL; your billing system processes the deduction and returns the result.
|
|
523
|
+
|
|
524
|
+
4. **Result Synchronization**: If succeeds, **AtomicXCore** broadcasts the `onReceiveGift` event; if fails, the completion callback of `sendGift` receives an error.
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
#### Call Flow
|
|
528
|
+
|
|
529
|
+

|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
#### Related REST API Interfaces Overview
|
|
533
|
+
<table>
|
|
534
|
+
<tr>
|
|
535
|
+
<td rowspan="1" colSpan="1" >**Interface**</td>
|
|
536
|
+
|
|
537
|
+
<td rowspan="1" colSpan="1" >**Description**</td>
|
|
538
|
+
|
|
539
|
+
<td rowspan="1" colSpan="1" >**Request Example**</td>
|
|
540
|
+
</tr>
|
|
541
|
+
|
|
542
|
+
<tr>
|
|
543
|
+
<td rowspan="1" colSpan="1" >**Callback Configuration - Callback before sending a gift**</td>
|
|
544
|
+
|
|
545
|
+
<td rowspan="1" colSpan="1" >Pre-gifting validation hook. <br>Allows your backend to intercept gift requests to perform necessary checks (e.g., sufficient balance, risk control) before the gift is processed.</td>
|
|
546
|
+
|
|
547
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/183772991768039424)</td>
|
|
548
|
+
</tr>
|
|
549
|
+
</table>
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
### Full-Screen Animation (SVGA Integration)
|
|
553
|
+
|
|
554
|
+
When a user sends a luxury gift (e.g., "Rocket", "Carnival"), play a full-screen animation (such as SVGA) to enhance engagement.
|
|
555
|
+
|
|
556
|
+
#### Implementation
|
|
557
|
+
|
|
558
|
+
**AtomicXCore** does not include a built-in gift animation player. Integrate a third-party library based on your requirements. Below is a comparison of two options:
|
|
559
|
+
<table>
|
|
560
|
+
<tr>
|
|
561
|
+
<td rowspan="1" colSpan="1" >**Comparison Item**</td>
|
|
562
|
+
|
|
563
|
+
<td rowspan="1" colSpan="1" >**Basic Solution (SVGAPlayer)**</td>
|
|
564
|
+
|
|
565
|
+
<td rowspan="1" colSpan="1" >**Gift AR (TCEffectPlayerKit)**</td>
|
|
566
|
+
</tr>
|
|
567
|
+
|
|
568
|
+
<tr>
|
|
569
|
+
<td rowspan="1" colSpan="1" >Billing</td>
|
|
570
|
+
|
|
571
|
+
<td rowspan="1" colSpan="1" >Free (open source)</td>
|
|
572
|
+
|
|
573
|
+
<td rowspan="1" colSpan="1" >Paid (License Required). See [Billing Guide](https://trtc.io/document/69949?product=beautyar&menulabel=core%20sdk&platform=android#X-Series-Capabilities)</td>
|
|
574
|
+
</tr>
|
|
575
|
+
|
|
576
|
+
<tr>
|
|
577
|
+
<td rowspan="1" colSpan="1" >Integration Method</td>
|
|
578
|
+
|
|
579
|
+
<td rowspan="1" colSpan="1" >Manual integration via Gradle</td>
|
|
580
|
+
|
|
581
|
+
<td rowspan="1" colSpan="1" >Requires additional integration and authentication</td>
|
|
582
|
+
</tr>
|
|
583
|
+
|
|
584
|
+
<tr>
|
|
585
|
+
<td rowspan="1" colSpan="1" > Formats</td>
|
|
586
|
+
|
|
587
|
+
<td rowspan="1" colSpan="1" >SVGA only</td>
|
|
588
|
+
|
|
589
|
+
<td rowspan="1" colSpan="1" >SVGA, PAG, WebP, Lottie, MP4, and more</td>
|
|
590
|
+
</tr>
|
|
591
|
+
|
|
592
|
+
<tr>
|
|
593
|
+
<td rowspan="1" colSpan="1" >Performance</td>
|
|
594
|
+
|
|
595
|
+
<td rowspan="1" colSpan="1" >Good for files < 10MB</td>
|
|
596
|
+
|
|
597
|
+
<td rowspan="1" colSpan="1" >Optimized for large assets & complex layering</td>
|
|
598
|
+
</tr>
|
|
599
|
+
|
|
600
|
+
<tr>
|
|
601
|
+
<td rowspan="1" colSpan="1" >Recommended Scenario</td>
|
|
602
|
+
|
|
603
|
+
<td rowspan="1" colSpan="1" >Uniform SVGA format, controllable file size</td>
|
|
604
|
+
|
|
605
|
+
<td rowspan="1" colSpan="1" >Multiple formats or higher performance/device compatibility needs</td>
|
|
606
|
+
</tr>
|
|
607
|
+
</table>
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
This section demonstrates the basic solution. For the **Gift AR**, see the [TCEffectPlayer Integration Guide](https://trtc.io/document/70537?product=beautyar&menulabel=core%20sdk&platform=ios).
|
|
611
|
+
|
|
612
|
+
#### Basic Solution Implementation: Using SVGAPlayer
|
|
613
|
+
1. **Integrate SVGAPlayer**: In your `Podfile`, add the dependency for `SVGAPlayer` and run `pod install` in the terminal.
|
|
614
|
+
|
|
615
|
+
``` ruby
|
|
616
|
+
target 'YourApp' do
|
|
617
|
+
# ... other pods
|
|
618
|
+
pod 'SVGAPlayer'
|
|
619
|
+
end
|
|
620
|
+
```
|
|
621
|
+
2. **Listen for Gift Events**: Subscribe to GiftStore's `giftEventPublisher`.
|
|
622
|
+
|
|
623
|
+
3. **Parse and Play**: When receiving an `.onReceiveGift` event, check if `gift.resourceURL` is valid and points to an SVGA file. If so, use `SVGAParser` to parse the URL and pass the parsed `SVGAVideoEntity` to the `SVGAPlayer` instance for playback.
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
#### Code Example
|
|
627
|
+
``` swift
|
|
628
|
+
import UIKit
|
|
629
|
+
import AtomicXCore
|
|
630
|
+
import Combine
|
|
631
|
+
import SVGAPlayer // 1. Import
|
|
632
|
+
|
|
633
|
+
class LiveRoomViewController: UIViewController, SVGAPlayerDelegate {
|
|
634
|
+
private var giftManager: GiftManager!
|
|
635
|
+
private var cancellables = Set<AnyCancellable>()
|
|
636
|
+
private let svgaPlayer = SVGAPlayer() // 2. Prepare instance
|
|
637
|
+
private let svgaParser = SVGAParser()
|
|
638
|
+
|
|
639
|
+
override func viewDidLoad() {
|
|
640
|
+
super.viewDidLoad()
|
|
641
|
+
setupSVGAPlayer()
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
private func setupSVGAPlayer() {
|
|
645
|
+
svgaPlayer.delegate = self
|
|
646
|
+
svgaPlayer.loops = 1 // Play once by default
|
|
647
|
+
svgaPlayer.clearsAfterStop = true // Automatically clear after playback
|
|
648
|
+
view.addSubview(svgaPlayer)
|
|
649
|
+
svgaPlayer.frame = view.bounds // Full screen by default
|
|
650
|
+
svgaPlayer.isHidden = true
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
func setupGiftSubscription(liveId: String) {
|
|
654
|
+
self.giftManager = GiftManager(liveId: liveId)
|
|
655
|
+
|
|
656
|
+
giftManager.giftEventPublisher
|
|
657
|
+
.sink { [weak self] event in // 3. Listen for events
|
|
658
|
+
guard case .onReceiveGift(_, let gift, _, _) = event else { return }
|
|
659
|
+
|
|
660
|
+
if !gift.resourceURL.isEmpty, let url = URL(string: gift.resourceURL) { // 4. Parse and play
|
|
661
|
+
self?.playAnimation(from: url)
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
.store(in: &cancellables)
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
private func playAnimation(from url: URL) {
|
|
668
|
+
svgaParser.parse(with: url, completionBlock: { [weak self] videoItem in
|
|
669
|
+
guard let self = self, let videoItem = videoItem else { return }
|
|
670
|
+
DispatchQueue.main.async {
|
|
671
|
+
self.svgaPlayer.videoItem = videoItem
|
|
672
|
+
self.svgaPlayer.isHidden = false
|
|
673
|
+
self.svgaPlayer.startAnimation()
|
|
674
|
+
}
|
|
675
|
+
}, failureBlock: { error in
|
|
676
|
+
print("Failed to parse SVGA animation: \(error?.localizedDescription ?? "unknown error")")
|
|
677
|
+
// Add retry or error reporting logic as needed
|
|
678
|
+
})
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
func svgaPlayerDidFinishedAnimation(_ player: SVGAPlayer!) { /* ... Handle end of playback ... */ }
|
|
682
|
+
}
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
### Display Gift Notifications in Barrage
|
|
686
|
+
|
|
687
|
+
Enhance social interaction by displaying a system notification in the public barrage (chat) area whenever a gift is sent (e.g., "[User] sent [Gift] x [Count]").
|
|
688
|
+
|
|
689
|
+
#### Implementation
|
|
690
|
+
1. **Listen for Events**: Subscribe to `giftStore.giftEventPublisher`.
|
|
691
|
+
|
|
692
|
+
2. **Extract Information**: After receiving the` .onReceiveGift` event, extract the sender, gift, and count.
|
|
693
|
+
|
|
694
|
+
3. **Get Barrage Store**: Use `BarrageStore.create(liveID:)` to get the instance bound to the current room.
|
|
695
|
+
|
|
696
|
+
4. **Compose Message**: Create a `Barrage` struct, set `messageType = .text`, and set `textContent` to the composed string (e.g., "[sender.userName] sent [gift.name] x [count]").
|
|
697
|
+
|
|
698
|
+
5. **Insert Locally**: Call `barrageStore.appendLocalTip(message: giftTip)` to insert the message into the local list.
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
#### Code Example
|
|
702
|
+
``` swift
|
|
703
|
+
// In LiveRoomManager or a similar top-level manager
|
|
704
|
+
private func setupGiftToBarrageFlow() {
|
|
705
|
+
giftStore.giftEventPublisher
|
|
706
|
+
.receive(on: DispatchQueue.main)
|
|
707
|
+
.sink { [weak self] event in // 1. Listen for events
|
|
708
|
+
guard case .onReceiveGift(_, let gift, let count, let sender) = event else { return } // 2. Extract information
|
|
709
|
+
|
|
710
|
+
guard let self = self else { return }
|
|
711
|
+
// 3. Get BarrageStore (assume barrageStore is already initialized)
|
|
712
|
+
|
|
713
|
+
// 4. Compose message
|
|
714
|
+
let tipText = "\(sender.userName) sent \(gift.name) x \(count)"
|
|
715
|
+
var giftTip = Barrage()
|
|
716
|
+
giftTip.messageType = .text
|
|
717
|
+
giftTip.textContent = tipText
|
|
718
|
+
// Optional: set a special sender
|
|
719
|
+
|
|
720
|
+
// 5. Insert locally
|
|
721
|
+
self.barrageStore.appendLocalTip(message: giftTip)
|
|
722
|
+
}
|
|
723
|
+
.store(in: &cancellables)
|
|
724
|
+
}
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
## API Documentation
|
|
728
|
+
|
|
729
|
+
For complete details on all public interfaces, properties, and methods of [GiftStore](https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore/giftstore) and related classes, see the official API documentation for [AtomicXCore](https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore). Key stores referenced in this guide include:
|
|
730
|
+
<table>
|
|
731
|
+
<tr>
|
|
732
|
+
<td rowspan="1" colSpan="1" >**Store/Component**</td>
|
|
733
|
+
|
|
734
|
+
<td rowspan="1" colSpan="1" >**Feature Description**</td>
|
|
735
|
+
|
|
736
|
+
<td rowspan="1" colSpan="1" >**API Documentation**</td>
|
|
737
|
+
</tr>
|
|
738
|
+
|
|
739
|
+
<tr>
|
|
740
|
+
<td rowspan="1" colSpan="1" >GiftStore</td>
|
|
741
|
+
|
|
742
|
+
<td rowspan="1" colSpan="1" >Fetch gift list, send/receive gifts, listen for gift events (including sender and gift details).</td>
|
|
743
|
+
|
|
744
|
+
<td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore/giftstore)</td>
|
|
745
|
+
</tr>
|
|
746
|
+
|
|
747
|
+
<tr>
|
|
748
|
+
<td rowspan="1" colSpan="1" >BarrageStore</td>
|
|
749
|
+
|
|
750
|
+
<td rowspan="1" colSpan="1" >Send text/custom barrage, maintain barrage list, listen to barrage status in real time.</td>
|
|
751
|
+
|
|
752
|
+
<td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore/barragestore)</td>
|
|
753
|
+
</tr>
|
|
754
|
+
</table>
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
## FAQs
|
|
758
|
+
|
|
759
|
+
### The gift list in GiftStore is empty. What should I do?
|
|
760
|
+
|
|
761
|
+
You must call `refreshUsableGifts(completion)` to fetch gift data from your backend. Ensure your backend is configured with gift data via the server REST API.
|
|
762
|
+
|
|
763
|
+
### How do I implement multi-language display for gifts (e.g., Chinese, English)?
|
|
764
|
+
|
|
765
|
+
Use the `GiftStore.setLanguage(language: String)` API before calling `refreshUsableGifts`, passing the target language code (e.g., "en" or "zh-CN"). The server will return gift names and descriptions in the specified language.
|
|
766
|
+
|
|
767
|
+
### I called sendGift, but the gift animation plays twice. Why?
|
|
768
|
+
|
|
769
|
+
The `onReceiveGift` event is broadcast to all room members, including the sender. If you update the UI both in the sendGift completion callback and in the `onReceiveGift` event, the animation will play twice.
|
|
770
|
+
- **Best Practice**: Only update the UI (e.g., play animations, show barrage) in the `onReceiveGift` event handler. Use the `sendGift` completion callback only for handling failures (such as "Send failed" or "Insufficient balance").
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
### Where is the gift deduction logic implemented?
|
|
774
|
+
|
|
775
|
+
Gift deduction is handled entirely by your billing system. AtomicXCore integrates with your billing system via a backend callback. When the client calls `sendGift`, your backend performs the deduction. After returning the result to the AtomicXCore backend, it determines whether to broadcast the gift event.
|
|
776
|
+
|
|
777
|
+
### Will gift notifications be blocked by mute or message frequency controls?
|
|
778
|
+
|
|
779
|
+
No. Gift notifications (`onReceiveGift` events) are not affected by mute or frequency controls and are always delivered reliably.
|
|
780
|
+
|
|
781
|
+
### What should I do if gift animation playback stutters?
|
|
782
|
+
|
|
783
|
+
Check your SVGA file size; the basic player recommends files no larger than 10MB. For large or complex animations, consider integrating the **Gift AR** provided by TUILiveKit for improved performance.
|