cloudx-react-native 2.0.0-beta.1

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 (171) hide show
  1. package/LICENSE +57 -0
  2. package/README.md +1258 -0
  3. package/android/build.gradle +78 -0
  4. package/android/gradle.properties +7 -0
  5. package/android/src/main/AndroidManifest.xml +7 -0
  6. package/android/src/main/java/com/cloudxreactnative/CloudXAdViewEvent.kt +15 -0
  7. package/android/src/main/java/com/cloudxreactnative/CloudXBannerViewManagerImpl.kt +472 -0
  8. package/android/src/main/java/com/cloudxreactnative/CloudXReactNativeModuleImpl.kt +861 -0
  9. package/android/src/newarch/com/cloudxreactnative/CloudXBannerViewManager.kt +90 -0
  10. package/android/src/newarch/com/cloudxreactnative/CloudXReactNativeModule.kt +73 -0
  11. package/android/src/newarch/com/cloudxreactnative/CloudXReactNativePackage.kt +37 -0
  12. package/android/src/oldarch/com/cloudxreactnative/CloudXBannerViewManager.kt +76 -0
  13. package/android/src/oldarch/com/cloudxreactnative/CloudXReactNativeModule.kt +73 -0
  14. package/android/src/oldarch/com/cloudxreactnative/CloudXReactNativePackage.kt +16 -0
  15. package/cloudx-react-native.podspec +46 -0
  16. package/ios/AppTrackingTransparency.h +13 -0
  17. package/ios/AppTrackingTransparency.mm +59 -0
  18. package/ios/RNCloudXBannerView.h +51 -0
  19. package/ios/RNCloudXBannerView.mm +633 -0
  20. package/ios/RNCloudXBannerViewManager.h +11 -0
  21. package/ios/RNCloudXBannerViewManager.mm +60 -0
  22. package/ios/RNCloudXModule.h +30 -0
  23. package/ios/RNCloudXModule.mm +1088 -0
  24. package/lib/commonjs/AdView.js +151 -0
  25. package/lib/commonjs/AdView.js.map +1 -0
  26. package/lib/commonjs/AppTrackingTransparency.js +62 -0
  27. package/lib/commonjs/AppTrackingTransparency.js.map +1 -0
  28. package/lib/commonjs/BannerAd.js +117 -0
  29. package/lib/commonjs/BannerAd.js.map +1 -0
  30. package/lib/commonjs/CloudX.js +49 -0
  31. package/lib/commonjs/CloudX.js.map +1 -0
  32. package/lib/commonjs/ErrorCode.js +116 -0
  33. package/lib/commonjs/ErrorCode.js.map +1 -0
  34. package/lib/commonjs/EventEmitter.js +44 -0
  35. package/lib/commonjs/EventEmitter.js.map +1 -0
  36. package/lib/commonjs/InterstitialAd.js +94 -0
  37. package/lib/commonjs/InterstitialAd.js.map +1 -0
  38. package/lib/commonjs/MRecAd.js +117 -0
  39. package/lib/commonjs/MRecAd.js.map +1 -0
  40. package/lib/commonjs/RewardedAd.js +103 -0
  41. package/lib/commonjs/RewardedAd.js.map +1 -0
  42. package/lib/commonjs/hooks.js +239 -0
  43. package/lib/commonjs/hooks.js.map +1 -0
  44. package/lib/commonjs/index.js +144 -0
  45. package/lib/commonjs/index.js.map +1 -0
  46. package/lib/commonjs/specs/CloudXAdViewNativeComponent.js +26 -0
  47. package/lib/commonjs/specs/CloudXAdViewNativeComponent.js.map +1 -0
  48. package/lib/commonjs/specs/NativeCloudXModule.js +18 -0
  49. package/lib/commonjs/specs/NativeCloudXModule.js.map +1 -0
  50. package/lib/commonjs/types/AdEvent.js +6 -0
  51. package/lib/commonjs/types/AdEvent.js.map +1 -0
  52. package/lib/commonjs/types/AdInfo.js +6 -0
  53. package/lib/commonjs/types/AdInfo.js.map +1 -0
  54. package/lib/commonjs/types/BannerAd.js +6 -0
  55. package/lib/commonjs/types/BannerAd.js.map +1 -0
  56. package/lib/commonjs/types/CloudX.js +6 -0
  57. package/lib/commonjs/types/CloudX.js.map +1 -0
  58. package/lib/commonjs/types/Configuration.js +2 -0
  59. package/lib/commonjs/types/Configuration.js.map +1 -0
  60. package/lib/commonjs/types/FullscreenAd.js +6 -0
  61. package/lib/commonjs/types/FullscreenAd.js.map +1 -0
  62. package/lib/commonjs/types/RewardedAd.js +6 -0
  63. package/lib/commonjs/types/RewardedAd.js.map +1 -0
  64. package/lib/commonjs/types/index.js +2 -0
  65. package/lib/commonjs/types/index.js.map +1 -0
  66. package/lib/module/AdView.js +144 -0
  67. package/lib/module/AdView.js.map +1 -0
  68. package/lib/module/AppTrackingTransparency.js +55 -0
  69. package/lib/module/AppTrackingTransparency.js.map +1 -0
  70. package/lib/module/BannerAd.js +110 -0
  71. package/lib/module/BannerAd.js.map +1 -0
  72. package/lib/module/CloudX.js +42 -0
  73. package/lib/module/CloudX.js.map +1 -0
  74. package/lib/module/ErrorCode.js +110 -0
  75. package/lib/module/ErrorCode.js.map +1 -0
  76. package/lib/module/EventEmitter.js +35 -0
  77. package/lib/module/EventEmitter.js.map +1 -0
  78. package/lib/module/InterstitialAd.js +87 -0
  79. package/lib/module/InterstitialAd.js.map +1 -0
  80. package/lib/module/MRecAd.js +110 -0
  81. package/lib/module/MRecAd.js.map +1 -0
  82. package/lib/module/RewardedAd.js +96 -0
  83. package/lib/module/RewardedAd.js.map +1 -0
  84. package/lib/module/hooks.js +230 -0
  85. package/lib/module/hooks.js.map +1 -0
  86. package/lib/module/index.js +33 -0
  87. package/lib/module/index.js.map +1 -0
  88. package/lib/module/specs/CloudXAdViewNativeComponent.js +20 -0
  89. package/lib/module/specs/CloudXAdViewNativeComponent.js.map +1 -0
  90. package/lib/module/specs/NativeCloudXModule.js +14 -0
  91. package/lib/module/specs/NativeCloudXModule.js.map +1 -0
  92. package/lib/module/types/AdEvent.js +2 -0
  93. package/lib/module/types/AdEvent.js.map +1 -0
  94. package/lib/module/types/AdInfo.js +2 -0
  95. package/lib/module/types/AdInfo.js.map +1 -0
  96. package/lib/module/types/BannerAd.js +2 -0
  97. package/lib/module/types/BannerAd.js.map +1 -0
  98. package/lib/module/types/CloudX.js +2 -0
  99. package/lib/module/types/CloudX.js.map +1 -0
  100. package/lib/module/types/Configuration.js +2 -0
  101. package/lib/module/types/Configuration.js.map +1 -0
  102. package/lib/module/types/FullscreenAd.js +2 -0
  103. package/lib/module/types/FullscreenAd.js.map +1 -0
  104. package/lib/module/types/RewardedAd.js +2 -0
  105. package/lib/module/types/RewardedAd.js.map +1 -0
  106. package/lib/module/types/index.js +2 -0
  107. package/lib/module/types/index.js.map +1 -0
  108. package/lib/typescript/src/AdView.d.ts +69 -0
  109. package/lib/typescript/src/AdView.d.ts.map +1 -0
  110. package/lib/typescript/src/AppTrackingTransparency.d.ts +28 -0
  111. package/lib/typescript/src/AppTrackingTransparency.d.ts.map +1 -0
  112. package/lib/typescript/src/BannerAd.d.ts +4 -0
  113. package/lib/typescript/src/BannerAd.d.ts.map +1 -0
  114. package/lib/typescript/src/CloudX.d.ts +4 -0
  115. package/lib/typescript/src/CloudX.d.ts.map +1 -0
  116. package/lib/typescript/src/ErrorCode.d.ts +102 -0
  117. package/lib/typescript/src/ErrorCode.d.ts.map +1 -0
  118. package/lib/typescript/src/EventEmitter.d.ts +16 -0
  119. package/lib/typescript/src/EventEmitter.d.ts.map +1 -0
  120. package/lib/typescript/src/InterstitialAd.d.ts +4 -0
  121. package/lib/typescript/src/InterstitialAd.d.ts.map +1 -0
  122. package/lib/typescript/src/MRecAd.d.ts +4 -0
  123. package/lib/typescript/src/MRecAd.d.ts.map +1 -0
  124. package/lib/typescript/src/RewardedAd.d.ts +4 -0
  125. package/lib/typescript/src/RewardedAd.d.ts.map +1 -0
  126. package/lib/typescript/src/hooks.d.ts +50 -0
  127. package/lib/typescript/src/hooks.d.ts.map +1 -0
  128. package/lib/typescript/src/index.d.ts +23 -0
  129. package/lib/typescript/src/index.d.ts.map +1 -0
  130. package/lib/typescript/src/specs/CloudXAdViewNativeComponent.d.ts +61 -0
  131. package/lib/typescript/src/specs/CloudXAdViewNativeComponent.d.ts.map +1 -0
  132. package/lib/typescript/src/specs/NativeCloudXModule.d.ts +106 -0
  133. package/lib/typescript/src/specs/NativeCloudXModule.d.ts.map +1 -0
  134. package/lib/typescript/src/types/AdEvent.d.ts +10 -0
  135. package/lib/typescript/src/types/AdEvent.d.ts.map +1 -0
  136. package/lib/typescript/src/types/AdInfo.d.ts +48 -0
  137. package/lib/typescript/src/types/AdInfo.d.ts.map +1 -0
  138. package/lib/typescript/src/types/BannerAd.d.ts +39 -0
  139. package/lib/typescript/src/types/BannerAd.d.ts.map +1 -0
  140. package/lib/typescript/src/types/CloudX.d.ts +25 -0
  141. package/lib/typescript/src/types/CloudX.d.ts.map +1 -0
  142. package/lib/typescript/src/types/Configuration.d.ts +10 -0
  143. package/lib/typescript/src/types/Configuration.d.ts.map +1 -0
  144. package/lib/typescript/src/types/FullscreenAd.d.ts +29 -0
  145. package/lib/typescript/src/types/FullscreenAd.d.ts.map +1 -0
  146. package/lib/typescript/src/types/RewardedAd.d.ts +10 -0
  147. package/lib/typescript/src/types/RewardedAd.d.ts.map +1 -0
  148. package/lib/typescript/src/types/index.d.ts +8 -0
  149. package/lib/typescript/src/types/index.d.ts.map +1 -0
  150. package/package.json +78 -0
  151. package/src/AdView.tsx +213 -0
  152. package/src/AppTrackingTransparency.ts +56 -0
  153. package/src/BannerAd.ts +133 -0
  154. package/src/CloudX.ts +55 -0
  155. package/src/ErrorCode.ts +157 -0
  156. package/src/EventEmitter.ts +38 -0
  157. package/src/InterstitialAd.ts +103 -0
  158. package/src/MRecAd.ts +133 -0
  159. package/src/RewardedAd.ts +113 -0
  160. package/src/hooks.ts +292 -0
  161. package/src/index.ts +50 -0
  162. package/src/specs/CloudXAdViewNativeComponent.ts +82 -0
  163. package/src/specs/NativeCloudXModule.ts +162 -0
  164. package/src/types/AdEvent.ts +11 -0
  165. package/src/types/AdInfo.ts +60 -0
  166. package/src/types/BannerAd.ts +59 -0
  167. package/src/types/CloudX.ts +33 -0
  168. package/src/types/Configuration.ts +10 -0
  169. package/src/types/FullscreenAd.ts +39 -0
  170. package/src/types/RewardedAd.ts +10 -0
  171. package/src/types/index.ts +7 -0
package/README.md ADDED
@@ -0,0 +1,1258 @@
1
+ # CloudX React Native SDK
2
+
3
+ A React Native wrapper for the CloudX native SDKs, providing a comprehensive solution for programmatic advertising with full privacy compliance support.
4
+
5
+ ## Features
6
+
7
+ - **Full SDK Integration**: Complete wrapper for CloudX Core SDK
8
+ - **Cross-Platform Ready**: iOS support (Android coming soon)
9
+ - **All Ad Types**: Banner, Interstitial, Rewarded, Native, and MREC ads
10
+ - **Privacy**: IAB privacy compliance is handled by the native SDK automatically
11
+ - **Event System**: React Native event emitter pattern for ad lifecycle management
12
+ - **Error Handling**: Comprehensive error handling with detailed error codes
13
+ - **Type Safety**: Full TypeScript support with complete type definitions
14
+ - **React Hooks**: Custom hooks for seamless React integration
15
+ - **Modern Patterns**: Follows React Native 0.70+ best practices
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install cloudx-react-native
21
+ # or
22
+ yarn add cloudx-react-native
23
+ ```
24
+
25
+ ### iOS Setup
26
+
27
+ 1. Add to your `Podfile`:
28
+
29
+ ```ruby
30
+ # CloudX Core SDK
31
+ pod 'CloudXCore'
32
+
33
+ # Optional: CloudX Adapters
34
+ pod 'CloudXMetaAdapter'
35
+ ```
36
+
37
+ 2. Install pods:
38
+
39
+ ```bash
40
+ cd ios && pod install
41
+ ```
42
+
43
+ 3. Add required permissions to `Info.plist`:
44
+
45
+ ```xml
46
+ <key>NSUserTrackingUsageDescription</key>
47
+ <string>This app uses tracking to provide personalized ads and better user experience.</string>
48
+
49
+ <key>SKAdNetworkItems</key>
50
+ <array>
51
+ <!-- Add your SKAdNetwork IDs -->
52
+ </array>
53
+ ```
54
+
55
+ ### Android Setup
56
+
57
+ > ⚠️ **Android support coming soon**
58
+
59
+ ---
60
+
61
+ ## Quick Start
62
+
63
+ ### 1. Initialize the SDK
64
+
65
+ ```javascript
66
+ import CloudXSDK from 'cloudx-react-native';
67
+
68
+ // Initialize CloudX SDK (testMode: false = production, true = test ads)
69
+ const result = await CloudXSDK.initialize({
70
+ appKey: 'YOUR_APP_KEY',
71
+ testMode: false, // false = production, true = test ads
72
+ });
73
+
74
+ if (result.success) {
75
+ console.log('CloudX SDK initialized successfully');
76
+ } else {
77
+ console.error('Failed to initialize CloudX SDK:', result.message);
78
+ }
79
+
80
+
81
+ // Check if initialized
82
+ const isInitialized = await CloudXSDK.isInitialized();
83
+ ```
84
+
85
+ #### Test Mode
86
+
87
+ The SDK supports an optional `testMode` parameter:
88
+
89
+ - **Production (`testMode: false`)**: Real ads with actual billing. Use for production releases.
90
+ - **Test Mode (`testMode: true`)**: Test ads without billing. Use for development and QA testing.
91
+
92
+ When `testMode` is enabled:
93
+ - Bid requests include `test=1` flag per OpenRTB spec
94
+ - Adapter SDKs are configured for test mode (e.g., Meta test ads)
95
+ - No real monetization occurs
96
+
97
+ ### 2. Using React Hooks (Recommended)
98
+
99
+ ```jsx
100
+ import { useCloudXInterstitial, useCloudXRewarded } from 'cloudx-react-native';
101
+
102
+ function GameOverScreen() {
103
+ const interstitial = useCloudXInterstitial({
104
+ placement: 'game-over-interstitial',
105
+ adId: 'interstitial-1',
106
+ onLoaded: (ad) => console.log('Interstitial ready:', ad.placementName),
107
+ onFailed: (error) => console.error('Failed to load:', error),
108
+ onShown: (ad) => console.log('Interstitial shown'),
109
+ onClosed: (ad) => console.log('Interstitial closed'),
110
+ onRevenuePaid: (ad) => console.log('Revenue:', ad.revenue, ad.currency),
111
+ });
112
+
113
+ return (
114
+ <View>
115
+ <Button
116
+ title="Show Interstitial"
117
+ onPress={() => interstitial.show()}
118
+ disabled={!interstitial.isReady || interstitial.isLoading}
119
+ />
120
+ {interstitial.isLoading && <ActivityIndicator />}
121
+ </View>
122
+ );
123
+ }
124
+ ```
125
+
126
+ ### 3. Banner Ads (Component)
127
+
128
+ ```jsx
129
+ import { CloudXBannerView, BannerSizes } from 'cloudx-react-native';
130
+
131
+ function HomeScreen() {
132
+ return (
133
+ <View style={styles.container}>
134
+ <Text>Your Content Here</Text>
135
+
136
+ <CloudXBannerView
137
+ placement="home-banner"
138
+ adId="banner-1"
139
+ bannerSize={BannerSizes.BANNER}
140
+ autoRefresh={true}
141
+ refreshInterval={30000}
142
+ onAdLoaded={(event) => console.log('Banner loaded:', event.ad)}
143
+ onAdFailedToLoad={(event) => console.error('Banner failed:', event.error)}
144
+ onAdImpression={(event) => trackImpression(event.ad)}
145
+ onRevenuePaid={(event) => trackRevenue(event.ad)}
146
+ style={styles.banner}
147
+ />
148
+ </View>
149
+ );
150
+ }
151
+
152
+ const styles = StyleSheet.create({
153
+ banner: {
154
+ width: 320,
155
+ height: 50,
156
+ marginVertical: 10,
157
+ },
158
+ });
159
+ ```
160
+
161
+ ---
162
+
163
+ ## API Reference
164
+
165
+ ### SDK Initialization
166
+
167
+ #### `initialize(appKey: string | InitOptions): Promise<InitResult>`
168
+
169
+ Initialize the CloudX SDK. Must be called before using any other SDK methods.
170
+
171
+ ```javascript
172
+ // Production initialization
173
+ const result = await CloudXSDK.initialize({
174
+ appKey: 'YOUR_APP_KEY',
175
+ testMode: false, // false = production, true = test ads
176
+ });
177
+
178
+ // result = { success: boolean, message?: string }
179
+ ```
180
+
181
+ **InitOptions:**
182
+ - `appKey` (string, required): Your CloudX app key
183
+ - `testMode` (boolean, optional): Enable test mode (false = production, true = test ads)
184
+
185
+ **Note:** To set a hashed user ID for targeting, call `CloudXSDK.setHashedUserID()` separately before or after initialization.
186
+
187
+ #### `isInitialized(): Promise<boolean>`
188
+
189
+ Check if the SDK has been initialized.
190
+
191
+ ```javascript
192
+ const initialized = await CloudXSDK.isInitialized();
193
+ ```
194
+
195
+ #### `getVersion(): Promise<string>`
196
+
197
+ Get the CloudX SDK version.
198
+
199
+ ```javascript
200
+ const version = await CloudXSDK.getVersion();
201
+ console.log('CloudX SDK version:', version);
202
+ ```
203
+
204
+ #### `setLoggingEnabled(enabled: boolean): Promise<void>`
205
+
206
+ Enable or disable verbose SDK logging (useful for debugging).
207
+
208
+ ```javascript
209
+ // Enable logging in development
210
+ if (__DEV__) {
211
+ await CloudXSDK.setLoggingEnabled(true);
212
+ }
213
+ ```
214
+
215
+ #### `setEnvironment(environment: 'dev' | 'staging' | 'production'): Promise<void>`
216
+
217
+ Set the SDK environment. Must be called **before** `initialize()`.
218
+
219
+ ```javascript
220
+ await CloudXSDK.setEnvironment('staging');
221
+ await CloudXSDK.initialize('YOUR_APP_KEY');
222
+ ```
223
+
224
+ ---
225
+
226
+ ## User Targeting
227
+
228
+ ### Hashed User ID
229
+
230
+ ```javascript
231
+ // Set hashed user ID for targeting
232
+ await CloudXSDK.setHashedUserID('hashed-email-or-user-id');
233
+
234
+ // Get current user ID
235
+ const userId = await CloudXSDK.getUserID();
236
+
237
+ // Clear user ID
238
+ await CloudXSDK.setUserID(null);
239
+ ```
240
+
241
+ ### User-Level Targeting
242
+
243
+ User-level key-values are **cleared automatically** when privacy regulations require removing personal data.
244
+
245
+ ```javascript
246
+ import { CloudX } from 'cloudx-react-native';
247
+
248
+ // User-specific targeting (privacy-sensitive)
249
+ CloudX.setUserKeyValue('age', '25');
250
+ CloudX.setUserKeyValue('interests', 'gaming');
251
+ CloudX.setUserKeyValue('subscription', 'premium');
252
+ ```
253
+
254
+ ### App-Level Targeting
255
+
256
+ App-level key-values are **NOT affected** by privacy regulations and persist across privacy changes.
257
+
258
+ ```javascript
259
+ // App-specific targeting (persistent)
260
+ CloudX.setAppKeyValue('app_version', '1.2.0');
261
+ CloudX.setAppKeyValue('build_type', 'release');
262
+ CloudX.setAppKeyValue('theme', 'dark');
263
+ ```
264
+
265
+ ### Clear Targeting
266
+
267
+ ```javascript
268
+ // Clear all targeting key-values
269
+ CloudX.clearAllKeyValues();
270
+ ```
271
+
272
+ ---
273
+
274
+ ## Banner Ads
275
+
276
+ ### Using BannerView Component (Recommended)
277
+
278
+ ```jsx
279
+ import { CloudXBannerView, BannerSizes } from 'cloudx-react-native';
280
+
281
+ function MyComponent() {
282
+ return (
283
+ <CloudXBannerView
284
+ // Required
285
+ placement="banner-placement"
286
+ adId="banner-1"
287
+
288
+ // Optional
289
+ bannerSize={BannerSizes.BANNER} // BANNER, MREC, LEADERBOARD
290
+ autoRefresh={true}
291
+ refreshInterval={30000} // milliseconds
292
+
293
+ // Event callbacks
294
+ onAdLoaded={(event) => console.log('Banner loaded:', event.ad)}
295
+ onAdFailedToLoad={(event) => console.error('Failed:', event.error)}
296
+ onAdShown={(event) => console.log('Banner shown')}
297
+ onAdImpression={(event) => console.log('Impression tracked')}
298
+ onAdClicked={(event) => console.log('Banner clicked')}
299
+ onAdExpanded={(event) => console.log('Banner expanded')}
300
+ onAdCollapsed={(event) => console.log('Banner collapsed')}
301
+ onRevenuePaid={(event) => console.log('Revenue:', event.ad.revenue)}
302
+
303
+ // Styling
304
+ style={{ width: 320, height: 50 }}
305
+ />
306
+ );
307
+ }
308
+ ```
309
+
310
+ ### Using Custom Hook
311
+
312
+ ```jsx
313
+ import { useCloudXBanner } from 'cloudx-react-native';
314
+
315
+ function MyComponent() {
316
+ const banner = useCloudXBanner({
317
+ placement: 'banner-placement',
318
+ adId: 'banner-1',
319
+ bannerSize: BannerSizes.BANNER,
320
+ autoRefresh: true,
321
+ onLoaded: (ad) => console.log('Banner ready'),
322
+ onRevenuePaid: (ad) => trackRevenue(ad),
323
+ });
324
+
325
+ return (
326
+ <View>
327
+ {banner.render({ style: styles.banner })}
328
+ {banner.isLoading && <ActivityIndicator />}
329
+ </View>
330
+ );
331
+ }
332
+ ```
333
+
334
+ ### Imperative API
335
+
336
+ ```javascript
337
+ // Create banner
338
+ await CloudXSDK.createBanner({
339
+ placement: 'banner-placement',
340
+ adId: 'banner-1',
341
+ bannerSize: BannerSizes.BANNER,
342
+ });
343
+
344
+ // Load banner
345
+ await CloudXSDK.loadBanner({ adId: 'banner-1' });
346
+
347
+ // Show banner (if hidden)
348
+ await CloudXSDK.showBanner({ adId: 'banner-1' });
349
+
350
+ // Hide banner (keeps it loaded)
351
+ await CloudXSDK.hideBanner({ adId: 'banner-1' });
352
+
353
+ // Auto-refresh control
354
+ await CloudXSDK.startAutoRefresh({ adId: 'banner-1' });
355
+ await CloudXSDK.stopAutoRefresh({ adId: 'banner-1' });
356
+
357
+ // Destroy banner (cleanup)
358
+ await CloudXSDK.destroyAd({ adId: 'banner-1' });
359
+ ```
360
+
361
+ ### Banner Sizes
362
+
363
+ ```javascript
364
+ export const BannerSizes = {
365
+ BANNER: 'BANNER', // 320x50
366
+ MREC: 'MREC', // 300x250
367
+ LEADERBOARD: 'LEADERBOARD', // 728x90
368
+ };
369
+ ```
370
+
371
+ ---
372
+
373
+ ## Interstitial Ads
374
+
375
+ ### Using React Hook (Recommended)
376
+
377
+ ```jsx
378
+ import { useCloudXInterstitial } from 'cloudx-react-native';
379
+
380
+ function GameOverScreen() {
381
+ const interstitial = useCloudXInterstitial({
382
+ placement: 'game-over-interstitial',
383
+ adId: 'interstitial-1',
384
+
385
+ // Event callbacks
386
+ onLoaded: (ad) => {
387
+ console.log('Interstitial ready:', ad.placementName);
388
+ setAdReady(true);
389
+ },
390
+ onFailedToLoad: (error) => {
391
+ console.error('Failed to load:', error);
392
+ },
393
+ onShown: (ad) => {
394
+ console.log('Interstitial shown');
395
+ pauseGame();
396
+ },
397
+ onFailedToShow: (error) => {
398
+ console.error('Failed to show:', error);
399
+ },
400
+ onImpression: (ad) => {
401
+ console.log('Impression tracked:', ad.revenue);
402
+ },
403
+ onClosed: (ad) => {
404
+ console.log('Interstitial closed');
405
+ resumeGame();
406
+ },
407
+ onClicked: (ad) => {
408
+ console.log('Interstitial clicked');
409
+ },
410
+ onRevenuePaid: (ad) => {
411
+ console.log('Revenue:', ad.revenue, ad.currency);
412
+ trackRevenue(ad);
413
+ },
414
+ });
415
+
416
+ useEffect(() => {
417
+ // Auto-load on mount
418
+ interstitial.load();
419
+
420
+ // Cleanup on unmount
421
+ return () => {
422
+ interstitial.destroy();
423
+ };
424
+ }, []);
425
+
426
+ return (
427
+ <View>
428
+ <Text>Game Over!</Text>
429
+ <Button
430
+ title="Continue (Watch Ad)"
431
+ onPress={() => interstitial.show()}
432
+ disabled={!interstitial.isReady || interstitial.isShowing}
433
+ />
434
+ {interstitial.isLoading && <ActivityIndicator />}
435
+ </View>
436
+ );
437
+ }
438
+ ```
439
+
440
+ ### Imperative API
441
+
442
+ ```javascript
443
+ // Create interstitial
444
+ await CloudXSDK.createInterstitial({
445
+ placement: 'interstitial-placement',
446
+ adId: 'interstitial-1',
447
+ });
448
+
449
+ // Load interstitial
450
+ await CloudXSDK.loadInterstitial({ adId: 'interstitial-1' });
451
+
452
+ // Check if ready
453
+ const isReady = await CloudXSDK.isInterstitialReady({ adId: 'interstitial-1' });
454
+
455
+ // Show interstitial
456
+ if (isReady) {
457
+ await CloudXSDK.showInterstitial({ adId: 'interstitial-1' });
458
+ }
459
+
460
+ // Destroy when done
461
+ await CloudXSDK.destroyAd({ adId: 'interstitial-1' });
462
+ ```
463
+
464
+ ---
465
+
466
+ ## Rewarded Ads
467
+
468
+ ### Using React Hook (Recommended)
469
+
470
+ ```jsx
471
+ import { useCloudXRewarded } from 'cloudx-react-native';
472
+
473
+ function RewardButton() {
474
+ const rewarded = useCloudXRewarded({
475
+ placement: 'extra-lives-rewarded',
476
+ adId: 'rewarded-1',
477
+
478
+ onLoaded: (ad) => console.log('Rewarded ad ready'),
479
+ onFailedToLoad: (error) => console.error('Failed:', error),
480
+ onShown: (ad) => console.log('Showing rewarded ad'),
481
+ onRewardEarned: (ad) => {
482
+ console.log('🎉 User earned reward!');
483
+ grantExtraLife();
484
+ },
485
+ onVideoStarted: (ad) => console.log('Video started'),
486
+ onVideoCompleted: (ad) => console.log('Video completed'),
487
+ onClosed: (ad) => console.log('Rewarded ad closed'),
488
+ onRevenuePaid: (ad) => trackRevenue(ad),
489
+ });
490
+
491
+ useEffect(() => {
492
+ rewarded.load();
493
+ return () => rewarded.destroy();
494
+ }, []);
495
+
496
+ return (
497
+ <Button
498
+ title="Watch Ad for Extra Life"
499
+ onPress={() => rewarded.show()}
500
+ disabled={!rewarded.isReady}
501
+ />
502
+ );
503
+ }
504
+ ```
505
+
506
+ ### Imperative API
507
+
508
+ ```javascript
509
+ // Create rewarded ad
510
+ await CloudXSDK.createRewarded({
511
+ placement: 'rewarded-placement',
512
+ adId: 'rewarded-1',
513
+ });
514
+
515
+ // Load rewarded ad
516
+ await CloudXSDK.loadRewarded({ adId: 'rewarded-1' });
517
+
518
+ // Check if ready
519
+ const isReady = await CloudXSDK.isRewardedReady({ adId: 'rewarded-1' });
520
+
521
+ // Show rewarded ad
522
+ if (isReady) {
523
+ await CloudXSDK.showRewarded({ adId: 'rewarded-1' });
524
+ }
525
+
526
+ // Listen for reward event
527
+ const listener = CloudXSDK.addEventListener(
528
+ CloudXEventTypes.REWARD_EARNED,
529
+ (event) => {
530
+ if (event.ad.adId === 'rewarded-1') {
531
+ console.log('User earned reward!');
532
+ grantReward();
533
+ }
534
+ }
535
+ );
536
+
537
+ // Clean up
538
+ listener.remove();
539
+ await CloudXSDK.destroyAd({ adId: 'rewarded-1' });
540
+ ```
541
+
542
+ ---
543
+
544
+ ## Native Ads
545
+
546
+ ### Using React Hook (Recommended)
547
+
548
+ ```jsx
549
+ import { useCloudXNative } from 'cloudx-react-native';
550
+
551
+ function FeedItemAd({ index }) {
552
+ const nativeAd = useCloudXNative({
553
+ placement: 'feed-native',
554
+ adId: `native-${index}`,
555
+
556
+ onLoaded: (ad) => {
557
+ console.log('Native ad loaded:', ad.assets);
558
+ },
559
+ onFailedToLoad: (error) => console.error('Failed:', error),
560
+ onImpression: (ad) => trackImpression(ad),
561
+ onClicked: (ad) => console.log('Native ad clicked'),
562
+ onRevenuePaid: (ad) => trackRevenue(ad),
563
+ });
564
+
565
+ useEffect(() => {
566
+ nativeAd.load();
567
+ return () => nativeAd.destroy();
568
+ }, []);
569
+
570
+ if (!nativeAd.isLoaded || !nativeAd.assets) {
571
+ return null;
572
+ }
573
+
574
+ return (
575
+ <View style={styles.nativeAd}>
576
+ {nativeAd.assets.iconUrl && (
577
+ <Image source={{ uri: nativeAd.assets.iconUrl }} style={styles.icon} />
578
+ )}
579
+ <View style={styles.content}>
580
+ <Text style={styles.title}>{nativeAd.assets.title}</Text>
581
+ <Text style={styles.body}>{nativeAd.assets.body}</Text>
582
+ {nativeAd.assets.callToAction && (
583
+ <TouchableOpacity
584
+ style={styles.cta}
585
+ onPress={() => nativeAd.click()}
586
+ >
587
+ <Text style={styles.ctaText}>{nativeAd.assets.callToAction}</Text>
588
+ </TouchableOpacity>
589
+ )}
590
+ </View>
591
+ <Text style={styles.adBadge}>Ad</Text>
592
+ </View>
593
+ );
594
+ }
595
+ ```
596
+
597
+ ### Imperative API
598
+
599
+ ```javascript
600
+ // Create native ad
601
+ await CloudXSDK.createNative({
602
+ placement: 'native-placement',
603
+ adId: 'native-1',
604
+ });
605
+
606
+ // Load native ad
607
+ await CloudXSDK.loadNative({ adId: 'native-1' });
608
+
609
+ // Get native ad assets
610
+ const assets = await CloudXSDK.getNativeAdAssets({ adId: 'native-1' });
611
+ // assets = {
612
+ // title: string,
613
+ // body: string,
614
+ // callToAction: string,
615
+ // iconUrl: string,
616
+ // imageUrl: string,
617
+ // starRating: number,
618
+ // advertiser: string,
619
+ // }
620
+
621
+ // Register view for impression tracking
622
+ await CloudXSDK.registerNativeAdView({ adId: 'native-1' });
623
+
624
+ // Track click
625
+ await CloudXSDK.trackNativeAdClick({ adId: 'native-1' });
626
+
627
+ // Destroy
628
+ await CloudXSDK.destroyAd({ adId: 'native-1' });
629
+ ```
630
+
631
+ ---
632
+
633
+ ## MREC Ads
634
+
635
+ MREC (Medium Rectangle) ads are 300x250 banner ads commonly used in content feeds.
636
+
637
+ ### Using Component
638
+
639
+ ```jsx
640
+ import { CloudXBannerView, BannerSizes } from 'cloudx-react-native';
641
+
642
+ function ContentFeed() {
643
+ return (
644
+ <ScrollView>
645
+ <Article />
646
+ <Article />
647
+
648
+ {/* MREC ad between content */}
649
+ <CloudXBannerView
650
+ placement="feed-mrec"
651
+ adId="mrec-1"
652
+ bannerSize={BannerSizes.MREC}
653
+ autoRefresh={true}
654
+ onAdLoaded={(event) => console.log('MREC loaded')}
655
+ onRevenuePaid={(event) => trackRevenue(event.ad)}
656
+ style={{ width: 300, height: 250, alignSelf: 'center' }}
657
+ />
658
+
659
+ <Article />
660
+ <Article />
661
+ </ScrollView>
662
+ );
663
+ }
664
+ ```
665
+
666
+ ---
667
+
668
+ ## Event Handling
669
+
670
+ ### Event Types
671
+
672
+ ```javascript
673
+ import { CloudXEventTypes } from 'cloudx-react-native';
674
+
675
+ // Banner Events
676
+ CloudXEventTypes.BANNER_LOADED
677
+ CloudXEventTypes.BANNER_FAILED_TO_LOAD
678
+ CloudXEventTypes.BANNER_SHOWN
679
+ CloudXEventTypes.BANNER_FAILED_TO_SHOW
680
+ CloudXEventTypes.BANNER_HIDDEN
681
+ CloudXEventTypes.BANNER_CLICKED
682
+ CloudXEventTypes.BANNER_IMPRESSION
683
+ CloudXEventTypes.BANNER_EXPANDED
684
+ CloudXEventTypes.BANNER_COLLAPSED
685
+ CloudXEventTypes.BANNER_REVENUE_PAID
686
+
687
+ // Interstitial Events
688
+ CloudXEventTypes.INTERSTITIAL_LOADED
689
+ CloudXEventTypes.INTERSTITIAL_FAILED_TO_LOAD
690
+ CloudXEventTypes.INTERSTITIAL_SHOWN
691
+ CloudXEventTypes.INTERSTITIAL_FAILED_TO_SHOW
692
+ CloudXEventTypes.INTERSTITIAL_CLOSED
693
+ CloudXEventTypes.INTERSTITIAL_CLICKED
694
+ CloudXEventTypes.INTERSTITIAL_IMPRESSION
695
+ CloudXEventTypes.INTERSTITIAL_CLOSED_BY_USER
696
+ CloudXEventTypes.INTERSTITIAL_REVENUE_PAID
697
+
698
+ // Rewarded Events
699
+ CloudXEventTypes.REWARDED_LOADED
700
+ CloudXEventTypes.REWARDED_FAILED_TO_LOAD
701
+ CloudXEventTypes.REWARDED_SHOWN
702
+ CloudXEventTypes.REWARDED_FAILED_TO_SHOW
703
+ CloudXEventTypes.REWARDED_CLOSED
704
+ CloudXEventTypes.REWARDED_CLICKED
705
+ CloudXEventTypes.REWARDED_IMPRESSION
706
+ CloudXEventTypes.REWARDED_CLOSED_BY_USER
707
+ CloudXEventTypes.REWARDED_REVENUE_PAID
708
+ CloudXEventTypes.REWARD_EARNED
709
+ CloudXEventTypes.REWARDED_VIDEO_STARTED
710
+ CloudXEventTypes.REWARDED_VIDEO_COMPLETED
711
+
712
+ // Native Events
713
+ CloudXEventTypes.NATIVE_LOADED
714
+ CloudXEventTypes.NATIVE_FAILED_TO_LOAD
715
+ CloudXEventTypes.NATIVE_SHOWN
716
+ CloudXEventTypes.NATIVE_CLICKED
717
+ CloudXEventTypes.NATIVE_IMPRESSION
718
+ CloudXEventTypes.NATIVE_REVENUE_PAID
719
+ ```
720
+
721
+ ### Using Event Emitter
722
+
723
+ ```javascript
724
+ import CloudXSDK, { CloudXEventTypes } from 'cloudx-react-native';
725
+
726
+ // Add listener
727
+ const listener = CloudXSDK.addEventListener(
728
+ CloudXEventTypes.INTERSTITIAL_LOADED,
729
+ (event) => {
730
+ console.log('Ad loaded:', event.ad.adId);
731
+ console.log('Placement:', event.ad.placementName);
732
+ }
733
+ );
734
+
735
+ // Remove specific listener
736
+ listener.remove();
737
+
738
+ // Remove all listeners for an event
739
+ CloudXSDK.removeAllListeners(CloudXEventTypes.INTERSTITIAL_LOADED);
740
+
741
+ // Remove all listeners
742
+ CloudXSDK.removeAllListeners();
743
+ ```
744
+
745
+ ### Event Payload
746
+
747
+ All events receive a payload with the following structure:
748
+
749
+ ```typescript
750
+ interface CloudXAdEvent {
751
+ ad?: CloudXAd;
752
+ error?: string;
753
+ timestamp: number;
754
+ }
755
+
756
+ interface CloudXAd {
757
+ adId: string;
758
+ placementName: string;
759
+ adType: 'banner' | 'interstitial' | 'rewarded' | 'native' | 'mrec';
760
+ revenue?: number;
761
+ currency?: string;
762
+ network?: string;
763
+ lineItemId?: string;
764
+ }
765
+ ```
766
+
767
+ ### Using with React
768
+
769
+ ```jsx
770
+ import { useEffect } from 'react';
771
+ import CloudXSDK, { CloudXEventTypes } from 'cloudx-react-native';
772
+
773
+ function MyComponent() {
774
+ useEffect(() => {
775
+ const listener = CloudXSDK.addEventListener(
776
+ CloudXEventTypes.INTERSTITIAL_LOADED,
777
+ handleInterstitialLoaded
778
+ );
779
+
780
+ return () => {
781
+ listener.remove(); // Cleanup on unmount
782
+ };
783
+ }, []);
784
+
785
+ const handleInterstitialLoaded = (event) => {
786
+ console.log('Interstitial ready:', event.ad);
787
+ };
788
+
789
+ return <View>...</View>;
790
+ }
791
+ ```
792
+
793
+ ---
794
+
795
+ ## Error Handling
796
+
797
+ ### Error Codes
798
+
799
+ ```javascript
800
+ // Common error codes
801
+ const ErrorCodes = {
802
+ NO_FILL: 'NO_FILL', // No ad available
803
+ TIMEOUT: 'TIMEOUT', // Request timed out
804
+ NETWORK_ERROR: 'NETWORK_ERROR', // Network issue
805
+ INVALID_PLACEMENT: 'INVALID_PLACEMENT', // Placement not configured
806
+ SDK_NOT_INITIALIZED: 'SDK_NOT_INITIALIZED', // Must initialize first
807
+ AD_NOT_READY: 'AD_NOT_READY', // Ad not loaded yet
808
+ AD_ALREADY_SHOWN: 'AD_ALREADY_SHOWN', // Ad already displayed
809
+ INVALID_AD_ID: 'INVALID_AD_ID', // Ad ID not found
810
+ };
811
+ ```
812
+
813
+ ### Handling Errors
814
+
815
+ ```javascript
816
+ // Try-catch for async methods
817
+ try {
818
+ await CloudXSDK.loadInterstitial({ adId: 'interstitial-1' });
819
+ } catch (error) {
820
+ if (error.code === 'NO_FILL') {
821
+ console.log('No ad available, continue without ad');
822
+ } else if (error.code === 'NETWORK_ERROR') {
823
+ console.log('Network error, retry later');
824
+ setTimeout(() => retry(), 5000);
825
+ } else {
826
+ console.error('Unexpected error:', error);
827
+ }
828
+ }
829
+
830
+ // Error events
831
+ CloudXSDK.addEventListener(
832
+ CloudXEventTypes.INTERSTITIAL_FAILED_TO_LOAD,
833
+ (event) => {
834
+ console.error('Failed to load ad:', event.error);
835
+
836
+ // Handle specific errors
837
+ switch (event.error) {
838
+ case 'NO_FILL':
839
+ // Show alternative content
840
+ break;
841
+ case 'TIMEOUT':
842
+ // Retry with longer timeout
843
+ break;
844
+ default:
845
+ // Generic error handling
846
+ }
847
+ }
848
+ );
849
+ ```
850
+
851
+ ### Best Practices
852
+
853
+ ```javascript
854
+ async function showInterstitialSafely(adId: string) {
855
+ try {
856
+ // Check if SDK is initialized
857
+ const initialized = await CloudXSDK.isInitialized();
858
+ if (!initialized) {
859
+ throw new Error('SDK not initialized');
860
+ }
861
+
862
+ // Check if ad is ready
863
+ const isReady = await CloudXSDK.isInterstitialReady({ adId });
864
+ if (!isReady) {
865
+ console.log('Ad not ready, loading...');
866
+ await CloudXSDK.loadInterstitial({ adId });
867
+ // Wait for load event before showing
868
+ return;
869
+ }
870
+
871
+ // Show the ad
872
+ await CloudXSDK.showInterstitial({ adId });
873
+ } catch (error) {
874
+ console.error('Error showing interstitial:', error);
875
+ // Continue app flow without ad
876
+ }
877
+ }
878
+ ```
879
+
880
+ ---
881
+
882
+ ## Advanced Usage
883
+
884
+ ### Multiple Ad Instances
885
+
886
+ ```javascript
887
+ // Create multiple instances of the same placement
888
+ await CloudXSDK.createInterstitial({
889
+ placement: 'level-complete',
890
+ adId: 'level-1-interstitial',
891
+ });
892
+
893
+ await CloudXSDK.createInterstitial({
894
+ placement: 'level-complete',
895
+ adId: 'level-2-interstitial',
896
+ });
897
+
898
+ // Each instance is managed independently
899
+ await CloudXSDK.loadInterstitial({ adId: 'level-1-interstitial' });
900
+ await CloudXSDK.loadInterstitial({ adId: 'level-2-interstitial' });
901
+ ```
902
+
903
+ ### Preloading Ads
904
+
905
+ ```javascript
906
+ // Preload ads early for better UX
907
+ async function preloadAds() {
908
+ // Preload interstitial
909
+ await CloudXSDK.createInterstitial({
910
+ placement: 'game-over',
911
+ adId: 'preloaded-interstitial',
912
+ });
913
+ await CloudXSDK.loadInterstitial({ adId: 'preloaded-interstitial' });
914
+
915
+ // Preload rewarded
916
+ await CloudXSDK.createRewarded({
917
+ placement: 'extra-life',
918
+ adId: 'preloaded-rewarded',
919
+ });
920
+ await CloudXSDK.loadRewarded({ adId: 'preloaded-rewarded' });
921
+ }
922
+
923
+ // Call during app initialization or loading screens
924
+ useEffect(() => {
925
+ preloadAds();
926
+ }, []);
927
+ ```
928
+
929
+ ### Ad Frequency Capping
930
+
931
+ ```javascript
932
+ // Implement your own frequency capping
933
+ class AdFrequencyCapper {
934
+ constructor(maxAdsPerHour = 5) {
935
+ this.maxAdsPerHour = maxAdsPerHour;
936
+ this.adTimestamps = [];
937
+ }
938
+
939
+ canShowAd() {
940
+ const oneHourAgo = Date.now() - 60 * 60 * 1000;
941
+ this.adTimestamps = this.adTimestamps.filter(ts => ts > oneHourAgo);
942
+ return this.adTimestamps.length < this.maxAdsPerHour;
943
+ }
944
+
945
+ recordAdShown() {
946
+ this.adTimestamps.push(Date.now());
947
+ }
948
+ }
949
+
950
+ const frequencyCapper = new AdFrequencyCapper(5);
951
+
952
+ async function showInterstitialWithCapping(adId: string) {
953
+ if (!frequencyCapper.canShowAd()) {
954
+ console.log('Ad frequency cap reached');
955
+ return;
956
+ }
957
+
958
+ try {
959
+ await CloudXSDK.showInterstitial({ adId });
960
+ frequencyCapper.recordAdShown();
961
+ } catch (error) {
962
+ console.error('Failed to show ad:', error);
963
+ }
964
+ }
965
+ ```
966
+
967
+ ### Revenue Tracking
968
+
969
+ ```javascript
970
+ // Track revenue from all ad types
971
+ CloudXSDK.addEventListener(
972
+ CloudXEventTypes.INTERSTITIAL_REVENUE_PAID,
973
+ (event) => trackRevenue(event.ad)
974
+ );
975
+
976
+ CloudXSDK.addEventListener(
977
+ CloudXEventTypes.REWARDED_REVENUE_PAID,
978
+ (event) => trackRevenue(event.ad)
979
+ );
980
+
981
+ CloudXSDK.addEventListener(
982
+ CloudXEventTypes.BANNER_REVENUE_PAID,
983
+ (event) => trackRevenue(event.ad)
984
+ );
985
+
986
+ function trackRevenue(ad: CloudXAd) {
987
+ if (ad.revenue && ad.currency) {
988
+ // Send to analytics
989
+ Analytics.logRevenue({
990
+ amount: ad.revenue,
991
+ currency: ad.currency,
992
+ adNetwork: ad.network,
993
+ adType: ad.adType,
994
+ placement: ad.placementName,
995
+ });
996
+
997
+ console.log(
998
+ `💰 Revenue: ${ad.currency} ${ad.revenue} from ${ad.network}`
999
+ );
1000
+ }
1001
+ }
1002
+ ```
1003
+
1004
+ ---
1005
+
1006
+ ## React Hooks API
1007
+
1008
+ ### useCloudXInterstitial
1009
+
1010
+ ```typescript
1011
+ interface UseInterstitialOptions {
1012
+ placement: string;
1013
+ adId: string;
1014
+ onLoaded?: (ad: CloudXAd) => void;
1015
+ onFailedToLoad?: (error: string) => void;
1016
+ onShown?: (ad: CloudXAd) => void;
1017
+ onFailedToShow?: (error: string) => void;
1018
+ onClosed?: (ad: CloudXAd) => void;
1019
+ onClicked?: (ad: CloudXAd) => void;
1020
+ onImpression?: (ad: CloudXAd) => void;
1021
+ onRevenuePaid?: (ad: CloudXAd) => void;
1022
+ autoLoad?: boolean; // Default: false
1023
+ }
1024
+
1025
+ interface UseInterstitialResult {
1026
+ isReady: boolean;
1027
+ isLoading: boolean;
1028
+ isShowing: boolean;
1029
+ error: string | null;
1030
+ load: () => Promise<void>;
1031
+ show: () => Promise<void>;
1032
+ destroy: () => Promise<void>;
1033
+ }
1034
+
1035
+ const interstitial = useCloudXInterstitial(options);
1036
+ ```
1037
+
1038
+ ### useCloudXRewarded
1039
+
1040
+ ```typescript
1041
+ interface UseRewardedOptions extends UseInterstitialOptions {
1042
+ onRewardEarned?: (ad: CloudXAd) => void;
1043
+ onVideoStarted?: (ad: CloudXAd) => void;
1044
+ onVideoCompleted?: (ad: CloudXAd) => void;
1045
+ }
1046
+
1047
+ interface UseRewardedResult extends UseInterstitialResult {
1048
+ // Same as interstitial
1049
+ }
1050
+
1051
+ const rewarded = useCloudXRewarded(options);
1052
+ ```
1053
+
1054
+ ### useCloudXBanner
1055
+
1056
+ ```typescript
1057
+ interface UseBannerOptions {
1058
+ placement: string;
1059
+ adId: string;
1060
+ bannerSize?: BannerSize;
1061
+ autoRefresh?: boolean;
1062
+ refreshInterval?: number;
1063
+ onLoaded?: (ad: CloudXAd) => void;
1064
+ onFailedToLoad?: (error: string) => void;
1065
+ onShown?: (ad: CloudXAd) => void;
1066
+ onImpression?: (ad: CloudXAd) => void;
1067
+ onClicked?: (ad: CloudXAd) => void;
1068
+ onRevenuePaid?: (ad: CloudXAd) => void;
1069
+ }
1070
+
1071
+ interface UseBannerResult {
1072
+ isLoaded: boolean;
1073
+ isVisible: boolean;
1074
+ error: string | null;
1075
+ render: (props?: ViewProps) => React.ReactElement;
1076
+ show: () => Promise<void>;
1077
+ hide: () => Promise<void>;
1078
+ destroy: () => Promise<void>;
1079
+ }
1080
+
1081
+ const banner = useCloudXBanner(options);
1082
+ ```
1083
+
1084
+ ### useCloudXNative
1085
+
1086
+ ```typescript
1087
+ interface UseNativeOptions {
1088
+ placement: string;
1089
+ adId: string;
1090
+ onLoaded?: (ad: CloudXAd) => void;
1091
+ onFailedToLoad?: (error: string) => void;
1092
+ onImpression?: (ad: CloudXAd) => void;
1093
+ onClicked?: (ad: CloudXAd) => void;
1094
+ onRevenuePaid?: (ad: CloudXAd) => void;
1095
+ }
1096
+
1097
+ interface UseNativeResult {
1098
+ isLoaded: boolean;
1099
+ assets: NativeAdAssets | null;
1100
+ error: string | null;
1101
+ load: () => Promise<void>;
1102
+ click: () => Promise<void>;
1103
+ destroy: () => Promise<void>;
1104
+ }
1105
+
1106
+ const nativeAd = useCloudXNative(options);
1107
+ ```
1108
+
1109
+ ---
1110
+
1111
+ ## TypeScript Support
1112
+
1113
+ The SDK is fully typed with TypeScript definitions included.
1114
+
1115
+ ```typescript
1116
+ import CloudXSDK, {
1117
+ CloudXAd,
1118
+ CloudXAdEvent,
1119
+ CloudXEventTypes,
1120
+ BannerSizes,
1121
+ CloudXBannerView,
1122
+ useCloudXInterstitial,
1123
+ useCloudXRewarded,
1124
+ useCloudXBanner,
1125
+ useCloudXNative,
1126
+ } from 'cloudx-react-native';
1127
+
1128
+ // All types are exported and fully documented
1129
+ ```
1130
+
1131
+ ---
1132
+
1133
+ ## Platform Support
1134
+
1135
+ | Platform | Status | Minimum Version |
1136
+ |----------|--------|-----------------|
1137
+ | iOS | ✅ Supported | iOS 14.0+ |
1138
+ | Android | 🚧 Coming Soon | API 21+ (Android 5.0+) |
1139
+
1140
+ ### Requirements
1141
+
1142
+ #### iOS
1143
+ - iOS 14.0 or higher
1144
+ - CocoaPods
1145
+ - Xcode 13.0+
1146
+
1147
+ #### Android
1148
+ - Android API 21 (Android 5.0) or higher
1149
+ - Gradle 8.0+
1150
+ - Kotlin 1.8+
1151
+
1152
+ #### React Native
1153
+ - React Native 0.70+
1154
+ - React 18.0+
1155
+ - TypeScript 4.5+ (optional but recommended)
1156
+
1157
+ ---
1158
+
1159
+ ## Troubleshooting
1160
+
1161
+ ### SDK Not Initializing
1162
+
1163
+ ```javascript
1164
+ // Make sure to await initialization with explicit testMode
1165
+ const result = await CloudXSDK.initialize({
1166
+ appKey: 'YOUR_APP_KEY',
1167
+ testMode: false, // Explicit for production
1168
+ });
1169
+ if (!result.success) {
1170
+ console.error('Initialization failed:', result.message);
1171
+ }
1172
+
1173
+ // Check iOS setup
1174
+ // 1. Verify CloudXCore pod is installed
1175
+ // 2. Run `pod install` in ios/ directory
1176
+ // 3. Check Info.plist has required permissions
1177
+ ```
1178
+
1179
+ ### Ads Not Loading
1180
+
1181
+ ```javascript
1182
+ // 1. Check SDK is initialized
1183
+ const initialized = await CloudXSDK.isInitialized();
1184
+
1185
+ // 2. Enable logging to see detailed errors
1186
+ await CloudXSDK.setLoggingEnabled(true);
1187
+
1188
+ // 3. Check placement is configured in CloudX dashboard
1189
+
1190
+ // 4. Verify network connectivity
1191
+
1192
+ // 5. Check for error events
1193
+ CloudXSDK.addEventListener(
1194
+ CloudXEventTypes.INTERSTITIAL_FAILED_TO_LOAD,
1195
+ (event) => console.error('Load error:', event.error)
1196
+ );
1197
+ ```
1198
+
1199
+ ### Memory Leaks
1200
+
1201
+ ```javascript
1202
+ // Always destroy ads when done
1203
+ useEffect(() => {
1204
+ return () => {
1205
+ CloudXSDK.destroyAd({ adId: 'my-ad' });
1206
+ };
1207
+ }, []);
1208
+
1209
+ // Remove event listeners
1210
+ useEffect(() => {
1211
+ const listener = CloudXSDK.addEventListener(...);
1212
+ return () => listener.remove();
1213
+ }, []);
1214
+ ```
1215
+
1216
+ ---
1217
+
1218
+ ## Examples
1219
+
1220
+ Complete example application is available in the [example/](example/) directory.
1221
+
1222
+ ```bash
1223
+ # Run example app
1224
+ cd example
1225
+ npm install
1226
+ cd ios && pod install && cd ..
1227
+ npm run ios
1228
+ ```
1229
+
1230
+ ---
1231
+
1232
+ ## Documentation
1233
+
1234
+ - **[SDK Audit](SDK_AUDIT.md)**: Detailed comparison with Flutter SDK and implementation roadmap
1235
+ - **[API Reference](https://docs.cloudx.io/react-native)**: Complete API documentation
1236
+ - **[iOS Integration Guide](https://docs.cloudx.io/ios)**: CloudX iOS SDK documentation
1237
+
1238
+ ---
1239
+
1240
+ ## Support
1241
+
1242
+ For technical support and questions:
1243
+
1244
+ - 📧 **Email**: support@cloudx.io
1245
+ - 🐛 **Issues**: [GitHub Issues](https://github.com/cloudx-io/cloudx-react-native/issues)
1246
+ - 📚 **Docs**: [docs.cloudx.io](https://docs.cloudx.io)
1247
+
1248
+ ---
1249
+
1250
+ ## License
1251
+
1252
+ This project is licensed under the Elastic License 2.0 - see the [LICENSE](LICENSE) file for details.
1253
+
1254
+ ---
1255
+
1256
+ ## Changelog
1257
+
1258
+ See [RELEASES](https://github.com/cloudx-io/cloudx-react-native/releases) for detailed changelog and version history.