@bigcrunch/react-native-ads 0.9.0 → 0.11.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.
- package/android/bigcrunch-ads/com/bigcrunch/ads/adapters/GoogleAdsAdapter.kt +6 -2
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/DeviceContext.kt +1 -1
- package/ios/BigCrunchAds/Sources/Adapters/GoogleAdsAdapter.swift +3 -2
- package/ios/BigCrunchAds/Sources/Core/DeviceContext.swift +1 -1
- package/ios/BigCrunchAds/Sources/Internal/Logger.swift +11 -6
- package/ios/BigCrunchAdsModule.swift +5 -0
- package/ios/BigCrunchBannerViewManager.swift +8 -1
- package/lib/BigCrunchBannerView.d.ts.map +1 -1
- package/lib/BigCrunchBannerView.js +23 -9
- package/package.json +1 -1
- package/src/BigCrunchBannerView.tsx +24 -10
|
@@ -120,17 +120,21 @@ internal class GoogleAdsAdapter(
|
|
|
120
120
|
* Resolve a BigCrunch AdSize to a Google AdSize.
|
|
121
121
|
* For adaptive sizes, calculates the optimal ad size based on screen width.
|
|
122
122
|
*/
|
|
123
|
+
/**
|
|
124
|
+
* Resolve a BigCrunch AdSize to a Google AdSize.
|
|
125
|
+
* A 0x0 size is always treated as adaptive since it is never valid as a fixed size.
|
|
126
|
+
*/
|
|
123
127
|
private fun resolveGoogleAdSize(
|
|
124
128
|
bcAdSize: com.bigcrunch.ads.models.AdSize
|
|
125
129
|
): AdSize {
|
|
126
|
-
if (bcAdSize.isAdaptive) {
|
|
130
|
+
if (bcAdSize.isAdaptive || (bcAdSize.width == 0 && bcAdSize.height == 0)) {
|
|
127
131
|
val widthDp = if (bcAdSize.width > 0) {
|
|
128
132
|
bcAdSize.width
|
|
129
133
|
} else {
|
|
130
134
|
val displayMetrics = context.resources.displayMetrics
|
|
131
135
|
(displayMetrics.widthPixels / displayMetrics.density).toInt()
|
|
132
136
|
}
|
|
133
|
-
BCLogger.d(TAG, "Resolving adaptive banner with width: ${widthDp}dp")
|
|
137
|
+
BCLogger.d(TAG, "Resolving adaptive banner with width: ${widthDp}dp (isAdaptive=${bcAdSize.isAdaptive}, original=${bcAdSize.width}x${bcAdSize.height})")
|
|
134
138
|
return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, widthDp)
|
|
135
139
|
}
|
|
136
140
|
return AdSize(bcAdSize.width, bcAdSize.height)
|
|
@@ -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.
|
|
31
|
+
internal const val SDK_VERSION = "0.11.0"
|
|
32
32
|
|
|
33
33
|
@Volatile
|
|
34
34
|
private var instance: DeviceContext? = null
|
|
@@ -94,12 +94,13 @@ internal class GoogleAdsAdapter: NSObject {
|
|
|
94
94
|
|
|
95
95
|
/// Resolve a BigCrunch AdSize to a Google AdSize.
|
|
96
96
|
/// For adaptive sizes, calculates the optimal ad size based on screen width.
|
|
97
|
+
/// A 0x0 size is always treated as adaptive since it is never valid as a fixed size.
|
|
97
98
|
private func resolveGoogleAdSize(_ bcAdSize: AdSize) -> GoogleMobileAds.AdSize {
|
|
98
|
-
if bcAdSize.isAdaptive {
|
|
99
|
+
if bcAdSize.isAdaptive || (bcAdSize.width == 0 && bcAdSize.height == 0) {
|
|
99
100
|
let width: CGFloat = bcAdSize.width > 0
|
|
100
101
|
? CGFloat(bcAdSize.width)
|
|
101
102
|
: UIScreen.main.bounds.width
|
|
102
|
-
BCLogger.debug("\(GoogleAdsAdapter.TAG): Resolving adaptive banner with width: \(width)pt")
|
|
103
|
+
BCLogger.debug("\(GoogleAdsAdapter.TAG): Resolving adaptive banner with width: \(width)pt (isAdaptive=\(bcAdSize.isAdaptive), original=\(bcAdSize.width)x\(bcAdSize.height))")
|
|
103
104
|
return GoogleMobileAds.currentOrientationAnchoredAdaptiveBanner(width: width)
|
|
104
105
|
}
|
|
105
106
|
return GoogleMobileAds.adSizeFor(cgSize: CGSize(
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import Foundation
|
|
2
|
+
import os.log
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Internal logger for BigCrunch Ads SDK
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
+
* Uses os_log for unified logging, visible in Console.app and terminal
|
|
8
|
+
* without requiring the Xcode debugger to be attached.
|
|
9
|
+
* All logs use the "BCrunch" subsystem for easy filtering.
|
|
7
10
|
* Logging can be disabled in production by setting isEnabled = false.
|
|
8
11
|
* Error logs are always shown regardless of isEnabled flag.
|
|
9
12
|
*/
|
|
10
13
|
internal class BCLogger {
|
|
11
14
|
|
|
15
|
+
private static let log = OSLog(subsystem: "com.bigcrunch.ads", category: "BCrunch")
|
|
16
|
+
|
|
12
17
|
/**
|
|
13
18
|
* Enable/disable debug logging
|
|
14
19
|
* Defaults to false for production builds
|
|
@@ -20,7 +25,7 @@ internal class BCLogger {
|
|
|
20
25
|
*/
|
|
21
26
|
static func verbose(_ message: String) {
|
|
22
27
|
if isEnabled {
|
|
23
|
-
|
|
28
|
+
os_log("[BCrunch:VERBOSE] %{public}@", log: log, type: .debug, message)
|
|
24
29
|
}
|
|
25
30
|
}
|
|
26
31
|
|
|
@@ -29,7 +34,7 @@ internal class BCLogger {
|
|
|
29
34
|
*/
|
|
30
35
|
static func debug(_ message: String) {
|
|
31
36
|
if isEnabled {
|
|
32
|
-
|
|
37
|
+
os_log("[BCrunch:DEBUG] %{public}@", log: log, type: .debug, message)
|
|
33
38
|
}
|
|
34
39
|
}
|
|
35
40
|
|
|
@@ -38,7 +43,7 @@ internal class BCLogger {
|
|
|
38
43
|
*/
|
|
39
44
|
static func info(_ message: String) {
|
|
40
45
|
if isEnabled {
|
|
41
|
-
|
|
46
|
+
os_log("[BCrunch:INFO] %{public}@", log: log, type: .info, message)
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
|
|
@@ -47,7 +52,7 @@ internal class BCLogger {
|
|
|
47
52
|
*/
|
|
48
53
|
static func warning(_ message: String) {
|
|
49
54
|
if isEnabled {
|
|
50
|
-
|
|
55
|
+
os_log("[BCrunch:WARNING] %{public}@", log: log, type: .default, message)
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
|
|
@@ -57,6 +62,6 @@ internal class BCLogger {
|
|
|
57
62
|
*/
|
|
58
63
|
static func error(_ message: String) {
|
|
59
64
|
// Always log errors
|
|
60
|
-
|
|
65
|
+
os_log("[BCrunch:ERROR] %{public}@", log: log, type: .error, message)
|
|
61
66
|
}
|
|
62
67
|
}
|
|
@@ -257,6 +257,11 @@ class BigCrunchAdsModule: RCTEventEmitter {
|
|
|
257
257
|
useTestAds: useTestAds,
|
|
258
258
|
callback: callbackBridge
|
|
259
259
|
)
|
|
260
|
+
|
|
261
|
+
if debug {
|
|
262
|
+
BigCrunchAds.setDebugMode(true)
|
|
263
|
+
}
|
|
264
|
+
|
|
260
265
|
NSLog("[BigCrunchRNBridge] native initialize() returned, waiting for callback...")
|
|
261
266
|
}
|
|
262
267
|
}
|
|
@@ -67,7 +67,7 @@ class BigCrunchBannerViewWrapper: UIView {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
var sizeString: String = "
|
|
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,
|
|
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
|
|
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
|
-
//
|
|
54
|
-
return
|
|
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
|
-
//
|
|
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
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigcrunch/react-native-ads",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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
|
|
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
|
-
//
|
|
86
|
-
return
|
|
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
|
-
//
|
|
243
|
-
|
|
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
|
};
|