@bigcrunch/react-native-ads 0.7.0 → 0.10.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.
@@ -108,6 +108,7 @@ object BigCrunchAds {
108
108
  * @param propertyId Your BigCrunch property ID
109
109
  * @param env Environment (Prod or Staging)
110
110
  * @param useMockConfig If true, uses hardcoded mock config for testing (default: false)
111
+ * @param useTestAds If true, uses Google's test ad units instead of production units (default: false)
111
112
  * @param callback Optional callback to be notified when initialization is complete
112
113
  */
113
114
  fun initialize(
@@ -115,6 +116,7 @@ object BigCrunchAds {
115
116
  propertyId: String,
116
117
  env: Environment = Environment.Prod,
117
118
  useMockConfig: Boolean = false,
119
+ useTestAds: Boolean = false,
118
120
  callback: InitializationCallback? = null
119
121
  ) {
120
122
  if (initialized) {
@@ -160,6 +162,9 @@ object BigCrunchAds {
160
162
  val baseUrl = "https://pipeline.bigcrunch.com"
161
163
 
162
164
  configManager = ConfigManager(httpClient, storage, moshi)
165
+ if (useTestAds) {
166
+ configManager.useTestAdsOverride = true
167
+ }
163
168
  analyticsClient = AnalyticsClient(appContext, httpClient, moshi, baseUrl)
164
169
  privacyStore = PrivacyStore(appContext)
165
170
 
@@ -54,6 +54,11 @@ internal class BidRequestClient(
54
54
  * @return Targeting KVPs to apply to GAM request, or null
55
55
  */
56
56
  suspend fun fetchDemand(placement: PlacementConfig): Map<String, String>? {
57
+ if (!s2sConfig.enabled) {
58
+ BCLogger.d(TAG, "S2S is disabled, skipping bid request")
59
+ return null
60
+ }
61
+
57
62
  val deferred = CompletableDeferred<Map<String, String>?>()
58
63
 
59
64
  mutex.withLock {
@@ -150,7 +150,7 @@ internal class ConfigManager(
150
150
  val config = try {
151
151
  adapter.fromJson(json)
152
152
  } catch (e: Exception) {
153
- BCLogger.e("ConfigManager", "Failed to parse config JSON", e)
153
+ BCLogger.e("ConfigManager", "Failed to parse config JSON from $url", e)
154
154
  null
155
155
  }
156
156
 
@@ -159,6 +159,7 @@ internal class ConfigManager(
159
159
  saveToStorage(json)
160
160
  val placementIds = config.placements.map { it.placementId }
161
161
  BCLogger.i("ConfigManager", "Config loaded successfully from network (${config.placements.size} placements): $placementIds")
162
+ BCLogger.v("ConfigManager", "Config JSON: $json")
162
163
  Result.success(config)
163
164
  } else {
164
165
  BCLogger.e("ConfigManager", "Invalid config JSON")
@@ -168,12 +169,12 @@ internal class ConfigManager(
168
169
  storedConfig != null -> {
169
170
  // Network failed but we have cached version
170
171
  val cachedIds = storedConfig.placements.map { it.placementId }
171
- BCLogger.w("ConfigManager", "Using cached config, network fetch failed: ${result.exceptionOrNull()?.message} (cached placements: $cachedIds)")
172
+ BCLogger.w("ConfigManager", "Config fetch failed for $url: ${result.exceptionOrNull()?.message}. Using cached config (cached placements: $cachedIds)")
172
173
  Result.success(storedConfig)
173
174
  }
174
175
  else -> {
175
176
  // Network failed and no cache available
176
- BCLogger.e("ConfigManager", "Config load failed and no cache available")
177
+ BCLogger.e("ConfigManager", "Config load failed for $url and no cache available")
177
178
  Result.failure(result.exceptionOrNull() ?: Exception("Config load failed"))
178
179
  }
179
180
  }
@@ -257,12 +258,16 @@ internal class ConfigManager(
257
258
  return cachedConfig?.refresh
258
259
  }
259
260
 
261
+ /** Override for useTestAds, set via initialize() options. Takes precedence over config value. */
262
+ var useTestAdsOverride: Boolean? = null
263
+
260
264
  /**
261
265
  * Check if test ads mode is enabled in config
262
266
  *
263
267
  * @return true if test ads should be used, false otherwise
264
268
  */
265
269
  fun shouldUseTestAds(): Boolean {
270
+ useTestAdsOverride?.let { return it }
266
271
  return cachedConfig?.useTestAds ?: false
267
272
  }
268
273
 
@@ -28,7 +28,7 @@ internal class DeviceContext private constructor(context: Context) {
28
28
 
29
29
  companion object {
30
30
  private const val TAG = "DeviceContext"
31
- internal const val SDK_VERSION = "0.7.0"
31
+ internal const val SDK_VERSION = "0.10.1"
32
32
 
33
33
  @Volatile
34
34
  private var instance: DeviceContext? = null
@@ -33,13 +33,15 @@ class BigCrunchAdsModule(reactContext: ReactApplicationContext) :
33
33
  ?: throw IllegalArgumentException("propertyId is required")
34
34
  val environment = options.getString("environment") ?: "production"
35
35
  val debug = if (options.hasKey("debug")) options.getBoolean("debug") else false
36
+ val useMockConfig = if (options.hasKey("useMockConfig")) options.getBoolean("useMockConfig") else false
37
+ val useTestAds = if (options.hasKey("useTestAds")) options.getBoolean("useTestAds") else false
36
38
 
37
39
  // Initialize the native SDK
38
40
  val context = reactApplicationContext.applicationContext
39
41
 
40
42
  scope.launch {
41
43
  try {
42
- android.util.Log.d("BigCrunchRNBridge", "initialize() called: propertyId=$propertyId env=$environment mock=${environment == "sandbox"}")
44
+ android.util.Log.d("BigCrunchRNBridge", "initialize() called: propertyId=$propertyId env=$environment mock=$useMockConfig testAds=$useTestAds")
43
45
 
44
46
  BigCrunchAds.initialize(
45
47
  context = context,
@@ -48,8 +50,8 @@ class BigCrunchAdsModule(reactContext: ReactApplicationContext) :
48
50
  BigCrunchAds.Environment.Staging
49
51
  else
50
52
  BigCrunchAds.Environment.Prod,
51
- // Use mock config for testing/development
52
- useMockConfig = environment == "sandbox"
53
+ useMockConfig = useMockConfig,
54
+ useTestAds = useTestAds
53
55
  )
54
56
 
55
57
  android.util.Log.d("BigCrunchRNBridge", "native initialize() returned, isInitialized=${BigCrunchAds.isInitialized()}")
@@ -62,12 +62,14 @@ public final class BigCrunchAds {
62
62
  * - propertyId: Your BigCrunch property ID
63
63
  * - env: Environment (prod or staging)
64
64
  * - useMockConfig: If true, uses hardcoded mock config for testing (default: false)
65
+ * - useTestAds: If true, uses Google's test ad units instead of production units (default: false)
65
66
  * - callback: Optional callback to be notified when initialization is complete
66
67
  */
67
68
  public static func initialize(
68
69
  propertyId: String,
69
70
  env: BigCrunchEnv = .prod,
70
71
  useMockConfig: Bool = false,
72
+ useTestAds: Bool = false,
71
73
  callback: BigCrunchInitializationCallback? = nil
72
74
  ) {
73
75
  if _isInitialized {
@@ -99,6 +101,9 @@ public final class BigCrunchAds {
99
101
  let baseURL = "https://pipeline.bigcrunch.com"
100
102
 
101
103
  configManager = ConfigManager(httpClient: httpClient, storage: storage)
104
+ if useTestAds {
105
+ configManager.useTestAdsOverride = true
106
+ }
102
107
  analyticsClient = AnalyticsClient(httpClient: httpClient, baseURL: baseURL)
103
108
 
104
109
  // Mark as initialized before async config load
@@ -422,7 +422,7 @@ internal class AdOrchestrator {
422
422
  */
423
423
  private class BannerCallbackWrapper {
424
424
  let placementId: String
425
- weak var callback: BannerCallback?
425
+ var callback: BannerCallback?
426
426
  var delegateWrapper: BannerDelegateAdapterWrapper?
427
427
 
428
428
  init(placementId: String, callback: BannerCallback) {
@@ -436,7 +436,7 @@ private class BannerCallbackWrapper {
436
436
  */
437
437
  private class InterstitialCallbackWrapper {
438
438
  let placementId: String
439
- weak var callback: InterstitialCallback?
439
+ var callback: InterstitialCallback?
440
440
  var delegateWrapper: InterstitialDelegateAdapterWrapper?
441
441
 
442
442
  init(placementId: String, callback: InterstitialCallback) {
@@ -60,6 +60,11 @@ internal class BidRequestClient {
60
60
  * - Returns: Targeting KVPs to apply to GAM request, or nil
61
61
  */
62
62
  func fetchDemand(placement: PlacementConfig) async -> [String: String]? {
63
+ guard s2sConfig.enabled else {
64
+ BCLogger.debug("BidRequestClient: S2S is disabled, skipping bid request")
65
+ return nil
66
+ }
67
+
63
68
  return await withCheckedContinuation { continuation in
64
69
  lock.lock()
65
70
  pendingRequests.append(PendingRequest(
@@ -149,9 +149,10 @@ internal class ConfigManager {
149
149
  saveToStorage(json)
150
150
  let placementIds = config.placements.map { $0.placementId }
151
151
  BCLogger.info("Config loaded successfully from network (\(config.placements.count) placements): \(placementIds)")
152
+ BCLogger.verbose("Config JSON: \(json)")
152
153
  return .success(config)
153
154
  } catch {
154
- BCLogger.error("Failed to parse config JSON: \(error)")
155
+ BCLogger.error("Failed to parse config JSON from \(url): \(error)")
155
156
  return .failure(error)
156
157
  }
157
158
 
@@ -159,10 +160,10 @@ internal class ConfigManager {
159
160
  // Network failed, check for cached version
160
161
  if let cached = cachedConfig {
161
162
  let cachedIds = cached.placements.map { $0.placementId }
162
- BCLogger.warning("Using cached config, network fetch failed: \(error) (cached placements: \(cachedIds))")
163
+ BCLogger.warning("Config fetch failed for \(url): \(error). Using cached config (cached placements: \(cachedIds))")
163
164
  return .success(cached)
164
165
  } else {
165
- BCLogger.error("Config load failed and no cache available")
166
+ BCLogger.error("Config load failed for \(url) and no cache available")
166
167
  return .failure(error)
167
168
  }
168
169
  }
@@ -229,15 +230,21 @@ internal class ConfigManager {
229
230
  return cachedConfig
230
231
  }
231
232
 
233
+ /// Override for useTestAds, set via initialize() options. Takes precedence over config value.
234
+ var useTestAdsOverride: Bool?
235
+
232
236
  /**
233
237
  * Check if test ads should be used
234
238
  *
235
- * Returns true if the cached config has useTestAds enabled.
239
+ * Returns true if the override is set, or if the cached config has useTestAds enabled.
236
240
  * When true, GoogleAdsAdapter should substitute production ad units with Google's test ad units.
237
241
  *
238
242
  * - Returns: True if test ads should be used, false otherwise
239
243
  */
240
244
  func shouldUseTestAds() -> Bool {
245
+ if let override = useTestAdsOverride {
246
+ return override
247
+ }
241
248
  lock.lock()
242
249
  defer { lock.unlock() }
243
250
  return cachedConfig?.useTestAds ?? false
@@ -74,7 +74,7 @@ internal final class DeviceContext {
74
74
  // MARK: - SDK Properties
75
75
 
76
76
  /// SDK version
77
- static let SDK_VERSION = "0.7.0"
77
+ static let SDK_VERSION = "0.10.1"
78
78
  let sdkVersion: String = SDK_VERSION
79
79
 
80
80
  /// SDK platform (always "ios")
@@ -226,12 +226,13 @@ class BigCrunchAdsModule: RCTEventEmitter {
226
226
  let environment = options["environment"] as? String ?? "production"
227
227
  let debug = options["debug"] as? Bool ?? false
228
228
  let useMockConfig = options["useMockConfig"] as? Bool ?? false
229
+ let useTestAds = options["useTestAds"] as? Bool ?? false
229
230
 
230
231
  DispatchQueue.main.async {
231
232
  // Map environment strings to SDK enum - "sandbox" maps to .staging
232
233
  let env: BigCrunchEnv = environment == "sandbox" ? .staging : .prod
233
234
 
234
- NSLog("[BigCrunchRNBridge] initialize() called: propertyId=%@ env=%@ mock=%d", propertyId, environment, useMockConfig ? 1 : 0)
235
+ NSLog("[BigCrunchRNBridge] initialize() called: propertyId=%@ env=%@ mock=%d testAds=%d", propertyId, environment, useMockConfig ? 1 : 0, useTestAds ? 1 : 0)
235
236
 
236
237
  // Use callback to wait for config to load before resolving the promise
237
238
  // This ensures placements are available when the app starts loading ads
@@ -253,6 +254,7 @@ class BigCrunchAdsModule: RCTEventEmitter {
253
254
  propertyId: propertyId,
254
255
  env: env,
255
256
  useMockConfig: useMockConfig,
257
+ useTestAds: useTestAds,
256
258
  callback: callbackBridge
257
259
  )
258
260
  NSLog("[BigCrunchRNBridge] native initialize() returned, waiting for callback...")
@@ -67,7 +67,7 @@ class BigCrunchBannerViewWrapper: UIView {
67
67
  }
68
68
  }
69
69
 
70
- var sizeString: String = "BANNER"
70
+ var sizeString: String = "" // Empty = use config sizes (no override)
71
71
  @objc var customWidth: NSNumber? {
72
72
  didSet {
73
73
  _customWidth = customWidth?.intValue
@@ -151,6 +151,13 @@ class BigCrunchBannerViewWrapper: UIView {
151
151
  func updateAdSize() {
152
152
  guard let bannerView = bannerView else { return }
153
153
 
154
+ // If no explicit size was set (sizeString is empty and no custom dimensions),
155
+ // don't set adSizeOverride — let the native SDK use config sizes
156
+ if sizeString.isEmpty && _customWidth == nil && _customHeight == nil {
157
+ bannerView.adSizeOverride = nil
158
+ return
159
+ }
160
+
154
161
  var googleAdSize: GoogleMobileAds.AdSize
155
162
  var bcAdSize: BCAdSize
156
163
 
@@ -1 +1 @@
1
- {"version":3,"file":"BigCrunchBannerView.d.ts","sourceRoot":"","sources":["../src/BigCrunchBannerView.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAkD,MAAM,OAAO,CAAC;AASvE,OAAO,KAAK,EACV,wBAAwB,EAKzB,MAAM,SAAS,CAAC;AAmBjB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA+MlE,CAAC;AAGF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"BigCrunchBannerView.d.ts","sourceRoot":"","sources":["../src/BigCrunchBannerView.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAkD,MAAM,OAAO,CAAC;AASvE,OAAO,KAAK,EACV,wBAAwB,EAKzB,MAAM,SAAS,CAAC;AAmBjB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA6NlE,CAAC;AAGF,eAAe,mBAAmB,CAAC"}
@@ -31,12 +31,18 @@ const NativeBannerView = requireNativeComponent(NATIVE_COMPONENT_NAME);
31
31
  * />
32
32
  * ```
33
33
  */
34
- export const BigCrunchBannerView = ({ placementId, size = 'BANNER', autoLoad = true, refreshInterval = 0, customTargeting, style, onAdLoaded, onAdFailedToLoad, onAdImpression, onAdClicked, onAdOpened, onAdClosed, onAdRevenue, }) => {
34
+ export const BigCrunchBannerView = ({ placementId, size, autoLoad = true, refreshInterval = 0, customTargeting, style, onAdLoaded, onAdFailedToLoad, onAdImpression, onAdClicked, onAdOpened, onAdClosed, onAdRevenue, }) => {
35
35
  const viewRef = useRef(null);
36
36
  const subscriptionsRef = useRef([]);
37
37
  const viewIdRef = useRef(`banner_${placementId}_${Date.now()}`);
38
- // Calculate banner size
38
+ // Calculate banner size for layout
39
+ // When size is undefined, config drives the ad size natively — use adaptive layout
39
40
  const bannerSize = useMemo(() => {
41
+ if (size === undefined) {
42
+ // No explicit size — let backend config drive the ad size
43
+ // Use adaptive layout since config may specify smart/adaptive sizes
44
+ return { width: 0, height: 0, adaptive: true, configDriven: true };
45
+ }
40
46
  if (typeof size === 'object' && 'width' in size && 'height' in size) {
41
47
  // Custom size
42
48
  return size;
@@ -50,8 +56,8 @@ export const BigCrunchBannerView = ({ placementId, size = 'BANNER', autoLoad = t
50
56
  }
51
57
  return dimensions;
52
58
  }
53
- // Default to BANNER size
54
- return BANNER_SIZES.BANNER;
59
+ // Unknown size string — fallback to adaptive layout
60
+ return { width: 0, height: 0, adaptive: true };
55
61
  }, [size]);
56
62
  // Handle native events
57
63
  const handleNativeEvent = useCallback((_eventName, handler) => {
@@ -155,20 +161,28 @@ export const BigCrunchBannerView = ({ placementId, size = 'BANNER', autoLoad = t
155
161
  return StyleSheet.flatten([baseStyle, style]);
156
162
  }, [bannerSize, style]);
157
163
  // Native view props
158
- // Always pass explicit dimensions to the native view
164
+ // Only send size/customWidth/customHeight when explicitly specified by the developer.
165
+ // When omitted, the native SDK uses placement config sizes (e.g., smart/adaptive from backend).
159
166
  const nativeProps = {
160
167
  ref: viewRef,
161
168
  style: containerStyle,
162
169
  placementId,
163
- size: typeof size === 'string' ? size : 'CUSTOM',
164
- // Always pass width and height, even for standard sizes
165
- customWidth: bannerSize.width > 0 ? bannerSize.width : undefined,
166
- customHeight: bannerSize.height > 0 ? bannerSize.height : undefined,
167
170
  autoLoad,
168
171
  refreshInterval,
169
172
  customTargeting,
170
173
  viewId: viewIdRef.current,
171
174
  };
175
+ // Only send size to native when explicitly set by the developer
176
+ if (size !== undefined) {
177
+ if (typeof size === 'string') {
178
+ nativeProps.size = size;
179
+ }
180
+ else if (typeof size === 'object' && 'width' in size && 'height' in size) {
181
+ nativeProps.size = 'CUSTOM';
182
+ nativeProps.customWidth = size.width;
183
+ nativeProps.customHeight = size.height;
184
+ }
185
+ }
172
186
  // Return the native view directly with the container style
173
187
  return React.createElement(NativeBannerView, { ...nativeProps });
174
188
  };
@@ -36,6 +36,8 @@ export interface InitializationOptions {
36
36
  debug?: boolean;
37
37
  /** Use mock configuration for testing (no backend required) */
38
38
  useMockConfig?: boolean;
39
+ /** Use Google's test ad units instead of production units */
40
+ useTestAds?: boolean;
39
41
  /** Custom backend URL (optional) */
40
42
  customBackendUrl?: string;
41
43
  /** Session timeout in seconds (default: 1800) */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigcrunch/react-native-ads",
3
- "version": "0.7.0",
3
+ "version": "0.10.1",
4
4
  "description": "BigCrunch Mobile Ads SDK for React Native - Simplified in-app advertising with S2S demand and Google Ad Manager",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -51,7 +51,7 @@ const NativeBannerView = requireNativeComponent<any>(NATIVE_COMPONENT_NAME);
51
51
  */
52
52
  export const BigCrunchBannerView: React.FC<BigCrunchBannerViewProps> = ({
53
53
  placementId,
54
- size = 'BANNER',
54
+ size,
55
55
  autoLoad = true,
56
56
  refreshInterval = 0,
57
57
  customTargeting,
@@ -68,8 +68,14 @@ export const BigCrunchBannerView: React.FC<BigCrunchBannerViewProps> = ({
68
68
  const subscriptionsRef = useRef<EventSubscription[]>([]);
69
69
  const viewIdRef = useRef<string>(`banner_${placementId}_${Date.now()}`);
70
70
 
71
- // Calculate banner size
71
+ // Calculate banner size for layout
72
+ // When size is undefined, config drives the ad size natively — use adaptive layout
72
73
  const bannerSize = useMemo(() => {
74
+ if (size === undefined) {
75
+ // No explicit size — let backend config drive the ad size
76
+ // Use adaptive layout since config may specify smart/adaptive sizes
77
+ return { width: 0, height: 0, adaptive: true, configDriven: true };
78
+ }
73
79
  if (typeof size === 'object' && 'width' in size && 'height' in size) {
74
80
  // Custom size
75
81
  return size;
@@ -82,8 +88,8 @@ export const BigCrunchBannerView: React.FC<BigCrunchBannerViewProps> = ({
82
88
  }
83
89
  return dimensions;
84
90
  }
85
- // Default to BANNER size
86
- return BANNER_SIZES.BANNER;
91
+ // Unknown size string — fallback to adaptive layout
92
+ return { width: 0, height: 0, adaptive: true };
87
93
  }, [size]);
88
94
 
89
95
  // Handle native events
@@ -239,21 +245,29 @@ export const BigCrunchBannerView: React.FC<BigCrunchBannerViewProps> = ({
239
245
  }, [bannerSize, style]);
240
246
 
241
247
  // Native view props
242
- // Always pass explicit dimensions to the native view
243
- const nativeProps = {
248
+ // Only send size/customWidth/customHeight when explicitly specified by the developer.
249
+ // When omitted, the native SDK uses placement config sizes (e.g., smart/adaptive from backend).
250
+ const nativeProps: any = {
244
251
  ref: viewRef,
245
252
  style: containerStyle,
246
253
  placementId,
247
- size: typeof size === 'string' ? size : 'CUSTOM',
248
- // Always pass width and height, even for standard sizes
249
- customWidth: bannerSize.width > 0 ? bannerSize.width : undefined,
250
- customHeight: bannerSize.height > 0 ? bannerSize.height : undefined,
251
254
  autoLoad,
252
255
  refreshInterval,
253
256
  customTargeting,
254
257
  viewId: viewIdRef.current,
255
258
  };
256
259
 
260
+ // Only send size to native when explicitly set by the developer
261
+ if (size !== undefined) {
262
+ if (typeof size === 'string') {
263
+ nativeProps.size = size;
264
+ } else if (typeof size === 'object' && 'width' in size && 'height' in size) {
265
+ nativeProps.size = 'CUSTOM';
266
+ nativeProps.customWidth = size.width;
267
+ nativeProps.customHeight = size.height;
268
+ }
269
+ }
270
+
257
271
  // Return the native view directly with the container style
258
272
  return <NativeBannerView {...nativeProps} />;
259
273
  };
@@ -49,6 +49,8 @@ export interface InitializationOptions {
49
49
  debug?: boolean;
50
50
  /** Use mock configuration for testing (no backend required) */
51
51
  useMockConfig?: boolean;
52
+ /** Use Google's test ad units instead of production units */
53
+ useTestAds?: boolean;
52
54
  /** Custom backend URL (optional) */
53
55
  customBackendUrl?: string;
54
56
  /** Session timeout in seconds (default: 1800) */