Skip to content

Feature/ad and adbreak custom data bridging - #866

Open
wvanhaevre wants to merge 13 commits into
developfrom
feature/ad-and-adbreak-customData-bridging
Open

Feature/ad and adbreak custom data bridging#866
wvanhaevre wants to merge 13 commits into
developfrom
feature/ad-and-adbreak-customData-bridging

Conversation

@wvanhaevre

@wvanhaevre wvanhaevre commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

@wvanhaevre
wvanhaevre requested a review from tvanlaerhoven July 8, 2026 12:35
devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 0 new potential issues.

Open in Devin Review

devin-ai-integration Bot and others added 2 commits July 8, 2026 13:24
Co-Authored-By: william.vanhaevre <william.vanhaevre@dolby.com>
Co-Authored-By: william.vanhaevre <william.vanhaevre@dolby.com>
Comment thread android/src/main/java/com/theoplayer/ads/AdAdapter.kt
devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

Open in Devin Review

Comment on lines +33 to +34
/** Additional integration-specific data associated with this ad.*/
var customData: [String: Any]? = nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Custom ad data sent from JavaScript is dropped when rebuilding ads on iOS

The new custom-data field on ads and ad breaks is never filled in when an ad is rebuilt from JavaScript data (customData at ios/ads/THEOplayerRCTAdsNative.swift:34), so for custom ad integrations the extra data always comes back empty.
Impact: Apps using a custom ad integration lose any custom data they attach to ads or ad breaks once the ad passes back through the native layer.

Initializers never assign the newly declared customData property

NativeAd.init (ios/ads/THEOplayerRCTAdsNative.swift:36-50) and NativeAdBreak.init (ios/ads/THEOplayerRCTAdsNative.swift:142-150) take no customData parameter and never assign the property, so it stays nil. Correspondingly THEOplayerRCTAdAdapter.toAd (ios/ads/THEOplayerRCTAdAdapter.swift:136-158) and toAdBreak (ios/ads/THEOplayerRCTAdAdapter.swift:194-215) never read adData[PROP_CUSTOM_DATA], even though fromAd/fromAdBreak now write it. These converted ads are used for custom-integration ad events (ios/ads/THEOplayerRCTAdEventAdapter.swift:14-20), so the JS→native direction silently discards custom data. Android has the same gap in AdAdapter.parseAd where getCustomData() returns null (android/src/main/java/com/theoplayer/ads/AdAdapter.kt:219-222).

Prompt for agents
The PR adds a customData property to NativeAd (ios/ads/THEOplayerRCTAdsNative.swift) and NativeAdBreak, and writes customData into the bridge payload in THEOplayerRCTAdAdapter.fromAd/fromAdBreak. However, the initializers of NativeAd, NativeLinearAd, NativeLinearGoogleImaAd and NativeAdBreak do not accept or assign customData, and THEOplayerRCTAdAdapter.toAd/toAdBreak never read the customData key from the incoming dictionary. As a result, for custom ad integrations (which build native ads from JS-provided data, see ios/ads/THEOplayerRCTAdEventAdapter.swift), the custom data is always nil. Consider threading customData through the initializer chain and reading adData[PROP_CUSTOM_DATA] in toAd/toAdBreak, or explicitly document that the JS->native direction is unsupported (Android's AdAdapter.parseAd currently returns null for getCustomData with a 'Not supported yet' comment).
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +136 to +141
val customData = ad.customData
if (customData is JSONObject) {
adPayload.putMap(PROP_CUSTOM_DATA, BridgeUtils.fromJSONObjectToBridge(customData))
} else if (customData is Map<*, *>) {
adPayload.putMap(PROP_CUSTOM_DATA, BridgeUtils.fromJSONObjectToBridge(JSONObject(customData)))
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Nested maps/lists inside a Map-typed customData may be silently dropped

When the native ad's custom data comes back as a plain Map, it is wrapped with JSONObject(customData). On Android, JSONObject(Map) casts keys to String (throwing ClassCastException/NullPointerException for non-String or null keys) and relies on JSONObject.wrap() for values; any value type that wrap() leaves as a raw object (or Float, custom objects, etc.) will not match any branch in BridgeUtils.fromJSONObjectToBridge (android/src/main/java/com/theoplayer/util/BridgeUtils.kt:28-37) and is silently omitted from the bridged map. Worth confirming what shapes the SDK actually returns for customData for the supported integrations.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants