@bigcrunch/react-native-ads 0.4.0 → 0.6.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 (58) hide show
  1. package/README.md +5 -5
  2. package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchAds.kt +434 -0
  3. package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchBannerView.kt +484 -0
  4. package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchInterstitial.kt +403 -0
  5. package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchRewarded.kt +409 -0
  6. package/android/bigcrunch-ads/com/bigcrunch/ads/adapters/GoogleAdsAdapter.kt +592 -0
  7. package/android/bigcrunch-ads/com/bigcrunch/ads/core/AdOrchestrator.kt +623 -0
  8. package/android/bigcrunch-ads/com/bigcrunch/ads/core/AnalyticsClient.kt +719 -0
  9. package/android/bigcrunch-ads/com/bigcrunch/ads/core/BidRequestClient.kt +364 -0
  10. package/android/bigcrunch-ads/com/bigcrunch/ads/core/ConfigManager.kt +300 -0
  11. package/android/bigcrunch-ads/com/bigcrunch/ads/core/DeviceContext.kt +385 -0
  12. package/android/bigcrunch-ads/com/bigcrunch/ads/core/RewardedCallback.kt +42 -0
  13. package/android/bigcrunch-ads/com/bigcrunch/ads/core/SessionManager.kt +330 -0
  14. package/android/bigcrunch-ads/com/bigcrunch/ads/internal/DeviceHelper.kt +60 -0
  15. package/android/bigcrunch-ads/com/bigcrunch/ads/internal/HttpClient.kt +114 -0
  16. package/android/bigcrunch-ads/com/bigcrunch/ads/internal/Logger.kt +71 -0
  17. package/android/bigcrunch-ads/com/bigcrunch/ads/internal/PrivacyStore.kt +125 -0
  18. package/android/bigcrunch-ads/com/bigcrunch/ads/internal/Storage.kt +88 -0
  19. package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/BannerAdListener.kt +55 -0
  20. package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/InterstitialAdListener.kt +55 -0
  21. package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/RewardedAdListener.kt +58 -0
  22. package/android/bigcrunch-ads/com/bigcrunch/ads/models/AdEvent.kt +880 -0
  23. package/android/bigcrunch-ads/com/bigcrunch/ads/models/AppConfig.kt +87 -0
  24. package/android/bigcrunch-ads/com/bigcrunch/ads/models/DeviceData.kt +18 -0
  25. package/android/bigcrunch-ads/com/bigcrunch/ads/models/PlacementConfig.kt +70 -0
  26. package/android/bigcrunch-ads/com/bigcrunch/ads/models/SessionInfo.kt +21 -0
  27. package/android/build.gradle +22 -10
  28. package/android/settings.gradle +2 -6
  29. package/android/src/main/java/com/bigcrunch/ads/react/BigCrunchAdsModule.kt +8 -2
  30. package/ios/BigCrunchAds/Sources/Adapters/GoogleAdsAdapter.swift +512 -0
  31. package/ios/BigCrunchAds/Sources/BigCrunchAds.swift +387 -0
  32. package/ios/BigCrunchAds/Sources/BigCrunchBannerView.swift +448 -0
  33. package/ios/BigCrunchAds/Sources/BigCrunchInterstitial.swift +412 -0
  34. package/ios/BigCrunchAds/Sources/BigCrunchRewarded.swift +523 -0
  35. package/ios/BigCrunchAds/Sources/Core/AdOrchestrator.swift +514 -0
  36. package/ios/BigCrunchAds/Sources/Core/AnalyticsClient.swift +874 -0
  37. package/ios/BigCrunchAds/Sources/Core/BidRequestClient.swift +344 -0
  38. package/ios/BigCrunchAds/Sources/Core/ConfigManager.swift +305 -0
  39. package/ios/BigCrunchAds/Sources/Core/DeviceContext.swift +284 -0
  40. package/ios/BigCrunchAds/Sources/Core/SessionManager.swift +392 -0
  41. package/ios/BigCrunchAds/Sources/Internal/HTTPClient.swift +146 -0
  42. package/ios/BigCrunchAds/Sources/Internal/Logger.swift +62 -0
  43. package/ios/BigCrunchAds/Sources/Internal/PrivacyStore.swift +129 -0
  44. package/ios/BigCrunchAds/Sources/Internal/Storage.swift +73 -0
  45. package/ios/BigCrunchAds/Sources/Models/AdEvent.swift +784 -0
  46. package/ios/BigCrunchAds/Sources/Models/AppConfig.swift +97 -0
  47. package/ios/BigCrunchAds/Sources/Models/DeviceData.swift +68 -0
  48. package/ios/BigCrunchAds/Sources/Models/PlacementConfig.swift +137 -0
  49. package/ios/BigCrunchAds/Sources/Models/SessionInfo.swift +48 -0
  50. package/ios/BigCrunchAdsModule.swift +37 -9
  51. package/ios/BigCrunchBannerViewManager.swift +0 -1
  52. package/lib/index.d.ts +1 -1
  53. package/lib/index.d.ts.map +1 -1
  54. package/lib/index.js +3 -2
  55. package/package.json +7 -1
  56. package/react-native-bigcrunch-ads.podspec +0 -1
  57. package/scripts/inject-version.js +55 -0
  58. package/src/index.ts +3 -2
@@ -0,0 +1,387 @@
1
+ import Foundation
2
+ import GoogleMobileAds
3
+
4
+ /**
5
+ * BigCrunch environment configuration
6
+ */
7
+ public enum BigCrunchEnv {
8
+ case prod
9
+ case staging
10
+ }
11
+
12
+ /**
13
+ * Callback protocol for SDK initialization completion
14
+ */
15
+ public protocol BigCrunchInitializationCallback: AnyObject {
16
+ /**
17
+ * Called when SDK initialization is complete and config is ready
18
+ */
19
+ func onInitialized()
20
+
21
+ /**
22
+ * Called if SDK initialization fails
23
+ * - Parameter error: Error message describing the failure
24
+ */
25
+ func onInitializationFailed(error: String)
26
+ }
27
+
28
+ /**
29
+ * BigCrunch Mobile Ads SDK - Main entry point
30
+ *
31
+ * Initialize the SDK before using any ad components:
32
+ * ```swift
33
+ * BigCrunchAds.initialize(
34
+ * propertyId: "your-property-id"
35
+ * )
36
+ * ```
37
+ */
38
+ public final class BigCrunchAds {
39
+
40
+ private static var _isInitialized = false
41
+ private static var configManager: ConfigManager!
42
+ private static var analyticsClient: AnalyticsClient!
43
+ private static var bidRequestClient: BidRequestClient?
44
+ internal static var privacyStore = PrivacyStore()
45
+
46
+ /// Check if the SDK has been initialized (internal use)
47
+ internal static func isInitialized() -> Bool {
48
+ return _isInitialized
49
+ }
50
+
51
+ internal static var propertyId: String = ""
52
+ internal static var environment: BigCrunchEnv = .prod
53
+
54
+ // State for debug and test device management
55
+ private static var debugMode = false
56
+ private static var testDeviceIds: [String] = []
57
+
58
+ /**
59
+ * Initialize the BigCrunch Ads SDK
60
+ *
61
+ * - Parameters:
62
+ * - propertyId: Your BigCrunch property ID
63
+ * - env: Environment (prod or staging)
64
+ * - useMockConfig: If true, uses hardcoded mock config for testing (default: false)
65
+ * - callback: Optional callback to be notified when initialization is complete
66
+ */
67
+ public static func initialize(
68
+ propertyId: String,
69
+ env: BigCrunchEnv = .prod,
70
+ useMockConfig: Bool = false,
71
+ callback: BigCrunchInitializationCallback? = nil
72
+ ) {
73
+ if _isInitialized {
74
+ BCLogger.warning("SDK already initialized, ignoring duplicate call")
75
+ return
76
+ }
77
+
78
+ BCLogger.info("BigCrunch Ads SDK v\(DeviceContext.SDK_VERSION) initializing...")
79
+ BCLogger.debug("Property ID: \(propertyId), Environment: \(env)")
80
+
81
+ // Store initialization parameters
82
+ self.propertyId = propertyId
83
+ self.environment = env
84
+
85
+ // Initialize Google Mobile Ads SDK
86
+ // Note: Google Mobile Ads SDK should be initialized by the app before calling BigCrunchAds.initialize()
87
+ BCLogger.debug("Google Mobile Ads SDK should be initialized by the app")
88
+
89
+ // Enable verbose logging in staging
90
+ if env == .staging {
91
+ BCLogger.isEnabled = true
92
+ }
93
+
94
+ // Create internal components
95
+ let httpClient = HTTPClient()
96
+ let storage = UserDefaultsStore()
97
+
98
+ // Analytics always uses pipeline.bigcrunch.com for both prod and staging
99
+ let baseURL = "https://pipeline.bigcrunch.com"
100
+
101
+ configManager = ConfigManager(httpClient: httpClient, storage: storage)
102
+ analyticsClient = AnalyticsClient(httpClient: httpClient, baseURL: baseURL)
103
+
104
+ // Mark as initialized before async config load
105
+ _isInitialized = true
106
+
107
+ // Kick off async config fetch
108
+ BCLogger.debug("Fetching app configuration...")
109
+ Task {
110
+ let result = await configManager.loadConfig(
111
+ propertyId: propertyId,
112
+ isProd: env == .prod,
113
+ useMockConfig: useMockConfig
114
+ )
115
+
116
+ switch result {
117
+ case .success(let config):
118
+ BCLogger.debug("Configuration loaded successfully")
119
+ BCLogger.verbose("Placements: \(config.placements.count)")
120
+
121
+ // Create shared BidRequestClient for S2S demand
122
+ if config.s2s.enabled {
123
+ bidRequestClient = BidRequestClient(
124
+ httpClient: httpClient,
125
+ configManager: configManager,
126
+ privacyStore: privacyStore,
127
+ s2sConfig: config.s2s
128
+ )
129
+ BCLogger.debug("BidRequestClient created: \(config.s2s.serverUrl)")
130
+ } else {
131
+ BCLogger.debug("S2S is disabled in config")
132
+ }
133
+
134
+ // Notify callback of successful initialization
135
+ await MainActor.run {
136
+ callback?.onInitialized()
137
+ }
138
+ case .failure(let error):
139
+ BCLogger.error("Failed to load configuration: \(error)")
140
+
141
+ // Notify callback of initialization failure
142
+ await MainActor.run {
143
+ callback?.onInitializationFailed(error: error.localizedDescription)
144
+ }
145
+ }
146
+ }
147
+
148
+ BCLogger.debug("BigCrunch Ads SDK initialization complete")
149
+ }
150
+
151
+ /**
152
+ * Track screen view for analytics
153
+ *
154
+ * - Parameter screenName: Name of the screen being viewed
155
+ */
156
+ public static func trackScreen(_ screenName: String) {
157
+ guard _isInitialized else {
158
+ BCLogger.warning("trackScreen called before initialization, ignoring")
159
+ return
160
+ }
161
+ analyticsClient.trackScreenView(screenName)
162
+ SessionManager.shared.startPageView()
163
+ }
164
+
165
+ // MARK: - Configuration
166
+
167
+ /**
168
+ * Get the current app configuration
169
+ *
170
+ * - Returns: The app configuration, or nil if not yet loaded
171
+ */
172
+ public static func getAppConfig() -> AppConfig? {
173
+ guard _isInitialized else { return nil }
174
+ return configManager.getCachedConfig()
175
+ }
176
+
177
+ /**
178
+ * Refresh the app configuration from the server
179
+ */
180
+ public static func refreshConfig() async {
181
+ guard _isInitialized else {
182
+ BCLogger.warning("refreshConfig called before initialization, ignoring")
183
+ return
184
+ }
185
+ _ = await configManager.loadConfig(
186
+ propertyId: propertyId,
187
+ isProd: environment == .prod,
188
+ useMockConfig: false
189
+ )
190
+ }
191
+
192
+ // MARK: - Session Management
193
+
194
+ /**
195
+ * Get current session information
196
+ *
197
+ * - Returns: Session info with tracking counts
198
+ */
199
+ public static func getSessionInfo() -> SessionInfo {
200
+ let sm = SessionManager.shared
201
+ return SessionInfo(
202
+ sessionId: sm.sessionId,
203
+ userId: sm.userId,
204
+ startTime: sm.sessionStartTime,
205
+ screenViewCount: sm.sessionDepth,
206
+ adRequestCount: sm.adRequestCount,
207
+ adImpressionCount: sm.adImpressionCount,
208
+ totalRevenueMicros: sm.totalRevenueMicros
209
+ )
210
+ }
211
+
212
+ /**
213
+ * Start a new session (resets all session counters)
214
+ */
215
+ public static func startNewSession() {
216
+ SessionManager.shared.startNewSession()
217
+ }
218
+
219
+ // MARK: - Device Information
220
+
221
+ /**
222
+ * Get device data
223
+ *
224
+ * - Returns: Device data with device information
225
+ */
226
+ public static func getDeviceData() -> DeviceData {
227
+ let ctx = DeviceContext.shared
228
+ let sm = SessionManager.shared
229
+ return DeviceData(
230
+ deviceId: sm.userId,
231
+ deviceModel: ctx.deviceModel,
232
+ osVersion: ctx.osVersion,
233
+ appVersion: ctx.appVersion,
234
+ screenWidth: ctx.screenWidth,
235
+ screenHeight: ctx.screenHeight,
236
+ language: ctx.languageCode,
237
+ country: ctx.countryCode,
238
+ isTablet: ctx.deviceType == "tablet",
239
+ carrier: nil,
240
+ networkType: nil
241
+ )
242
+ }
243
+
244
+ // MARK: - Privacy Compliance
245
+
246
+ /**
247
+ * Set GDPR consent string for privacy compliance
248
+ *
249
+ * - Parameter consent: GDPR consent string
250
+ */
251
+ public static func setGdprConsent(_ consent: String) {
252
+ privacyStore.setGdprConsent(consent)
253
+ BCLogger.debug("GDPR consent set")
254
+ }
255
+
256
+ /**
257
+ * Set CCPA string for privacy compliance
258
+ *
259
+ * - Parameter ccpaString: CCPA consent string (e.g., "1YNN")
260
+ */
261
+ public static func setCcpaString(_ ccpaString: String) {
262
+ privacyStore.setCcpaString(ccpaString)
263
+ BCLogger.debug("CCPA string set: \(ccpaString)")
264
+ }
265
+
266
+ /**
267
+ * Set COPPA compliance flag
268
+ *
269
+ * - Parameter isCompliant: true if the app should comply with COPPA
270
+ */
271
+ public static func setCoppaCompliant(_ isCompliant: Bool) {
272
+ privacyStore.setCoppaApplies(isCompliant)
273
+
274
+ // Also set in Google Mobile Ads
275
+ GoogleMobileAds.MobileAds.shared.requestConfiguration.tagForChildDirectedTreatment = isCompliant ? true : false
276
+ BCLogger.debug("COPPA compliance set to: \(isCompliant)")
277
+ }
278
+
279
+ // MARK: - Debug and Testing
280
+
281
+ /**
282
+ * Enable or disable debug mode
283
+ *
284
+ * - Parameter enabled: true to enable debug logging
285
+ */
286
+ public static func setDebugMode(_ enabled: Bool) {
287
+ debugMode = enabled
288
+ BCLogger.isEnabled = enabled
289
+ BCLogger.debug("Debug mode set to: \(enabled)")
290
+ }
291
+
292
+ /**
293
+ * Add a test device ID for Google Ads testing
294
+ *
295
+ * - Parameter deviceId: Test device ID from Google Ads logs
296
+ */
297
+ public static func addTestDevice(_ deviceId: String) {
298
+ if !testDeviceIds.contains(deviceId) {
299
+ testDeviceIds.append(deviceId)
300
+ }
301
+ GoogleMobileAds.MobileAds.shared.requestConfiguration.testDeviceIdentifiers = testDeviceIds
302
+ BCLogger.debug("Added test device: \(deviceId)")
303
+ }
304
+
305
+ /**
306
+ * Remove a test device ID
307
+ *
308
+ * - Parameter deviceId: Test device ID to remove
309
+ */
310
+ public static func removeTestDevice(_ deviceId: String) {
311
+ testDeviceIds.removeAll { $0 == deviceId }
312
+ GoogleMobileAds.MobileAds.shared.requestConfiguration.testDeviceIdentifiers = testDeviceIds
313
+ BCLogger.debug("Removed test device: \(deviceId)")
314
+ }
315
+
316
+ /**
317
+ * Get list of test device IDs
318
+ *
319
+ * - Returns: List of currently configured test device IDs
320
+ */
321
+ public static func getTestDevices() -> [String] {
322
+ return testDeviceIds
323
+ }
324
+
325
+ // MARK: - State Queries
326
+
327
+ /**
328
+ * Check if the SDK has been initialized
329
+ *
330
+ * - Returns: true if initialized, false otherwise
331
+ */
332
+ public static func isSDKInitialized() -> Bool {
333
+ return _isInitialized
334
+ }
335
+
336
+ /**
337
+ * Check if configuration has been loaded
338
+ *
339
+ * - Returns: true if configuration has been successfully loaded
340
+ */
341
+ public static func isConfigReady() -> Bool {
342
+ guard _isInitialized else { return false }
343
+ return configManager?.getCachedConfig() != nil
344
+ }
345
+
346
+ /**
347
+ * Track screen view for analytics (alias for Android API compatibility)
348
+ *
349
+ * - Parameter screenName: Name of the screen being viewed
350
+ */
351
+ public static func trackScreenView(_ screenName: String) {
352
+ trackScreen(screenName)
353
+ }
354
+
355
+ // MARK: - Internal
356
+
357
+ internal static func requireInitialized() {
358
+ precondition(_isInitialized, "BigCrunchAds SDK not initialized. Call initialize() first.")
359
+ }
360
+
361
+ internal static func getConfigManager() -> ConfigManager {
362
+ requireInitialized()
363
+ return configManager
364
+ }
365
+
366
+ internal static func getAnalyticsClient() -> AnalyticsClient {
367
+ requireInitialized()
368
+ return analyticsClient
369
+ }
370
+
371
+ internal static func getBidRequestClient() -> BidRequestClient? {
372
+ return bidRequestClient
373
+ }
374
+
375
+ // MARK: - Testing Support
376
+
377
+ /// Reset the SDK state for testing purposes only
378
+ /// - Warning: This is for unit tests only. Do not call in production code.
379
+ internal static func resetForTesting() {
380
+ _isInitialized = false
381
+ configManager = nil
382
+ analyticsClient = nil
383
+ propertyId = ""
384
+ environment = .prod
385
+ BCLogger.isEnabled = false
386
+ }
387
+ }