cloudx-react-native 3.2.0 → 3.4.4
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/README.md +40 -652
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/cloudxreactnative/CloudXAdInfo.kt +9 -0
- package/android/src/main/java/com/cloudxreactnative/CloudXModuleImpl.kt +262 -0
- package/android/src/newarch/com/cloudxreactnative/CloudXModule.kt +6 -0
- package/android/src/oldarch/com/cloudxreactnative/CloudXModule.kt +7 -0
- package/cloudx-react-native.podspec +1 -1
- package/ios/CloudX.mm +313 -1
- package/lib/commonjs/CloudX.js +5 -1
- package/lib/commonjs/CloudX.js.map +1 -1
- package/lib/commonjs/CloudXBannerAd.js +4 -0
- package/lib/commonjs/CloudXBannerAd.js.map +1 -1
- package/lib/commonjs/CloudXInterstitialAd.js +4 -0
- package/lib/commonjs/CloudXInterstitialAd.js.map +1 -1
- package/lib/commonjs/CloudXMRECAd.js +4 -0
- package/lib/commonjs/CloudXMRECAd.js.map +1 -1
- package/lib/commonjs/CloudXRewardedAd.js +4 -0
- package/lib/commonjs/CloudXRewardedAd.js.map +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/NativeCloudX.js +1 -1
- package/lib/commonjs/specs/NativeCloudX.js.map +1 -1
- package/lib/commonjs/types/Arbiter.js +27 -0
- package/lib/commonjs/types/Arbiter.js.map +1 -0
- package/lib/commonjs/types/ExtraParameters.js +2 -0
- package/lib/commonjs/types/ExtraParameters.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/CloudX.js +5 -1
- package/lib/module/CloudX.js.map +1 -1
- package/lib/module/CloudXBannerAd.js +4 -0
- package/lib/module/CloudXBannerAd.js.map +1 -1
- package/lib/module/CloudXInterstitialAd.js +4 -0
- package/lib/module/CloudXInterstitialAd.js.map +1 -1
- package/lib/module/CloudXMRECAd.js +4 -0
- package/lib/module/CloudXMRECAd.js.map +1 -1
- package/lib/module/CloudXRewardedAd.js +4 -0
- package/lib/module/CloudXRewardedAd.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/NativeCloudX.js +1 -1
- package/lib/module/specs/NativeCloudX.js.map +1 -1
- package/lib/module/types/Arbiter.js +21 -0
- package/lib/module/types/Arbiter.js.map +1 -0
- package/lib/module/types/ExtraParameters.js +2 -0
- package/lib/module/types/ExtraParameters.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/CloudX.d.ts.map +1 -1
- package/lib/typescript/src/CloudXBannerAd.d.ts.map +1 -1
- package/lib/typescript/src/CloudXInterstitialAd.d.ts.map +1 -1
- package/lib/typescript/src/CloudXMRECAd.d.ts.map +1 -1
- package/lib/typescript/src/CloudXRewardedAd.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeCloudX.d.ts +7 -1
- package/lib/typescript/src/specs/NativeCloudX.d.ts.map +1 -1
- package/lib/typescript/src/types/AdInfo.d.ts +2 -0
- package/lib/typescript/src/types/AdInfo.d.ts.map +1 -1
- package/lib/typescript/src/types/Arbiter.d.ts +35 -0
- package/lib/typescript/src/types/Arbiter.d.ts.map +1 -0
- package/lib/typescript/src/types/CloudX.d.ts +3 -0
- package/lib/typescript/src/types/CloudX.d.ts.map +1 -1
- package/lib/typescript/src/types/ExtraParameters.d.ts +7 -0
- package/lib/typescript/src/types/ExtraParameters.d.ts.map +1 -0
- package/lib/typescript/src/types/FullscreenAd.d.ts +3 -0
- package/lib/typescript/src/types/FullscreenAd.d.ts.map +1 -1
- package/lib/typescript/src/types/ViewAd.d.ts +2 -0
- package/lib/typescript/src/types/ViewAd.d.ts.map +1 -1
- package/lib/typescript/src/types/index.d.ts +2 -0
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +3 -1
- package/src/CloudX.ts +6 -0
- package/src/CloudXBannerAd.ts +6 -0
- package/src/CloudXInterstitialAd.ts +6 -0
- package/src/CloudXMRECAd.ts +6 -0
- package/src/CloudXRewardedAd.ts +6 -0
- package/src/index.ts +9 -0
- package/src/specs/NativeCloudX.ts +12 -1
- package/src/types/AdInfo.ts +3 -0
- package/src/types/Arbiter.ts +62 -0
- package/src/types/CloudX.ts +4 -0
- package/src/types/ExtraParameters.ts +11 -0
- package/src/types/FullscreenAd.ts +4 -0
- package/src/types/ViewAd.ts +2 -0
- package/src/types/index.ts +10 -0
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -1,680 +1,68 @@
|
|
|
1
1
|
# CloudX React Native SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React Native wrapper for the CloudX SDK.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Full integration docs live in the public docs site. Keep setup guides, ad-format examples, native adapter setup, and public release notes there instead of duplicating them in this repository.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Public Documentation
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- **App Tracking Transparency**: Built-in ATT support for iOS 14+
|
|
16
|
-
- **Type Safety**: Full TypeScript definitions with CloudX-prefixed namespace
|
|
9
|
+
- [React Native integration guide](https://docs.cloudx.io/en/react-native/integration)
|
|
10
|
+
- Ad format guides:
|
|
11
|
+
- [Banner and MREC ads](https://docs.cloudx.io/en/react-native/ad-formats/banner-mrec)
|
|
12
|
+
- [Interstitial ads](https://docs.cloudx.io/en/react-native/ad-formats/interstitial)
|
|
13
|
+
- [Rewarded ads](https://docs.cloudx.io/en/react-native/ad-formats/rewarded)
|
|
14
|
+
- [React Native changelog](https://docs.cloudx.io/en/react-native/changelog)
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
When customer-facing behavior changes, update the docs repo directly and link the docs PR from the SDK or release PR.
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|--------|-------------------|---------------------------|
|
|
22
|
-
| 3.2.0 | 3.2.0 | 3.2.0 |
|
|
23
|
-
| 3.1.2 | 3.1.0 | 3.1.0 |
|
|
24
|
-
| 2.2.3 | 2.2.3 | 2.2.3 |
|
|
18
|
+
## Repository Layout
|
|
25
19
|
|
|
26
|
-
|
|
20
|
+
- `src/` - JavaScript and TypeScript API surface consumed by React Native apps.
|
|
21
|
+
- `ios/` - iOS native bridge over `CloudXCore`.
|
|
22
|
+
- `android/` - Android native bridge over `io.cloudx:sdk`.
|
|
23
|
+
- `demo-app/` - React Native demo app for manual and automated validation.
|
|
24
|
+
- `cloudx-react-native.podspec` - CocoaPods package metadata.
|
|
25
|
+
- `RELEASE.md` - Internal release process.
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
## Development
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
npm install cloudx-react-native
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### iOS Setup
|
|
35
|
-
|
|
36
|
-
Add ad network adapter pods to your `ios/Podfile`:
|
|
37
|
-
|
|
38
|
-
```ruby
|
|
39
|
-
target 'YourApp' do
|
|
40
|
-
# ... existing config ...
|
|
41
|
-
|
|
42
|
-
# CloudX ad network adapters (add as needed)
|
|
43
|
-
pod 'CloudXMetaAdapter', '~> 3.2.0'
|
|
44
|
-
pod 'CloudXVungleAdapter', '~> 3.2.0'
|
|
45
|
-
pod 'CloudXInMobiAdapter', '~> 3.2.0'
|
|
46
|
-
pod 'CloudXMintegralAdapter', '~> 3.2.0'
|
|
47
|
-
pod 'CloudXUnityAdsAdapter', '~> 3.2.0'
|
|
48
|
-
pod 'CloudXMagniteAdapter', '~> 3.2.0'
|
|
49
|
-
pod 'CloudXRenderer', '~> 3.2.0'
|
|
50
|
-
end
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Then install pods:
|
|
29
|
+
Install dependencies:
|
|
54
30
|
|
|
55
31
|
```bash
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
> **Note:** The `CloudXCore` pod is automatically included as a dependency of the `cloudx-react-native` npm package. You only need to add the adapter pods you want.
|
|
60
|
-
|
|
61
|
-
#### App Transport Security
|
|
62
|
-
|
|
63
|
-
If your ads use HTTP URLs, add the following to your `Info.plist`:
|
|
64
|
-
|
|
65
|
-
```xml
|
|
66
|
-
<key>NSAppTransportSecurity</key>
|
|
67
|
-
<dict>
|
|
68
|
-
<key>NSAllowsArbitraryLoads</key>
|
|
69
|
-
<true/>
|
|
70
|
-
</dict>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Android Setup
|
|
74
|
-
|
|
75
|
-
Add CloudX SDK and adapter dependencies to your `android/app/build.gradle`:
|
|
76
|
-
|
|
77
|
-
```kotlin
|
|
78
|
-
dependencies {
|
|
79
|
-
// CloudX Android SDK
|
|
80
|
-
implementation "io.cloudx:sdk:3.2.0"
|
|
81
|
-
|
|
82
|
-
// Adapters for ad networks (add as needed)
|
|
83
|
-
implementation "io.cloudx:adapter-meta:3.2.0"
|
|
84
|
-
implementation "io.cloudx:adapter-vungle:3.2.0"
|
|
85
|
-
implementation "io.cloudx:adapter-inmobi:3.2.0"
|
|
86
|
-
implementation "io.cloudx:adapter-mintegral:3.2.0"
|
|
87
|
-
implementation "io.cloudx:adapter-unityads:3.2.0"
|
|
88
|
-
implementation "io.cloudx:adapter-magnite:3.2.0"
|
|
89
|
-
|
|
90
|
-
// Required by the native SDK 3.2.0 when using the Meta adapter.
|
|
91
|
-
implementation "com.facebook.android:audience-network-sdk:6.21.0"
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
> **Note:** At least one adapter is required for the SDK to serve ads.
|
|
96
|
-
|
|
97
|
-
If you integrate the Mintegral adapter, also declare its Maven repository in `android/build.gradle` (Mintegral is not on Maven Central):
|
|
98
|
-
|
|
99
|
-
```kotlin
|
|
100
|
-
allprojects {
|
|
101
|
-
repositories {
|
|
102
|
-
maven { url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" }
|
|
103
|
-
}
|
|
104
|
-
}
|
|
32
|
+
npm install
|
|
105
33
|
```
|
|
106
34
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
Initialize the SDK before loading any ads:
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
import { CloudX, CloudXLogLevel } from 'cloudx-react-native';
|
|
113
|
-
|
|
114
|
-
// Optional: enable verbose logging (development only)
|
|
115
|
-
CloudX.setMinLogLevel(CloudXLogLevel.VERBOSE);
|
|
116
|
-
|
|
117
|
-
// Initialize with your app key
|
|
118
|
-
const result = await CloudX.initialize('YOUR_APP_KEY');
|
|
119
|
-
if (result.success) {
|
|
120
|
-
console.log('CloudX initialized');
|
|
121
|
-
} else {
|
|
122
|
-
console.error('CloudX init failed:', result.message);
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Initialization API
|
|
127
|
-
|
|
128
|
-
| Method | Returns | Description |
|
|
129
|
-
|--------|---------|-------------|
|
|
130
|
-
| `CloudX.initialize(appKey)` | `Promise<CloudXInitializationResult>` | Initialize the SDK with your app key |
|
|
131
|
-
| `CloudX.isInitialized()` | `Promise<boolean>` | Check if the SDK has been initialized |
|
|
132
|
-
| `CloudX.getVersion()` | `Promise<string>` | Get the native SDK version string |
|
|
133
|
-
| `CloudX.isTablet()` | `Promise<boolean>` | Check if the device is a tablet |
|
|
134
|
-
|
|
135
|
-
The `CloudXInitializationResult` contains:
|
|
136
|
-
- `success: boolean` — whether initialization succeeded
|
|
137
|
-
- `message?: string` — additional details on failure
|
|
138
|
-
|
|
139
|
-
## Ad Integration
|
|
140
|
-
|
|
141
|
-
### Banner Ads (Programmatic Overlay)
|
|
142
|
-
|
|
143
|
-
Banners overlay your content at a fixed screen position:
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
import { CloudXBannerAd, CloudXAdPosition } from 'cloudx-react-native';
|
|
147
|
-
|
|
148
|
-
const AD_UNIT_ID = 'home_banner';
|
|
149
|
-
|
|
150
|
-
// Set up event listeners
|
|
151
|
-
CloudXBannerAd.addAdLoadedEventListener((adInfo) => {
|
|
152
|
-
console.log('Banner loaded from', adInfo.networkName);
|
|
153
|
-
});
|
|
154
|
-
CloudXBannerAd.addAdLoadFailedEventListener((error) => {
|
|
155
|
-
console.log('Banner failed:', error.code, error.message);
|
|
156
|
-
});
|
|
157
|
-
CloudXBannerAd.addAdRevenuePaidListener((adInfo) => {
|
|
158
|
-
console.log('Banner revenue:', adInfo.revenue);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// Create and show
|
|
162
|
-
CloudXBannerAd.createAd(AD_UNIT_ID, CloudXAdPosition.BOTTOM_CENTER);
|
|
163
|
-
CloudXBannerAd.showAd(AD_UNIT_ID);
|
|
164
|
-
|
|
165
|
-
// Hide / destroy when done
|
|
166
|
-
CloudXBannerAd.hideAd(AD_UNIT_ID);
|
|
167
|
-
CloudXBannerAd.destroyAd(AD_UNIT_ID);
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Auto-refresh is enabled by default. To control it manually:
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
CloudXBannerAd.stopAutoRefresh(AD_UNIT_ID);
|
|
174
|
-
CloudXBannerAd.startAutoRefresh(AD_UNIT_ID);
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
#### Full Banner API
|
|
178
|
-
|
|
179
|
-
| Method | Description |
|
|
180
|
-
|--------|-------------|
|
|
181
|
-
| `createAd(adUnitId, position)` | Create a banner at the given `CloudXAdPosition` |
|
|
182
|
-
| `createAdWithOffsets(adUnitId, position, xOffset, yOffset)` | Create with pixel offsets from the position anchor |
|
|
183
|
-
| `showAd(adUnitId)` | Show the banner |
|
|
184
|
-
| `hideAd(adUnitId)` | Hide the banner (preserves the ad) |
|
|
185
|
-
| `destroyAd(adUnitId)` | Destroy the banner and release resources |
|
|
186
|
-
| `updatePosition(adUnitId, position)` | Move to a new `CloudXAdPosition` |
|
|
187
|
-
| `updateOffsets(adUnitId, xOffset, yOffset)` | Update pixel offsets |
|
|
188
|
-
| `setBackgroundColor(adUnitId, hexColor)` | Set banner background color (e.g., `"#000000"`) |
|
|
189
|
-
| `setPlacement(adUnitId, placement)` | Set placement name for reporting |
|
|
190
|
-
| `setCustomData(adUnitId, customData)` | Set custom data string |
|
|
191
|
-
| `startAutoRefresh(adUnitId)` | Resume auto-refresh |
|
|
192
|
-
| `stopAutoRefresh(adUnitId)` | Pause auto-refresh |
|
|
193
|
-
|
|
194
|
-
#### Banner Events
|
|
195
|
-
|
|
196
|
-
| Method | Callback Parameter |
|
|
197
|
-
|--------|--------------------|
|
|
198
|
-
| `addAdLoadedEventListener(fn)` | `CloudXAdInfo` |
|
|
199
|
-
| `addAdLoadFailedEventListener(fn)` | `CloudXAdLoadFailedInfo` |
|
|
200
|
-
| `addAdClickedEventListener(fn)` | `CloudXAdInfo` |
|
|
201
|
-
| `addAdExpandedEventListener(fn)` | `CloudXAdInfo` |
|
|
202
|
-
| `addAdCollapsedEventListener(fn)` | `CloudXAdInfo` |
|
|
203
|
-
| `addAdRevenuePaidListener(fn)` | `CloudXAdInfo` |
|
|
204
|
-
|
|
205
|
-
Each `add*` listener has a corresponding `remove*` method (e.g., `removeAdLoadedEventListener()`).
|
|
206
|
-
|
|
207
|
-
### MREC Ads (Programmatic Overlay)
|
|
208
|
-
|
|
209
|
-
MRECs work identically to banners but with a 300x250 size:
|
|
210
|
-
|
|
211
|
-
```typescript
|
|
212
|
-
import { CloudXMRECAd, CloudXAdPosition } from 'cloudx-react-native';
|
|
213
|
-
|
|
214
|
-
const AD_UNIT_ID = 'home_mrec';
|
|
215
|
-
|
|
216
|
-
CloudXMRECAd.addAdLoadedEventListener((adInfo) => {
|
|
217
|
-
console.log('MREC loaded from', adInfo.networkName);
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
CloudXMRECAd.createAd(AD_UNIT_ID, CloudXAdPosition.CENTERED);
|
|
221
|
-
CloudXMRECAd.showAd(AD_UNIT_ID);
|
|
222
|
-
|
|
223
|
-
// Destroy when done
|
|
224
|
-
CloudXMRECAd.destroyAd(AD_UNIT_ID);
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
The MREC API surface is identical to Banner — all the same methods and events are available on `CloudXMRECAd`, including `createAdWithOffsets`, `updatePosition`, `updateOffsets`, `setBackgroundColor`, `setPlacement`, `setCustomData`, auto-refresh control, and all event listeners.
|
|
228
|
-
|
|
229
|
-
### Interstitial Ads
|
|
230
|
-
|
|
231
|
-
Full-screen ads shown at natural transition points.
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
import { CloudXInterstitialAd } from 'cloudx-react-native';
|
|
235
|
-
|
|
236
|
-
const AD_UNIT_ID = 'level_complete';
|
|
237
|
-
|
|
238
|
-
// Set up event listeners
|
|
239
|
-
CloudXInterstitialAd.addAdLoadedEventListener((adInfo) => {
|
|
240
|
-
console.log('Interstitial loaded');
|
|
241
|
-
});
|
|
242
|
-
CloudXInterstitialAd.addAdLoadFailedEventListener((error) => {
|
|
243
|
-
console.log('Interstitial load failed:', error.code, error.message);
|
|
244
|
-
});
|
|
245
|
-
CloudXInterstitialAd.addAdDisplayedEventListener((adInfo) => {
|
|
246
|
-
console.log('Interstitial displayed');
|
|
247
|
-
});
|
|
248
|
-
CloudXInterstitialAd.addAdFailedToDisplayEventListener((error) => {
|
|
249
|
-
console.log('Interstitial display failed:', error.code, error.message);
|
|
250
|
-
});
|
|
251
|
-
CloudXInterstitialAd.addAdHiddenEventListener((adInfo) => {
|
|
252
|
-
// Reload for next use
|
|
253
|
-
CloudXInterstitialAd.loadAd(AD_UNIT_ID);
|
|
254
|
-
});
|
|
255
|
-
CloudXInterstitialAd.addAdRevenuePaidListener((adInfo) => {
|
|
256
|
-
console.log('Revenue:', adInfo.revenue);
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
// Load
|
|
260
|
-
CloudXInterstitialAd.loadAd(AD_UNIT_ID);
|
|
261
|
-
|
|
262
|
-
// Show when ready (with optional placement and custom data)
|
|
263
|
-
const isReady = await CloudXInterstitialAd.isAdReady(AD_UNIT_ID);
|
|
264
|
-
if (isReady) {
|
|
265
|
-
CloudXInterstitialAd.showAd(AD_UNIT_ID);
|
|
266
|
-
// or with placement/custom data:
|
|
267
|
-
// CloudXInterstitialAd.showAd(AD_UNIT_ID, 'level_end', 'custom_data');
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Destroy when done
|
|
271
|
-
CloudXInterstitialAd.destroyAd(AD_UNIT_ID);
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
#### Interstitial API
|
|
275
|
-
|
|
276
|
-
| Method | Description |
|
|
277
|
-
|--------|-------------|
|
|
278
|
-
| `loadAd(adUnitId)` | Start loading an interstitial |
|
|
279
|
-
| `isAdReady(adUnitId)` | Returns `Promise<boolean>` — whether an ad is ready to show |
|
|
280
|
-
| `showAd(adUnitId, placement?, customData?)` | Show the loaded interstitial |
|
|
281
|
-
| `destroyAd(adUnitId)` | Destroy the interstitial and release resources |
|
|
282
|
-
|
|
283
|
-
#### Interstitial Events
|
|
284
|
-
|
|
285
|
-
| Method | Callback Parameter |
|
|
286
|
-
|--------|--------------------|
|
|
287
|
-
| `addAdLoadedEventListener(fn)` | `CloudXAdInfo` |
|
|
288
|
-
| `addAdLoadFailedEventListener(fn)` | `CloudXAdLoadFailedInfo` |
|
|
289
|
-
| `addAdDisplayedEventListener(fn)` | `CloudXAdInfo` |
|
|
290
|
-
| `addAdFailedToDisplayEventListener(fn)` | `CloudXAdDisplayFailedInfo` |
|
|
291
|
-
| `addAdClickedEventListener(fn)` | `CloudXAdInfo` |
|
|
292
|
-
| `addAdHiddenEventListener(fn)` | `CloudXAdInfo` |
|
|
293
|
-
| `addAdRevenuePaidListener(fn)` | `CloudXAdInfo` |
|
|
294
|
-
|
|
295
|
-
### Rewarded Ads
|
|
296
|
-
|
|
297
|
-
Full-screen ads that grant users a reward upon completion.
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
import { CloudXRewardedAd } from 'cloudx-react-native';
|
|
301
|
-
|
|
302
|
-
const AD_UNIT_ID = 'rewarded_coins';
|
|
303
|
-
|
|
304
|
-
// Set up event listeners
|
|
305
|
-
CloudXRewardedAd.addAdLoadedEventListener((adInfo) => {
|
|
306
|
-
console.log('Rewarded loaded');
|
|
307
|
-
});
|
|
308
|
-
CloudXRewardedAd.addAdLoadFailedEventListener((error) => {
|
|
309
|
-
console.log('Rewarded load failed:', error.code, error.message);
|
|
310
|
-
});
|
|
311
|
-
CloudXRewardedAd.addAdDisplayedEventListener((adInfo) => {
|
|
312
|
-
console.log('Rewarded displayed');
|
|
313
|
-
});
|
|
314
|
-
CloudXRewardedAd.addAdFailedToDisplayEventListener((error) => {
|
|
315
|
-
console.log('Rewarded display failed:', error.code, error.message);
|
|
316
|
-
});
|
|
317
|
-
CloudXRewardedAd.addAdReceivedRewardEventListener((rewardInfo) => {
|
|
318
|
-
console.log(`Earned ${rewardInfo.rewardAmount} ${rewardInfo.rewardLabel}`);
|
|
319
|
-
});
|
|
320
|
-
CloudXRewardedAd.addAdHiddenEventListener((adInfo) => {
|
|
321
|
-
// Reload for next use
|
|
322
|
-
CloudXRewardedAd.loadAd(AD_UNIT_ID);
|
|
323
|
-
});
|
|
324
|
-
CloudXRewardedAd.addAdRevenuePaidListener((adInfo) => {
|
|
325
|
-
console.log('Revenue:', adInfo.revenue);
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
// Load
|
|
329
|
-
CloudXRewardedAd.loadAd(AD_UNIT_ID);
|
|
330
|
-
|
|
331
|
-
// Show when ready (with optional placement and custom data)
|
|
332
|
-
const isReady = await CloudXRewardedAd.isAdReady(AD_UNIT_ID);
|
|
333
|
-
if (isReady) {
|
|
334
|
-
CloudXRewardedAd.showAd(AD_UNIT_ID);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Destroy when done
|
|
338
|
-
CloudXRewardedAd.destroyAd(AD_UNIT_ID);
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
#### Rewarded API
|
|
342
|
-
|
|
343
|
-
| Method | Description |
|
|
344
|
-
|--------|-------------|
|
|
345
|
-
| `loadAd(adUnitId)` | Start loading a rewarded ad |
|
|
346
|
-
| `isAdReady(adUnitId)` | Returns `Promise<boolean>` — whether an ad is ready to show |
|
|
347
|
-
| `showAd(adUnitId, placement?, customData?)` | Show the loaded rewarded ad |
|
|
348
|
-
| `destroyAd(adUnitId)` | Destroy the rewarded ad and release resources |
|
|
349
|
-
|
|
350
|
-
#### Rewarded Events
|
|
351
|
-
|
|
352
|
-
| Method | Callback Parameter |
|
|
353
|
-
|--------|--------------------|
|
|
354
|
-
| `addAdLoadedEventListener(fn)` | `CloudXAdInfo` |
|
|
355
|
-
| `addAdLoadFailedEventListener(fn)` | `CloudXAdLoadFailedInfo` |
|
|
356
|
-
| `addAdDisplayedEventListener(fn)` | `CloudXAdInfo` |
|
|
357
|
-
| `addAdFailedToDisplayEventListener(fn)` | `CloudXAdDisplayFailedInfo` |
|
|
358
|
-
| `addAdClickedEventListener(fn)` | `CloudXAdInfo` |
|
|
359
|
-
| `addAdHiddenEventListener(fn)` | `CloudXAdInfo` |
|
|
360
|
-
| `addAdReceivedRewardEventListener(fn)` | `CloudXAdRewardInfo` |
|
|
361
|
-
| `addAdRevenuePaidListener(fn)` | `CloudXAdInfo` |
|
|
362
|
-
|
|
363
|
-
## React Hooks
|
|
364
|
-
|
|
365
|
-
The SDK provides React hooks for declarative ad management that handle event subscriptions and cleanup automatically.
|
|
366
|
-
|
|
367
|
-
### useCloudXInterstitial
|
|
368
|
-
|
|
369
|
-
```typescript
|
|
370
|
-
import { useCloudXInterstitial } from 'cloudx-react-native';
|
|
371
|
-
|
|
372
|
-
function GameScreen() {
|
|
373
|
-
const { isLoaded, isLoading, error, load, show, destroy } =
|
|
374
|
-
useCloudXInterstitial('level_complete');
|
|
375
|
-
|
|
376
|
-
useEffect(() => {
|
|
377
|
-
load();
|
|
378
|
-
}, [load]);
|
|
379
|
-
|
|
380
|
-
return (
|
|
381
|
-
<Button
|
|
382
|
-
title={isLoading ? 'Loading...' : 'Show Ad'}
|
|
383
|
-
onPress={() => show()}
|
|
384
|
-
disabled={!isLoaded}
|
|
385
|
-
/>
|
|
386
|
-
);
|
|
387
|
-
}
|
|
388
|
-
```
|
|
35
|
+
Build generated package outputs:
|
|
389
36
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
- `isLoading: boolean` — load in progress
|
|
393
|
-
- `error: string | null` — last error message
|
|
394
|
-
- `load()` — start loading
|
|
395
|
-
- `show(placement?, customData?)` — show the loaded ad
|
|
396
|
-
- `destroy()` — destroy and reset state
|
|
397
|
-
|
|
398
|
-
### useCloudXRewarded
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
import { useCloudXRewarded } from 'cloudx-react-native';
|
|
402
|
-
|
|
403
|
-
function RewardScreen() {
|
|
404
|
-
const { isLoaded, isLoading, error, rewardEarned, load, show } =
|
|
405
|
-
useCloudXRewarded('rewarded_coins');
|
|
406
|
-
|
|
407
|
-
useEffect(() => {
|
|
408
|
-
load();
|
|
409
|
-
}, [load]);
|
|
410
|
-
|
|
411
|
-
useEffect(() => {
|
|
412
|
-
if (rewardEarned) {
|
|
413
|
-
grantCoinsToUser();
|
|
414
|
-
}
|
|
415
|
-
}, [rewardEarned]);
|
|
416
|
-
|
|
417
|
-
return (
|
|
418
|
-
<Button
|
|
419
|
-
title="Watch Ad for Coins"
|
|
420
|
-
onPress={() => show()}
|
|
421
|
-
disabled={!isLoaded}
|
|
422
|
-
/>
|
|
423
|
-
);
|
|
424
|
-
}
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
Returns `CloudXRewardedHookResult`:
|
|
428
|
-
- `isLoaded: boolean` — ad is ready to show
|
|
429
|
-
- `isLoading: boolean` — load in progress
|
|
430
|
-
- `error: string | null` — last error message
|
|
431
|
-
- `rewardEarned: boolean` — user completed the ad and earned a reward
|
|
432
|
-
- `load()` — start loading
|
|
433
|
-
- `show(placement?, customData?)` — show the loaded ad
|
|
434
|
-
- `destroy()` — destroy and reset state
|
|
435
|
-
|
|
436
|
-
### useCloudXBanner
|
|
437
|
-
|
|
438
|
-
```typescript
|
|
439
|
-
import { useCloudXBanner, CloudXBannerAd, CloudXAdPosition } from 'cloudx-react-native';
|
|
440
|
-
|
|
441
|
-
function HomeScreen() {
|
|
442
|
-
const { isLoaded, error } = useCloudXBanner('home_banner');
|
|
443
|
-
|
|
444
|
-
useEffect(() => {
|
|
445
|
-
CloudXBannerAd.createAd('home_banner', CloudXAdPosition.BOTTOM_CENTER);
|
|
446
|
-
CloudXBannerAd.showAd('home_banner');
|
|
447
|
-
return () => CloudXBannerAd.destroyAd('home_banner');
|
|
448
|
-
}, []);
|
|
449
|
-
|
|
450
|
-
return <Text>{isLoaded ? 'Banner showing' : 'Loading banner...'}</Text>;
|
|
451
|
-
}
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
Returns `CloudXBannerHookResult`:
|
|
455
|
-
- `isLoaded: boolean` — banner has loaded an ad
|
|
456
|
-
- `error: string | null` — last error message
|
|
457
|
-
|
|
458
|
-
## Types Reference
|
|
459
|
-
|
|
460
|
-
### CloudXAdInfo
|
|
461
|
-
|
|
462
|
-
Received by most ad event callbacks:
|
|
463
|
-
|
|
464
|
-
```typescript
|
|
465
|
-
type CloudXAdInfo = {
|
|
466
|
-
adUnitId: string;
|
|
467
|
-
adFormat: string; // "BANNER", "MREC", "INTERSTITIAL", "REWARDED"
|
|
468
|
-
networkName: string;
|
|
469
|
-
networkPlacement?: string | null;
|
|
470
|
-
placement?: string | null;
|
|
471
|
-
revenue: number; // USD
|
|
472
|
-
};
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
### CloudXAdLoadFailedInfo
|
|
476
|
-
|
|
477
|
-
Received by `addAdLoadFailedEventListener`:
|
|
478
|
-
|
|
479
|
-
```typescript
|
|
480
|
-
type CloudXAdLoadFailedInfo = {
|
|
481
|
-
adUnitId: string;
|
|
482
|
-
code: CloudXErrorCode;
|
|
483
|
-
message?: string | null;
|
|
484
|
-
};
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
### CloudXAdDisplayFailedInfo
|
|
488
|
-
|
|
489
|
-
Received by `addAdFailedToDisplayEventListener`:
|
|
490
|
-
|
|
491
|
-
```typescript
|
|
492
|
-
type CloudXAdDisplayFailedInfo = CloudXAdInfo & {
|
|
493
|
-
code: CloudXErrorCode;
|
|
494
|
-
message?: string | null;
|
|
495
|
-
};
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
### CloudXAdRewardInfo
|
|
499
|
-
|
|
500
|
-
Received by `addAdReceivedRewardEventListener`:
|
|
501
|
-
|
|
502
|
-
```typescript
|
|
503
|
-
type CloudXAdRewardInfo = CloudXAdInfo & {
|
|
504
|
-
rewardLabel?: string | null;
|
|
505
|
-
rewardAmount: number;
|
|
506
|
-
};
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
### CloudXAdPosition
|
|
510
|
-
|
|
511
|
-
Position constants for programmatic banner and MREC placement:
|
|
512
|
-
|
|
513
|
-
```typescript
|
|
514
|
-
enum CloudXAdPosition {
|
|
515
|
-
TOP_LEFT, TOP_CENTER, TOP_RIGHT,
|
|
516
|
-
CENTER_LEFT, CENTERED, CENTER_RIGHT,
|
|
517
|
-
BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT,
|
|
518
|
-
}
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
## Advanced Features
|
|
522
|
-
|
|
523
|
-
### Error Handling
|
|
524
|
-
|
|
525
|
-
All error callbacks receive an object with `code` and `message` properties:
|
|
526
|
-
|
|
527
|
-
| Range | Category | Common Codes |
|
|
528
|
-
|-------|----------|--------------|
|
|
529
|
-
| 0 | General | `internalError` |
|
|
530
|
-
| 100-199 | Network | `networkError`, `networkTimeout`, `networkNoConnection` |
|
|
531
|
-
| 200-299 | Initialization | `notInitialized`, `sdkDisabled`, `invalidAppKey` |
|
|
532
|
-
| 300-399 | Ad Loading | `noFill`, `invalidAdUnit`, `adsDisabled` |
|
|
533
|
-
| 400-499 | Display | `adNotReady`, `adAlreadyShowing` |
|
|
534
|
-
| 600-699 | Adapter | `adapterNoFill`, `adapterTimeout` |
|
|
535
|
-
|
|
536
|
-
See `CloudXErrorCode` export for the full list of error codes.
|
|
537
|
-
|
|
538
|
-
### Revenue Tracking
|
|
539
|
-
|
|
540
|
-
All ad formats provide revenue callbacks. The `CloudXAdInfo` object includes `revenue` (USD) and `networkName`:
|
|
541
|
-
|
|
542
|
-
```typescript
|
|
543
|
-
CloudXInterstitialAd.addAdRevenuePaidListener((adInfo) => {
|
|
544
|
-
trackRevenue(adInfo.revenue, adInfo.networkName, adInfo.adUnitId);
|
|
545
|
-
});
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
### User Targeting
|
|
549
|
-
|
|
550
|
-
```typescript
|
|
551
|
-
import { CloudX } from 'cloudx-react-native';
|
|
552
|
-
|
|
553
|
-
// Set hashed user ID
|
|
554
|
-
CloudX.setHashedUserID('hashed-user-id');
|
|
555
|
-
|
|
556
|
-
// Set custom key-value pairs
|
|
557
|
-
CloudX.setUserKeyValue('age_group', '25-34');
|
|
558
|
-
CloudX.setAppKeyValue('app_version', '1.0.0');
|
|
559
|
-
|
|
560
|
-
// Clear all custom key-values
|
|
561
|
-
CloudX.clearAllKeyValues();
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
### Manual Privacy Overrides
|
|
565
|
-
|
|
566
|
-
In most cases, IAB privacy signals (TCF, US Privacy String) are read automatically from shared `NSUserDefaults` / `SharedPreferences` written by your CMP. Use the manual APIs only when you need to override a CMP-provided value or when you don't use a CMP:
|
|
567
|
-
|
|
568
|
-
```typescript
|
|
569
|
-
import { CloudX } from 'cloudx-react-native';
|
|
570
|
-
|
|
571
|
-
// GDPR: user has granted consent
|
|
572
|
-
CloudX.setHasUserConsent(true);
|
|
573
|
-
|
|
574
|
-
// CCPA / US Privacy: user opted out of sale
|
|
575
|
-
CloudX.setDoNotSell(true);
|
|
576
|
-
|
|
577
|
-
// Clear a previously set override (fall back to CMP signal)
|
|
578
|
-
CloudX.setHasUserConsent(null);
|
|
579
|
-
CloudX.setDoNotSell(null);
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
Call these before `CloudX.initialize()` so the value is available before the first auction.
|
|
583
|
-
|
|
584
|
-
### App Tracking Transparency (iOS)
|
|
585
|
-
|
|
586
|
-
```typescript
|
|
587
|
-
import { requestTrackingAuthorization, getTrackingAuthorizationStatus, CloudXATTStatus } from 'cloudx-react-native';
|
|
588
|
-
|
|
589
|
-
const status = await requestTrackingAuthorization();
|
|
590
|
-
if (status === CloudXATTStatus.AUTHORIZED) {
|
|
591
|
-
console.log('Tracking authorized');
|
|
592
|
-
}
|
|
37
|
+
```bash
|
|
38
|
+
npm run prepare
|
|
593
39
|
```
|
|
594
40
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
ATT status values: `AUTHORIZED`, `DENIED`, `RESTRICTED`, `NOT_DETERMINED`, `NOT_REQUIRED`.
|
|
598
|
-
|
|
599
|
-
On Android or iOS < 14, `requestTrackingAuthorization()` returns `NOT_REQUIRED`.
|
|
600
|
-
|
|
601
|
-
### Test Mode
|
|
602
|
-
|
|
603
|
-
Test mode is **server-controlled** via device whitelisting:
|
|
604
|
-
|
|
605
|
-
1. Initialize the SDK with verbose logging enabled
|
|
606
|
-
2. Find your device advertising ID in the console logs
|
|
607
|
-
3. Add the device to your whitelist on the CloudX dashboard
|
|
41
|
+
Run library checks:
|
|
608
42
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
import { CloudX, CloudXLogLevel } from 'cloudx-react-native';
|
|
613
|
-
|
|
614
|
-
// Enable verbose logging (call before initialize)
|
|
615
|
-
CloudX.setMinLogLevel(CloudXLogLevel.VERBOSE);
|
|
616
|
-
|
|
617
|
-
// Available levels: VERBOSE, DEBUG, INFO, WARN, ERROR, NONE
|
|
43
|
+
```bash
|
|
44
|
+
npm run typescript
|
|
45
|
+
npm run lint
|
|
618
46
|
```
|
|
619
47
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
Enable visual debugging overlays to see ad unit boundaries and network info:
|
|
48
|
+
Run the demo app:
|
|
623
49
|
|
|
624
|
-
```
|
|
625
|
-
|
|
50
|
+
```bash
|
|
51
|
+
cd demo-app
|
|
52
|
+
npm install
|
|
53
|
+
npm run ios
|
|
54
|
+
npm run android
|
|
626
55
|
```
|
|
627
56
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
| Platform | Status | Minimum Version |
|
|
631
|
-
|----------|--------|-----------------|
|
|
632
|
-
| iOS | Supported | iOS 13.0+ |
|
|
633
|
-
| Android | Supported | API 23+ |
|
|
634
|
-
|
|
635
|
-
### Requirements
|
|
636
|
-
|
|
637
|
-
- React Native 0.70+
|
|
638
|
-
- React 18.0+
|
|
639
|
-
- TypeScript 4.5+ (recommended)
|
|
640
|
-
- Xcode 14.0+ / CocoaPods (iOS)
|
|
641
|
-
- Gradle 8.0+ / Kotlin 1.8+ (Android)
|
|
642
|
-
|
|
643
|
-
### Native SDK Versions (3.2.0)
|
|
644
|
-
|
|
645
|
-
| Platform | Dependency | Version |
|
|
646
|
-
|----------|-----------|---------|
|
|
647
|
-
| iOS | CloudXCore | ~> 3.2.0 |
|
|
648
|
-
| Android | io.cloudx:sdk | 3.2.0 |
|
|
57
|
+
Install demo iOS pods:
|
|
649
58
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
React Native 0.84.0 has a known issue where `TurboModuleRegistry.getEnforcing(...)` fails with:
|
|
655
|
-
|
|
656
|
-
> `TurboModuleRegistry.getEnforcing(...): 'PlatformConstants' could not be found. Verify that a module by this name is registered in the native binary.`
|
|
657
|
-
|
|
658
|
-
This is a React Native framework bug, not a CloudX SDK issue. It manifests as a red screen crash on app launch:
|
|
659
|
-
|
|
660
|
-
```
|
|
661
|
-
TurboModuleRegistry.getEnforcing(...):
|
|
662
|
-
'PlatformConstants' could not be found. Verify
|
|
663
|
-
that a module by this name is registered in
|
|
664
|
-
the native binary.
|
|
59
|
+
```bash
|
|
60
|
+
cd demo-app/ios
|
|
61
|
+
pod install
|
|
665
62
|
```
|
|
666
63
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
## Documentation
|
|
670
|
-
|
|
671
|
-
- **[Integration Guide](https://docs.cloudx.io/en/react-native/integration)**: Complete integration documentation
|
|
672
|
-
- **[Changelog](https://docs.cloudx.io/en/react-native/changelog)**: Release history
|
|
673
|
-
|
|
674
|
-
## Support
|
|
675
|
-
|
|
676
|
-
For support, contact mobile@cloudx.io
|
|
64
|
+
## Releases
|
|
677
65
|
|
|
678
|
-
|
|
66
|
+
Follow [RELEASE.md](RELEASE.md) for npm releases, native dependency updates, QA gates, and post-release validation.
|
|
679
67
|
|
|
680
|
-
|
|
68
|
+
Public integration docs and release notes belong in the docs repo.
|