cloudx-react-native 3.2.0 → 3.4.0

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.
Files changed (62) hide show
  1. package/README.md +40 -652
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/cloudxreactnative/CloudXModuleImpl.kt +97 -0
  4. package/android/src/newarch/com/cloudxreactnative/CloudXModule.kt +5 -0
  5. package/android/src/oldarch/com/cloudxreactnative/CloudXModule.kt +5 -0
  6. package/cloudx-react-native.podspec +1 -1
  7. package/ios/CloudX.mm +109 -0
  8. package/lib/commonjs/CloudXBannerAd.js +4 -0
  9. package/lib/commonjs/CloudXBannerAd.js.map +1 -1
  10. package/lib/commonjs/CloudXInterstitialAd.js +4 -0
  11. package/lib/commonjs/CloudXInterstitialAd.js.map +1 -1
  12. package/lib/commonjs/CloudXMRECAd.js +4 -0
  13. package/lib/commonjs/CloudXMRECAd.js.map +1 -1
  14. package/lib/commonjs/CloudXRewardedAd.js +4 -0
  15. package/lib/commonjs/CloudXRewardedAd.js.map +1 -1
  16. package/lib/commonjs/index.js.map +1 -1
  17. package/lib/commonjs/specs/NativeCloudX.js.map +1 -1
  18. package/lib/commonjs/types/ExtraParameters.js +2 -0
  19. package/lib/commonjs/types/ExtraParameters.js.map +1 -0
  20. package/lib/commonjs/version.js +1 -1
  21. package/lib/module/CloudXBannerAd.js +4 -0
  22. package/lib/module/CloudXBannerAd.js.map +1 -1
  23. package/lib/module/CloudXInterstitialAd.js +4 -0
  24. package/lib/module/CloudXInterstitialAd.js.map +1 -1
  25. package/lib/module/CloudXMRECAd.js +4 -0
  26. package/lib/module/CloudXMRECAd.js.map +1 -1
  27. package/lib/module/CloudXRewardedAd.js +4 -0
  28. package/lib/module/CloudXRewardedAd.js.map +1 -1
  29. package/lib/module/index.js.map +1 -1
  30. package/lib/module/specs/NativeCloudX.js.map +1 -1
  31. package/lib/module/types/ExtraParameters.js +2 -0
  32. package/lib/module/types/ExtraParameters.js.map +1 -0
  33. package/lib/module/version.js +1 -1
  34. package/lib/typescript/src/CloudXBannerAd.d.ts.map +1 -1
  35. package/lib/typescript/src/CloudXInterstitialAd.d.ts.map +1 -1
  36. package/lib/typescript/src/CloudXMRECAd.d.ts.map +1 -1
  37. package/lib/typescript/src/CloudXRewardedAd.d.ts.map +1 -1
  38. package/lib/typescript/src/index.d.ts +1 -1
  39. package/lib/typescript/src/index.d.ts.map +1 -1
  40. package/lib/typescript/src/specs/NativeCloudX.d.ts +5 -0
  41. package/lib/typescript/src/specs/NativeCloudX.d.ts.map +1 -1
  42. package/lib/typescript/src/types/ExtraParameters.d.ts +7 -0
  43. package/lib/typescript/src/types/ExtraParameters.d.ts.map +1 -0
  44. package/lib/typescript/src/types/FullscreenAd.d.ts +3 -0
  45. package/lib/typescript/src/types/FullscreenAd.d.ts.map +1 -1
  46. package/lib/typescript/src/types/ViewAd.d.ts +2 -0
  47. package/lib/typescript/src/types/ViewAd.d.ts.map +1 -1
  48. package/lib/typescript/src/types/index.d.ts +1 -0
  49. package/lib/typescript/src/types/index.d.ts.map +1 -1
  50. package/lib/typescript/src/version.d.ts +1 -1
  51. package/package.json +3 -1
  52. package/src/CloudXBannerAd.ts +6 -0
  53. package/src/CloudXInterstitialAd.ts +6 -0
  54. package/src/CloudXMRECAd.ts +6 -0
  55. package/src/CloudXRewardedAd.ts +6 -0
  56. package/src/index.ts +2 -0
  57. package/src/specs/NativeCloudX.ts +5 -0
  58. package/src/types/ExtraParameters.ts +11 -0
  59. package/src/types/FullscreenAd.ts +4 -0
  60. package/src/types/ViewAd.ts +2 -0
  61. package/src/types/index.ts +1 -0
  62. package/src/version.ts +1 -1
package/README.md CHANGED
@@ -1,680 +1,68 @@
1
1
  # CloudX React Native SDK
2
2
 
3
- [![npm](https://img.shields.io/npm/v/cloudx-react-native)](https://www.npmjs.com/package/cloudx-react-native)
3
+ React Native wrapper for the CloudX SDK.
4
4
 
5
- The CloudX React Native SDK enables monetization of your React Native apps with banner, MREC, interstitial, and rewarded ads on iOS and Android. It supports both the New Architecture (Fabric) and the legacy architecture (Paper).
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
- ## Features
7
+ ## Public Documentation
8
8
 
9
- - **Cross-Platform**: Full iOS and Android support
10
- - **Dual Architecture**: Works on both Fabric (New Architecture) and Paper (Legacy)
11
- - **All Ad Formats**: Banner, MREC, Interstitial, and Rewarded ads
12
- - **Programmatic Ad APIs**: Overlay APIs for banner and MREC, plus fullscreen formats
13
- - **React Hooks**: Declarative hooks for fullscreen and banner ad lifecycles
14
- - **Privacy Compliance**: IAB privacy handled automatically via CMP shared storage, plus manual `setHasUserConsent` / `setDoNotSell` overrides
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
- ### Native SDK Versions
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
- | Plugin | iOS (`CloudXCore`) | Android (`io.cloudx:sdk`) |
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
- ## Installation
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
- Requires React Native 0.70+, React 18.0+, iOS 13.0+, and Android API 23+.
27
+ ## Development
29
28
 
30
- ```bash
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
- cd ios && pod install
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
- ## Initialization
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
- Returns `CloudXInterstitialHookResult`:
391
- - `isLoaded: boolean` — ad is ready to show
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
- > **Note:** Call `requestTrackingAuthorization()` before `CloudX.initialize()` for best ad targeting results.
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
- ### Debug Logging
610
-
611
- ```typescript
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
- ### Visual Debugging
621
-
622
- Enable visual debugging overlays to see ad unit boundaries and network info:
48
+ Run the demo app:
623
49
 
624
- ```typescript
625
- CloudX.setVisualDebuggingEnabled(true);
50
+ ```bash
51
+ cd demo-app
52
+ npm install
53
+ npm run ios
54
+ npm run android
626
55
  ```
627
56
 
628
- ## Platform Support
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
- ## Troubleshooting
651
-
652
- ### React Native 0.84.0 — TurboModuleRegistry crash
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
- **Workaround:** Use React Native 0.83.x or wait for the fix in a later 0.84.x patch release. The CloudX SDK is fully compatible with RN 0.70 through 0.83.
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
- ## License
66
+ Follow [RELEASE.md](RELEASE.md) for npm releases, native dependency updates, QA gates, and post-release validation.
679
67
 
680
- This project is licensed under the Elastic License 2.0 — see the [LICENSE](LICENSE) file for details.
68
+ Public integration docs and release notes belong in the docs repo.