Migration from 4.X to 5.X
All code samples are provided in swift unless otherwise noted. The 5.X documentation is effective for v5.0.0. Refer to the main documentation for the most up-to-date information with the latest 5.X version.
New Features for the 5.X Series π
Core SDK Required π
The Chartboost Mediation 5.X series of SDKs introduces a new architecture centered around the Chartboost Core SDK. By moving the Mediation SDKβs consent duties to the Core SDK, the Mediation SDK is able to more rapidly keep pace with the evolving privacy and consent landscape.
Review the Core SDK integration guide for more information.
Mediation API π
The public APIs have been audited so that there is better parity between all of the platforms.
- The fixed and adapter banner APIs have been merged into a singular API.
- The fullscreen ads API architecture has been updated to match that of the banner ads API.
- The old
Helium
moniker has been rebranded withChartboostMediation
to be consistent with the productβs marketing terms. - The
ChartboostMediation
prefixing has been dropped for brevity. In the event that there is a name collision with another SDK in the Publisher app, using theChartboostMediation
.namespace before the object type will tell Xcode explicitly which object to use.
Classes π
Mediation 4.X | Mediation 5.X |
---|---|
Helium |
ChartboostMediation |
HeliumAdapterInfo |
AdapterInfo |
HeliumBannerView |
BannerAdView |
HeliumImpressionData |
ImpressionData |
HeliumInitializationOptions |
PreinitializationOptions |
HeliumKeywords |
Removed, now uses standard Dictionary type |
Protocols π
Mediation 4.X | Mediation 5.X |
---|---|
HeliumBannerAdDelegate |
BannerAdViewDelegate |
HeliumSdkDelegate |
Removed |
Integration π
SDK Initialization π
Starting with Mediation SDK 5.0.0, the Mediation SDK can only be initialized by Chartboost Core SDK. This architectural change was made so that Core can manage the initialization sequences of the current Mediation SDK and future SDKs on the horizon.
Review the Core SDK integration guide for more information.
Network Killswitch π
Since Mediation SDK initialization is now handled by the Core SDK, the network killswitch feature has been moved to the static method ChartboostMediation.setPreinitializationConfiguration()
that must be called before Core SDK initialization is initiated.
-
import ChartboostMediationSDK // Optionally create an options object the with a list of partner IDs to disable. let options = HeliumInitializationOptions( skippedPartnerIdentifiers: YOUR_LIST_OF_PARTNER_IDS_TO_SKIP ) // Initialize Chartboost Mediation. Helium.shared().start( withAppId: "<YOUR APP ID>", options: options, delegate: self // optional delegate, can be nil ) // Optionally implement the HeliumSdkDelegate protocol to get notified when // Chartboost Mediation is initialized. func heliumDidStartWithError(_ error: ChartboostMediationError?) { if let error { // Handle error } else { // Success } }
-
import ChartboostCoreSDK import ChartboostMediationSDK // Optionally set the Chartboost Mediation preinitialization configuration // to disable some mediation partners. ChartboostMediation.setPreinitializationConfiguration( .init(skippedPartnerIDs: YOUR_LIST_OF_PARTNER_IDS_TO_SKIP) ) // Create a consent module instance, e.g. Usercentrics let usercentrics = UsercentricsAdapter( options: .init(settingsId: "<YOUR USECENTRICS SETTINGS ID>") ) // Initialize Core. // This automatically initializes the Chartboost Mediation SDK, as well as other // modules included in the `modules` array. // Make sure to include your consent module in this array. ChartboostCore.initializeSDK( configuration: .init(chartboostAppID: "<YOUR APP ID>"), modules: [usercentrics], moduleObserver: self // optional observer, can be nil ) // Optionally implement the ModuleObserver protocol to get notified when some // particular module is initialized (e.g. Chartboost Mediation). func onModuleInitializationCompleted(_ result: ModuleInitializationResult) { if result.module.moduleID == ChartboostMediation.coreModuleID { if let error = result.error { // Handle error } else { // Success } } }
Consent π
All privacy and consent related APIs have been removed from the Mediation 5.X SDK and will be handled by the Core SDK.
The Mediation SDK will continue to utilize the TCFv2 string as part of auction requests, and will forward consent changes to the partner adapters. For partners that utilize complex non-IAB compliant privacy and consent signals that cannot be extrapolated from Core SDK consent signals, last resort APIs will be exposed via that partner adapterβs AdapterConfiguration
class and must be directly set on the adapter configuration.
For more information on supported Consent Mediation Platforms and their integration, review the Core SDK integration guide.
HyprMX π
import ChartboostMediationAdapterHyprMX
// Set consent status directly on the adapter configuration
HyprMXAdapterConfiguration.setConsentStatusOverride(CONSENT_GIVEN)
Pangle π
import ChartboostMediationAdapterPangle
// Set consent status directly on the adapter configuration
PangleAdapterConfiguration.setGDPRConsentOverride(.consent)
PangleAdapterConfiguration.setDoNotSellOverride(.sell)
UnityAds π
import ChartboostMediationAdapterUnity
// Set consent status directly on the adapter configuration
UnityAdsAdapterConfiguration.setGDPRConsentOverride(true)
UnityAdsAdapterConfiguration.setPrivacyConsentOverride(true)
Vungle π
// Demonstrate setting the consent related APIs
// Set consent status directly on the adapter configuration
VungleAdapterConfiguration.setGdprStatusOverride(true)
VungleAdapterConfiguration.setCcpaStatusOverride(true)
Publisher Metadata π
Publisher-specified data used to improve auction requests have been moved to the Core SDK, and will still be available to the Mediation 5.X auction requests.
Mediation 4.X | Mediation 5.X |
---|---|
Helium.userIdentifier |
ChartboostCore.publisherMetadata.setPlayerIdentifier() |
Helium.setGameEngineName(_, version:) |
ChartboostCore.publisherMetadata.setFramework(name:, version:) |
Helium.setSubjectToCoppa() |
ChartboostCore.publisherMetadata.setIsUserUnderage() |
Adaptive Banner Ads π
The changes to the adaptive banner ads APIs revolved around naming convention parity.
-
import ChartboostMediationSDK // Create the banner ad instance let bannerAd = ChartboostMediationBannerView() // Create the load request let request = ChartboostMediationBannerLoadRequest( placement: "YOUR_MEDIATION_PLACEMENT", size: .adaptive(width: SOME_WIDTH) // see BannerSize for other options ) // Load the ad with the request bannerAd.load(with: request, viewController: self) { result in if let error = result.error { // Handle error } else { // Success } }
-
import ChartboostMediationSDK // Create the banner ad instance let bannerAd = BannerAdView() // Create the load request let request = BannerAdLoadRequest( placement: "YOUR_MEDIATION_PLACEMENT", size: .adaptive(width: SOME_WIDTH) // see BannerSize for other options ) // Load the ad with the request bannerAd.load(with: request, viewController: self) { result in if let error = result.error { // Handle error } else { // Success } }
Resizing adaptive banner π
The changes to resizing adaptive banner ads APIs revolved around naming convention parity.
-
func willAppear(bannerView: ChartboostMediationBannerView) { // Manual layout bannerView.frame.size = bannerView.size?.size ?? .zero // The alignment of the ad can be changed if the frame of the bannerView is larger than the ad. bannerView.horizontalAlignment = .left bannerView.verticalAlignment = .top // Auto-layout will automatically resize the bannerView based on the set constraints. }
-
func willAppear(bannerView: ChartboostMediationBannerView) { // Manual layout @@ -194,141 +215,31 @@ bannerView.verticalAlignment = .top // Auto-layout will automatically resize the bannerView based on the set constraints. }
Fixed Banner Ads π
The fixed banner APIs have been deprecated and removed. To create and load fixed banners in the 5.X series, use the new banner APIs with a fixed size.
-
import ChartboostMediationSDK // Create the banner ad instance with the desired fixed size // Fixed 320x50 standard banner let bannerAd = Helium.shared().bannerProvider( with: self, andPlacementName: "YOUR_MEDIATION_PLACEMENT", andSize: .standard ) // Fixed 300x250 medium rectangle banner // let bannerAd = Helium.shared().bannerProvider( // with: self, // andPlacementName: "YOUR_MEDIATION_PLACEMENT", // andSize: .medium // ) // Fixed 720x90 leaderboard banner // let bannerAd = Helium.shared().bannerProvider( // with: self, // andPlacementName: "YOUR_MEDIATION_PLACEMENT", // andSize: .leaderboard // ) // Load the ad bannerAd.load(with: self)
-
import ChartboostMediationSDK // Create the banner ad instance let bannerAd = BannerAdView() // Create the load request with the desired fixed size // Fixed 320x50 standard banner let request = BannerAdLoadRequest( placement: "YOUR_MEDIATION_PLACEMENT", size: .standard ) // Fixed 300x250 medium rectangle banner // let request = BannerAdLoadRequest( // placement: "YOUR_MEDIATION_PLACEMENT", // size: .medium // ) // Fixed 720x90 leaderboard banner // let request = BannerAdLoadRequest( // placement: "YOUR_MEDIATION_PLACEMENT", // size: .leaderboard // ) // Load the ad with the request bannerAd.load(with: request, viewController: self) { result in if let error = result.error { // Handle error } else { // Success } }
Fullscreen Ads π
The changes to the fullscreen ads APIs revolved around naming convention parity and architectural alignment with the banner ads APIs.
-
import ChartboostMediationSDK // Interstitial Ads // Create the load request let request = ChartboostMediationAdLoadRequest( placement: "YOUR_INTERSTITIAL_MEDIATION_PLACEMENT" ) // Load the ad with the request Helium.shared().loadFullscreenAd(with: request) { result in if let error = result.error { // Handle error } else { // Success } } // Rewarded Ads // Create the load request let request = ChartboostMediationAdLoadRequest( placement: "YOUR_REWARDED_MEDIATION_PLACEMENT" ) // Load the ad with the request Helium.shared().loadFullscreenAd(with: request) { result in if let error = result.error { // Handle error } else { // Success } }
-
import ChartboostMediationSDK // Fullscreen Ads // Create the load request let request = FullscreenAdLoadRequest( placement: "YOUR_FULLSCREEN_MEDIATION_PLACEMENT" ) // Load the ad with the request FullscreenAd.load(with: request) { result in if let error = result.error { // Handle error } else if let ad = result.ad { // Success ad.customData = "Y3VzdG9tIGRhdGE=" // base 64 encoded string for rewarded fullscreen ads } else { // Handle no ad error } }
Clearing Loaded Ads π
The changes to clearing loaded ads revolved around naming convention parity and architectural alignment with the banner ads APIs.
-
// Clearing Interstitial and Rewarded Ads interstitialAd?.clearLoadedAd() rewardedAd?.clearLoadedAd() // Clearing Banner Ads bannerAd?.clear()
-
FullscreenAd.invalidate() BannerAdView.reset()
Winning Bid Information π
The keys used to retrieve information from the dictionary have been normalized to use underscores instead of hyphens.
Mediation 4.X | Mediation 5.X |
---|---|
auction-id |
auction_id |
partner-id |
partner_id |
price |
price |
line_item_id |
line_item_id |
line_item_name |
line_item_name |
Configure Mediation π
Test Mode π
The changes to test mode revolved around naming convention parity.
-
Add the environment variable `HELIUM_TEST_MODE` in your appβs scheme and set it to `on` or `off`.
-
// For swift, set to true or false ChartboostMediation.isTestModeEnabled = true // For Objective-C, set to 'TRUE'/'FALSE' or 'YES'/'NO' ChartboostMediation.isTestModeEnabled = TRUE;
Privacy Methods π
All privacy methods have been removed from 5.X and migrated to Chartboost Core SDK.
-
// COPPA Helium.shared().setSubjectToCoppa(true) // or Helium.shared().setSubjectToCoppa(false) [[Helium sharedHelium] setSubjectToCoppa:YES]; // or [[Helium sharedHelium] setSubjectToCoppa:NO]; //- By sending `setSubjectToCoppa(true)`/`setSubjectToCoppa (YES)` you indicate that you want your content treated as child-directed for purposes of COPPA. We will take steps to disable interest-based advertising for such ad requests. //- By sending `setSubjectToCoppa(false)`/`setSubjectToCoppa (NO)`, you indicate that you don't want your content treated as child-directed for purposes of COPPA. You represent and warrant that your applications and services are not directed towards children and that you will not provide any information to Mediation from a user under the age of 13. // GDPR Helium.shared().setSubjectToGDPR(true) // or Helium.shared().setSubjectToGDPR(false) [[Helium sharedHelium] setSubjectToGDPR:YES]; // or [[Helium sharedHelium] setSubjectToGDPR:NO]; //- By sending `setSubjectToGDPR(true)`/`setSubjectToGDPR (YES)`, you indicate that GDPR is applied to this user from your application. //- By sending `setSubjectToGDPR(false)`/`setSubjectToGDPR (NO)`, you indicate that GDPR is not applied to this user from your application. // User Given Consent Helium.shared().setUserHasGivenConsent(true) // or Helium.shared().setUserHasGivenConsent(false) [[Helium sharedHelium] setUserHasGivenConsent:YES]; // or [[Helium sharedHelium] setUserHasGivenConsent:NO]; //- By sending `setUserHasGivenConsent(true)`/`setUserHasGivenConsent (YES)`, you indicate that this user from your application has given consent to share personal data for behavior-targeted advertising. //- By sending `setUserHasGivenConsent(false)`/`setUserHasGivenConsent (NO)`, you indicate that this user from your application has not given consent to use its personal data for behavior-targeted advertising, so only contextual advertising is allowed. //CCPA Helium.shared().setCCPAConsent(true) // or Helium.shared().setCCPAConsent(false) [[Helium sharedHelium] setCCPAConsent:YES]; // or [[Helium sharedHelium] setCCPAConsent:NO]; //- By sending `setCCPAConsent(true)`/`setCCPAConsent (YES)`, you indicate that this user from your application has given consent to share personal data for behavior-targeted advertising under CCPA regulation. //- By sending `setCCPAConsent(false)`/`setCCPAConsent (NO)`, you indicate that this user from your application has not given consent to allow sharing personal data for behavior-targeted advertising under CCPA regulation.
Keywords π
The changes to keywords revolved around naming convention parity and architectural alignment with the banner ads APIs.
-
let interstitial = Helium.shared().interstitialAdProvider(with: self, andPlacementName: "placement") let rewarded = Helium.shared().rewardedAdProvider(with: self, andPlacementName: "placement") let banner = Helium.shared().bannerProvider(with: self, andPlacementName: "placement", andSize: .standard) // Setting Keyword // (The set method returns a boolean whether or not if the keyword has been successfully set) let success = interstitial?.keywords?.set(keyword: "i12_keyword1", value: "i12_value1") ?? false if (!success) { // Failed to set keyword } let success = rewarded?.keywords?.set(keyword: "rwd_keyword1", value: "rwd_value1") ?? false if (!success) { // Failed to set keyword } let success = banner?.keywords?.set(keyword: "bnr_keyword1", value: "bnr_value1") ?? false if (!success) { // Failed to set keyword } // Remove Custom Keyword (The remove method returns the value of the key removed) let removedi12KeywordValue = interstitial?.keywords?.remove(keyword:"i12_keyword1"); let removedRewardedKeywordValue = interstitial?.keywords?.remove(keyword: "rwd_keyword1"); let removedBannerKeywordValue = interstitial?.keywords?.remove(keyword: "bnr_keyword1");
-
// Set Keywords // Banner Ads let banner = BannerAdView() banner.keywords = ["keyword1": "value1"] // Fullscreen Ads FullscreenAd.load( with: .init( placement: "placement", keywords: ["keyword1": "value1"], // set the whole dictionary partnerSettings: nil ) ) { result in // handle result } // Remove Keywords let banner = BannerAdView() banner.keywords = nil // remove the whole dictionary
Setting User Identifier π
The user identifier property is now configured with the Chartboost Core SDK.
-
Helium.shared().userIdentifier = "user"
-
ChartboostCore.publisherMetadata.setPlayerID("player_id")
Setting Custom Data π
HeliumRewardedAd
no longer exists in 5.X and is replaced with FullscreenAd
to align with the banner ads APIs.
-
let rewardedAd = Helium.shared().rewardedAdProvider(with: self, andPlacementName: "placement") // load ad let customData = "custom data".data(using: .utf8) let base64CustomData = customData?.base64EncodedString() rewardedAd?.customData = base64CustomData // show ad
-
let fullscreenAd: FullscreenAd = ... // obtain the ad with a load request fullscreenAd.customData = "Y3VzdG9tIGRhdGE=" // base 64 encoded string
Implementation π
The changes to implementation revolved around naming convention parity.
-
public class HeliumImpressionData: NSObject { // The placement associated with Impression Level Revenue Data. let placement: String // The Impression Level Revenue Data JSON. let jsonData: [String : Any] }
-
public class ImpressionData: NSObject { // The placement associated with Impression Level Revenue Data. let placement: String // The Impression Level Revenue Data JSON. let jsonData: [String : Any] }
Usage Example
-
NotificationCenter.default.addObserver( self, selector: #selector(didReceiveILRDNotification), name: .heliumDidReceiveILRD, object: nil ) @objc func didReceiveILRDNotification(notification: Notification) { // Extract the ILRD payload. guard let ilrd = notification.object as? HeliumImpressionData else { return } // Placement name let placement = ilrd.placement // JSON let json = ilrd.jsonData }
-
NotificationCenter.default.addObserver( self, selector: #selector(didReceiveILRDNotification), name: .chartboostMediationDidReceiveILRD, object: nil ) @objc func didReceiveILRDNotification(notification: Notification) { // Extract the ILRD payload. guard let ilrd = notification.object as? ImpressionData else { return } // Placement name let placement = ilrd.placement // JSON let json = ilrd.jsonData }
Delegate Usage π
Mediation Start / Module Observer π
Initialization of the Mediation SDK is now done by the Chartboost Core SDK. To receive initialization callbacks, utilize the module observer.
-
extension AppDelegate: HeliumSdkDelegate { func heliumDidStartWithError(_ error: ChartboostMediationSDK.ChartboostMediationError?) { if let error = error { print("Chartboost Mediation did not start due to error: \(error)") } else { print("Chartboost Mediation Started Successfully") } } }
-
extension ChartboostMediationController: ModuleObserver { func onModuleInitializationCompleted(_ result: ModuleInitializationResult) { // Chartboost Mediation SDK initialization result is represented by the initialization result of // an internal module with module ID `ChartboostMediation.coreModuleID`. let moduleName = (result.moduleID == ChartboostMediation.coreModuleID ? "Chartboost Mediation" : "Chartboost Core module \(result.moduleID)") if let error = result.error { print("[Error] \(moduleName) initialization failed: \(error.localizedDescription)") initializationResult = .failure(error) completionHandler?(.failure(error)) } else { print("[Success] \(moduleName) initialization succeeded") initializationResult = .success(true) completionHandler?(.success(true)) } } }
Interstitial Ad Delegate π
-
extension ViewController: CHBHeliumInterstitialAdDelegate { func heliumInterstitialAd( withPlacementName placementName: String, requestIdentifier: String, winningBidInfo: [String : Any]?, didLoadWithError error: ChartboostMediationSDK.ChartboostMediationError? ) { if let error = error { print("Interstitial with Placement Name:\(placementName) failed to load with error:\(error.localizedDescription)") } else { print("Interstitial with Placement Name:\(placementName) didLoad") } } func heliumInterstitialAd( withPlacementName placementName: String, didShowWithError error: ChartboostMediationSDK.ChartboostMediationError? ) { if let error = error { print("Interstitial with Placement Name:\(placementName) failed to show with error:\(error.localizedDescription)") } else { print("Interstitial with Placement Name:\(placementName) didShow") } } func heliumInterstitialAd( withPlacementName placementName: String, didCloseWithError error: ChartboostMediationSDK.ChartboostMediationError? ) { if let error = error { print("Interstitial with Placement Name:\(placementName) failed to close with error:\(error.localizedDescription)") } else { print("Interstitial with Placement Name:\(placementName) didClose") } } func heliumInterstitialAdDidRecordImpression(withPlacementName placementName: String) { print("Impression recorded") } }
-
extension FullscreenAdController: FullscreenAdDelegate { func didRecordImpression(ad: FullscreenAd) { log(action: "record impression", placementName: placementName, error: nil) } func didClick(ad: FullscreenAd) { log(action: "click", placementName: placementName, error: nil) } func didReward(ad: FullscreenAd) { log(action: "get reward", placementName: placementName, error: nil) } func didClose(ad: FullscreenAd, error: ChartboostMediationError?) { log(action: "close", placementName: placementName, error: error) } func didExpire(ad: FullscreenAd) { log(action: "expire", placementName: placementName, error: nil) } }
Banner Ad Delegate π
-
extension ViewController: HeliumBannerAdDelegate { func heliumBannerAd( placementName: String, requestIdentifier: String, winningBidInfo: [String : Any]?, didLoadWithError error: ChartboostMediationSDK.ChartboostMediationError? ) { if let error = error { print("Banner with Placement Name:\(placementName) failed to load with error:\(error.localizedDescription)") } else { print("Banner with Placement Name:\(placementName) didLoad") } } func heliumBannerAd( placementName: String, didClickWithError error: ChartboostMediationError? ) { if let error = error { print("Banner with Placement Name:\(placementName) didClick with error:\(error.localizedDescription)") } else { print("Banner with Placement Name:\(placementName) didClick") } } func heliumBannerAdDidRecordImpression(placementName: String) { print("Impression recorded") } }
-
extension BannerAdController: BannerAdViewDelegate { func willAppear(bannerView: BannerAdView) { // Called when a new ad is about to appear inside of `bannerView`. This method can be used // to manually size `bannerView` if desired: // if let size = bannerView.size?.size { // bannerView.frame.size = size // } // This method can also be used to check other updated properties of `bannerView`. } }
Rewarded Ad Delegates π
Rewarded ad delegates are no longer available for 5.X.
-
// Implement the `CHBHeliumRewardedAdDelegate` protocol to receive notifications about rewarded ads loading, displaying, and closing. @interface ViewController () <CHBHeliumRewardedAdDelegate> // This will allow you to implement the following methods: func heliumRewardedAd( withPlacementName placementName: String, requestIdentifier: String, winningBidInfo: [String : Any]?, didLoadWithError error: ChartboostMediationSDK.ChartboostMediationError? ) { if let error = error { print("Rewarded with Placement Name:\(placementName) failed to load with error:\(error.localizedDescription)") } else { print("Rewarded with Placement Name:\(placementName) didLoad") } } func heliumRewardedAd( withPlacementName placementName: String, didShowWithError error: ChartboostMediationSDK.ChartboostMediationError? ) { if let error = error { print("Rewarded with Placement Name:\(placementName) failed to show with error:\(error.localizedDescription)") } else { print("Rewarded with Placement Name:\(placementName) didShow") } } func heliumRewardedAd( withPlacementName placementName: String, didCloseWithError error: ChartboostMediationSDK.ChartboostMediationError? ) { if let error = error { print("Rewarded with Placement Name:\(placementName) failed to close with error:\(error.localizedDescription)") } else { print("Rewarded with Placement Name:\(placementName) didClose") } } func heliumRewardedAdDidGetReward(withPlacementName placementName: String) { print("Got Reward for RV with placementName:\(placementName)") } func heliumRewardedAdDidRecordImpression(withPlacementName placementName: String) { print("Impression recorded") }
Error Codes π
5.X will continue to use codes from 4.X with minor changes in the descriptions. Any new error codes introduced in 5.X will follow the same naming convention.