React Native Integraiton document

React Native Integraiton document

Yieldlove SDK for React Native

As of version 4, the main class name has been renamed to StroeerSDK.

The Yieldlove class is no longer supported.

For more information, please see this document.

Starting from Version 3, all libraries will share the same version number to prevent mismatches and reduce confusion.

Additionally, the SDK configuration has been updated. Please verify that all configurations are correctly set in your project.

Ensure you are using the correct version for all dependencies.

Release Note (v4.1.0)

  • Added support for IO campaign banners from Ströer.(Android, iOS)

  • Implemented disableErrorLog. When enabled, Android error messages will be replaced with informational messages. The default value is false.(Android)

  • Fixed a minor issue related to configuration loading. (Android)

  • Enhanced debug panel with more detailed information.(iOS)

  • General bug fixes and stability improvements (iOS)

Installation

Using npm

$ npm install react-native-yieldlove --save

Using yarn

$ yarn add react-native-yieldlove

 

Set-Up

If you don't want use Cocoapods, you can always link the library manually.

Android

Add our ad-integration SDK into your app's build.gradle file:

allprojects { repositories { maven { url 'https://slabs-yieldlove-ad-integration.s3.eu-central-1.amazonaws.com/android' content { includeGroup("com.yieldlove.adIntegration") } } } }

iOS

The package is automatically linked when building the app. All you need to do is:

$ cd ios && pod install

 

Gravite Set-Up (Optional)

Please reach out to your Ströer Publisher Account Manager to enable the Gravite plugin.

The Stroeer SDK only references the Gravite Core Library. To use the ad networks provided by Gravite, you must include the ad networks for Gravite Library. For more details, refer to the Gravite setup page.

You can upgrade the Gravite SDK version to utilize additional features. The officially supported version is 3.12.5 for Android and 3.12.0 for iOS

Android https://aatkit.gitbook.io/android-integration/start/setup/maven

  • Repository settings

allprojects { repositories { google() mavenCentral() // Third-party repositories maven { url 'https://android-sdk.aatkit.com/maven/' } // AATKit maven { url 'https://s3.amazonaws.com/smaato-sdk-releases/' } // Smaato maven { url 'https://packagecloud.io/smartadserver/android/maven2' } // SmartAdServer maven { url 'https://verve.jfrog.io/artifactory/verve-gradle-release' } // PubNative maven { url 'https://android-sdk.is.com/' } // ironSource maven { url 'https://maven.ogury.co' } // Ogury maven { url 'https://android-sdk-rtb.gravite.net/maven' } // GraviteRTB maven { url 'https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea' } // Mintegral maven { url 'https://slabs-yieldlove-ad-integration.s3.eu-central-1.amazonaws.com/android' content { includeGroup("com.yieldlove.adIntegration") } } // Yieldlove } }
  • Dependency settings

dependencies { implementation ('com.yieldlove.adIntegration:gravite:8.1.0') implementation ('com.intentsoftware.addapptr:AATKit:3.12.5') { transitive = true } }

iOS https://aatkit.gitbook.io/ios-integration/start/setup/cocoapods

pod 'YieldloveAdIntegration/Gravite', '10.4.1' pod 'AATKit', '3.12.0'

 

 

Confiant Set-Up (Optional)

Please contact your Ströer Publisher Account Manager to enable the Confiant plugin.

Android

  • Repository settings

repositories { maven{ url 'https://cdn.confiant-integrations.net/backend-integrations/in-app/releases/android/maven' content { includeGroup("com.confiant.android") } maven { url 'https://slabs-yieldlove-ad-integration.s3.eu-central-1.amazonaws.com/android' content { includeGroup("com.yieldlove.adIntegration") } } // Yieldlove } }
  • Dependency setting

dependencies { implementation 'com.confiant.android:sdk:6.1.3' implementation 'com.yieldlove.adIntegration:confiant:8.1.0' }

iOS

  • CocoaPod

# This should be decleared before "Target" source 'https://cdn.cocoapods.org/' source 'https://cdn.confiant-integrations.net/backend-integrations/in-app/releases/ios/podspecs.git' # This should be decleared in "Target" pod 'ConfiantSDK', '6.1.0' pod 'YieldloveAdIntegration', :podspec => 'https://slabs-yieldlove-ad-integration.s3.eu-central-1.amazonaws.com/ios/YieldloveAdIntegration-10.4.1.podspec', subspecs: ['Confiant']
  • CocoaPod for Gravite & Confiant
    If you want to use both Confiant and Gravite, use the following settings. (Android doesn’t require the different settings)

# This should be decleared before "Target" source 'https://cdn.cocoapods.org/' source 'https://cdn.confiant-integrations.net/backend-integrations/in-app/releases/ios/podspecs.git' # This should be decleared in "Target" pod 'AATKit', '3.12.0' pod 'ConfiantSDK', '6.1.0' pod 'YieldloveAdIntegration', :podspec => 'https://slabs-yieldlove-ad-integration.s3.eu-central-1.amazonaws.com/ios/YieldloveAdIntegration-10.4.1.podspec', subspecs: ['Confiant', 'Gravite']

Example Code

Contact to your account manager to obtain your application name (APPLICATION_NAME) and call strings (INTERSTITIAL_CALL_STRING and BANNER_CALL_STRING). Each call string represents a single slot.

import { StroeerSDK, StroeerIdentity } from 'react-native-yieldlove'; // Initialize SDK first - MUST be called before any other SDK calls StroeerSDK.setApplicationName(applicationName); console.log(`[RN] SDK initialized with application: ${applicationName}`); StroeerSDK.enableDebugMode(); // StroeerSDK.enableInspectionMode(); // This will give more debug information and allows to open the debug information panel // optional global custom targeting // Meaning: targeting values set per ad request / per ad unit / per placement. StroeerSDK.setCustomTargeting({ userAge: ['25'], userInterest: ['sports', 'technology', 'music'], userLocation: ['New York'], }); // Set global context targeting // Meaning: targeting values applied globally for the whole app/session/user context, and automatically included in all ad requests (or most of them). // Note: iOS SDK doesn't support context targeting yet StroeerSDK.setContextTargeting(['sport', 'news']); // optional for additional user information // If you add this information using the user information, you may be able to get more expensive ads. StroeerIdentity.setEmail('freeschool@gmail.com'); StroeerIdentity.setPhone('123456788'); StroeerIdentity.setPuid('123456'); StroeerIdentity.setRegionCode('DE'); StroeerIdentity.setCityCode('Berlin'); StroeerIdentity.apply(); export default function BannerSimpleExample() { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <StroeerBannerAd publisherSlotName={SLOT} contentUrl="https://stroeer.de" customTargeting={{ pos: 'top', test: 'banner' }} style={{ width: 320, height: 50, // initial size (native will update it after load) }} onAdLoaded={({ width, height, publisherSlotName, source }) => { console.log( `[RN] Banner loaded: ${publisherSlotName} -> ${width}x${height} (${source})` ); }} onAdFailedToLoad={({ message }) => { console.log(`[RN] Banner failed: ${message}`); }} onAdClicked={() => { console.log('[RN] Banner clicked'); }} onAdImpression={() => { console.log('[RN] Banner impression'); }} /> </View> ); }

 

Example Code for Gravite (Optional)

import { AppState, AppStateStatus, Platform } from 'react-native'; import { StroeerGravite } from 'react-native-yieldlove'; let appStateSub: { remove: () => void } | null = null; export async function setupGravite() { // Optional: debug logs StroeerGravite.enableDebugMode(); // Optional: cache size StroeerGravite.setCacheSize(2); // Optional: map your Stroeer placements -> Gravite placements StroeerGravite.setPlacementMapTable({ 'b1': 'gb1', 'b2': 'gb2', }); // Optional: only for QA/testing // StroeerGravite.enableTestMode('com.example.app', 12345, true); // Optional: direct calls if your native supports this mode // StroeerGravite.enableDirectGraviteCall(); // Initialize const ok = await StroeerGravite.initialize(); if (!ok) throw new Error('Gravite initialize() returned false'); // Wire app foreground/background -> onResume/onPause StroeerGravite.onResume(); // app is active at startup appStateSub?.remove(); appStateSub = AppState.addEventListener('change', (next: AppStateStatus) => { if (next === 'active') { StroeerGravite.onResume(); } else if (next === 'inactive' || next === 'background') { StroeerGravite.onPause(); } }); return ok; } export function teardownGravite() { appStateSub?.remove(); appStateSub = null; } export default function App() { useEffect(() => { setupGravite().catch((e) => { console.log('[RN] Gravite setup failed:', e); }); return () => teardownGravite(); }, []); return null; // or your normal navigation/root component }

To ensure proper functionality, please preload an interstitial ad before use—ideally when the application starts. Since GraviteSDK requires 3 to 10 seconds to load an interstitial, StroeerSDK cannot effectively manage interstitial results from Gravite in real time. If not preloaded, the SDK will return a 'No Interstitial' error, and the initial interstitial will fail to display.

EnableDebugMode Method. The Debug Mode provides detailed logs to assist with troubleshooting and debugging

Debug Mode must not be enabled in production environments. This mode is intended only for testing and development.

EnableTestMode Method

public void enableTestMode(String bundleId, Integer accountId, boolean forceToExecute)

Parameters:

  • bundleId
    Gravite identifies your app using its bundle ID. If you need to use a different bundle ID for publishing, testing, or other purposes, you can override the default bundle ID by specifying an "alternative bundle ID" here.

    • To use the app’s default bundle ID, pass “"empty string.

  • accountId
    AATKit’s test mode allows ad testing even before your app is fully set up with Gravite. Use your accountId to activate test mode.

    • If not needed, pass 0.

  • forceToExecute
    If set to true, the SDK will bypass normal ad rendering and always call Gravite Ads. This ensures that your application integrates properly with Gravite.

Test Mode must not be enabled in production environments. This modes is intended only for testing and development.

Gravite includes a preloading feature to ensure seamless display of banner and interstitial ads. By default, the cache size is set to 1. However, if Gravite is accessed frequently, the cache may empty too quickly, causing delays or empty ads while new ads load. To mitigate this, consider increasing the cache size

StroeerSDK provides to call Gravite directly bypassing the Stroeer Ad request. Please contact the Stroeer administrator to discuss this feature.
To enable Gravite Direct Call, use the the code

StroeerSDK features a placement mapping capability that automatically translates Stroeer placement names to their corresponding Gravite placements. This eliminates the need to create identical placement names for each provider, streamlining the integration process.
Create a mapping table and send it via setPlacementMapTable.

StroeerGravite.setPlacementMapTable({ 'b1': 'gb1', 'b2': 'gb2', });

This configuration ensures that when Gravite processes placements:

  • Stroeer placement b1 will be mapped to Gravite placement gb1.

  • Stroeer placement b2 will be mapped to Gravite placement gb2.

The StroeerGravite.initialize function is responsible for initializing the Gravite SDK. This setup process ensures that the necessary configurations and resources are properly loaded before the application starts displaying ads.

const ok = await StroeerGravite.initialize();
if (!ok) throw new Error('Gravite initialize() returned false');

 

Transferring Resume / Pause events.

Gravite requires page resume and pause events for efficient resource management. Call StroeerGravite.onResume(); and StroeerGravite.onPause(); whenever the page state changes. There are multiple ways to implement this. The example code demonstrates one of those approaches.

These methods must be invoked on every page; otherwise, ads may not render properly. Refer to the following code for implementation.

class App extends Component { constructor(props) { super(props); this.state = { appState: AppState.currentState }; } componentDidMount() { this.appStateListener = AppState.addEventListener('change', this.handleAppStateChange); } componentWillUnmount() { this.appStateListener.remove(); // Cleanup event listener } handleAppStateChange = (nextAppState) => { if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') { StroeerGravite.onResume(); } else if (nextAppState === 'background') { StroeerGravite.onPause(); } this.setState({ appState: nextAppState }); }; render() { return ( <View> <Text>Current App State: {this.state.appState}</Text> </View> ); } }

Example Code for Confiant (Optional)

import { StroeerConfiant } from 'react-native-yieldlove'; export async function setupConfiant() { // Optional (QA only): enable test mode before initialize() // StroeerConfiant.enableTestMode(); const confiantPropertyId = 'YOUR_CONFIANT_PROPERTY_ID'; const enableReload = true; const ok = await StroeerConfiant.initialize(confiantPropertyId, enableReload); if (!ok) { throw new Error('Confiant initialize() returned false'); } console.log('[RN] Confiant initialized ✅'); return ok; }

This is to test if Confiant works. If this method is called, all the ads will be blocked.

Test Mode must not be enabled in production environments. This modes is intended only for testing and development.

Parameters:

  • confiantPropertyID: To obtain the confiantPropertyID, please contact your Ströer Publisher Account Manager.

  • enableReload: This setting determines whether Confiant should reload advertisements when they are blocked.

    • If set to true, Confiant will attempt to reload the advertisement up to two times.

    • If set to false, the invalid advertisement will simply be blocked without a reload attempt.


isInitialized indicates whether the Confiant SDK was initialized successfully (true) or failed (false).

 

Enable ID5

Starting from Version 3, the SDK supports ID5. This feature is disabled by default. To enable it, please contact your Ströer account manager.

You don’t need to make any code changes to use ID5. However, for improved identification, you can provide additional user information to ID5. Please refer to the ID5 website for details.

This information can be added at any time. StroeerSDK automatically checks the provided variables and updates the ID from ID5. However, for optimal identification, we recommend setting this information before SDK initialization, if possible.

To use ID5, the user must provide consent as required by the publisher. Additionally, if the user opts out of ID5 in their privacy settings, the SDK will not use ID5.

StroeerIdentity.setEmail('test@test.com'); //User Email StroeerIdentity.setPhone('12345656'); //User Phonenumber StroeerIdentity.setPuid('115352342'); //Publisher User ID StroeerIdentity.setRegionCode('CA'); //Region Code StroeerIdentity.setCityCode('MTL'); //City Code StroeerIdentity.apply(); //Call to apply the updates

Custom Information

  • CustomInfo is optional, and you are not required to provide all the information.

  • For RegionalCode, use the ISO-3166-2 standard. If the location is in the USA, specify the 2-letter state code(reference).

  • For CityCode, use the United Nations Code for Trade & Transport Locations (UN/LOCODE) format (reference).

 

Troubleshooting

Error: Multiple dependencies with different sources with CocoaPod

This is because you may want to use Gravite and Confiant together and use both settings in the Podfile.
Use the following settings in the PodfileReact Native Integraiton document | iOS.1

# This should be decleared before "Target" source 'https://cdn.cocoapods.org/' source 'https://cdn.confiant-integrations.net/backend-integrations/in-app/releases/ios/podspecs.git' # This should be decleared in "Target" pod 'AATKit', '3.12.0' pod 'ConfiantSDK', '6.1.0' pod 'YieldloveAdIntegration', :podspec => 'https://slabs-yieldlove-ad-integration.s3.eu-central-1.amazonaws.com/ios/YieldloveAdIntegration-10.4.1.podspec', subspecs: ['Confiant', 'Gravite']

Error: Confiant could not block Gravite Banner.

Unfortunately, Confiant doesn’t block the Gravite Banner very well. We are investigating with the Confiant team.

Error: AsyncStroage is null

add dependency in the package.json file

"dependencies": { "@react-native-async-storage/async-storage": "^1.23.1", },

After adding the dependency, add the following lines in the podfile.

# AsyncStorage - manually added for monorepo setup pod 'RNCAsyncStorage', :path => '../../node_modules/@react-native-async-storage/async-storage'

 

My application crashes on start

The Google Mobile Ads SDK may be initialized without an application ID.

Ad Manager

iOS: Update your Info.plist.
Android: Get Started

AdMob

iOS: Update your Info.plist.
Android: Get Started

Package.json

{ "name": "react-native-yieldlove", "title": "React Native Yieldlove", "version": "4.1.0", "description": "Yieldlove SDK bridge for React Native", "main": "lib/commonjs/index.js", "module": "lib/module/index.js", "types": "lib/typescript/src/index.d.ts", "react-native": "src/index", "source": "src/index", "sideEffects": false, "files": [ "src", "lib", "android", "ios", "cpp", "*.podspec", "!ios/build", "!android/build", "!android/gradle", "!android/gradlew", "!android/gradlew.bat", "!android/local.properties", "!**/__tests__", "!**/__fixtures__", "!**/__mocks__", "!**/.*" ], "exports": { ".": { "types": "./lib/typescript/src/index.d.ts", "react-native": "./src/index.js", "import": "./lib/module/index.js", "require": "./lib/commonjs/index.js", "default": "./lib/module/index.js" }, "react-native": "./src/index.js" }, "scripts": { "example": "yarn workspace react-native-yieldlove-example", "test": "jest", "typecheck": "tsc --noEmit", "lint": "eslint \"**/*.{js,ts,tsx}\"", "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib", "prepare": "bob build", "release": "release-it" }, "keywords": [ "react", "react-native", "react native", "yieldlove", "ads integration", "mobile ads", "ads" ], "repository": "https://github.com/mbrtargeting/stroeerSDK-react-native", "author": "Stroeer Media Lab <stroeerlabs@adscale.co.nz>", "license": "MIT", "bugs": { "url": "https://github.com/mbrtargeting/stroeerSDK-react-native/issues" }, "homepage": "https://github.com/mbrtargeting/stroeerSDK-react-native#readme", "publishConfig": { "registry": "https://registry.npmjs.org/" }, "devDependencies": { "@babel/core": "^7.28.5", "@commitlint/config-conventional": "^17.0.2", "@evilmartians/lefthook": "^1.5.0", "@react-native-community/cli": "15.0.0", "@react-native/eslint-config": "^0.80.0", "@types/jest": "^28.1.2", "@types/react": "19.1.0", "commitlint": "^17.0.2", "del-cli": "^5.0.0", "eslint": "^8.4.1", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.0.0", "jest": "^28.1.1", "pod-install": "^0.1.0", "prettier": "^2.0.5", "react": "19.1.0", "react-native": "0.80.2", "react-native-builder-bob": "^0.20.0", "release-it": "^19.0.6", "turbo": "^1.10.7", "typescript": "^5.1.6" }, "resolutions": { "@types/react": "19.1.0" }, "peerDependencies": { "react": ">=19.1.0", "react-native": ">=0.80.2" }, "workspaces": [ "example" ], "packageManager": "yarn@4.6.0", "engines": { "node": ">=20.0.0" }, "jest": { "preset": "react-native", "modulePathIgnorePatterns": [ "<rootDir>/example/node_modules", "<rootDir>/lib/", "<rootDir>/Legacy/", "<rootDir>/example/ios/Pods/", "<rootDir>/example/android/" ], "testPathIgnorePatterns": [ "/node_modules/", "/lib/", "/Legacy/", "/example/ios/", "/example/android/", "\\.d\\.ts$" ] }, "commitlint": { "extends": [] }, "release-it": { "git": { "commitMessage": "chore: release ${version}", "tagName": "v${version}" }, "npm": { "publish": true }, "github": { "release": false } }, "eslintConfig": { "root": true, "extends": [ "@react-native" ], "rules": { "prettier/prettier": "off", "@typescript-eslint/no-unused-vars": "off", "react-hooks/exhaustive-deps": "off" } }, "eslintIgnore": [ "node_modules/", "lib/", "Legacy/", "**/build/", "**/android/**", "**/ios/**", "*.js", "babel.config.js", "metro.config.js", "jest.config.js" ], "prettier": { "quoteProps": "consistent", "singleQuote": true, "tabWidth": 2, "trailingComma": "es5", "useTabs": false }, "react-native-builder-bob": { "source": "src", "output": "lib", "targets": [ "commonjs", "module", [ "typescript", { "project": "tsconfig.build.json" } ] ] } }