-jio-start-block-type-2
-jio-style-title
Follow below steps for integrating Jio Ads SDK for React Native Apps
Complete GETTING STARTED section and INITIALIZE SDK section before starting this section.
-jio-style-title
-jio-style-title
Node & Watchman
We recommend installing Node
and Watchman
using Homebrew.
Run the following commands in a Terminal after installing Homebrew:
brew install node
brew install watchman
1. If you have already installed Node on your system, make sure it is Node 18 or newer.
2. For more Info follow below link:
https://reactnative.dev/docs/environment-setupFollow the above link for setting up the Node JS and all the required setup for running the React native iOS Application
-jio-style-title
-jio-style-title
Before proceeding, ensure that you have the latest version of the JioAds SDK for iOS.
The minimum requirements for JioAds SDK for iOS are Xcode 12.0 and iOS version 10.0.
-jio-style-title
Extract all the files from the SDK archive into a separate folder. Currently the JioAds do not support Bitcode So if you are using Xcode 12 or higher then in Build Settings set “Enable Bitcode” setting to NO.
-jio-style-title
1. Open the .xcworkspace from the ios folder inside the react native app folder.
2. Import the latest JioAds Framework inside the ios app.
3. Embed the Framework inside the app target frameworks.
-jio-style-title
app.js
Open the app.js
file then add below code:
import React, { Component } from 'react';
//import { requestIDFAPermission } from './trackingPermissionService';
import {
StyleSheet,
View,
requireNativeComponent,
Text,
TouchableOpacity,
TextInput,
ScrollView,
FlatList,
Animated,
Keyboard,
} from 'react-native';
import { NativeModules } from 'react-native';
//const { JioAdHandler } = NativeModules;
const JioAdHandler = requireNativeComponent('JioAdHandler');
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
adspotKey: 'h7d5wxyo',
showAd: false,
adType: 1,
environment: 'PROD',
eventType: '', // Clubbable bydefault need then add eventType: 'Clubbable',
activeFrame: '', // Track which frame is active
clubbableItems: ['Deep-Link launch event', 'Cart view event', 'Page view event',
'Product list view event', 'Product search view event', 'Product view event',
'Custom data event', 'User details event', 'Location event'],
nonClubbableItems: ['Add to cart', 'Remove from cart', 'Add to Wishlist',
'Remove from Wishlist', 'Purchase completed', 'Purchase cancelled event',
'Purchase return event', 'App Launch'],
editableText: '',
selectedItem: '',
setPackageTFKey: 'com.ril.ajiofnl',
keyboardHeight: new Animated.Value(0),
isRetargetingExpanded: false,
editableTextJson: '',
setproductIdTFKey: 'ID122',
setLevelTFKey: '4',
setClickIdTFKey: '77363_63207_250954_308291_1_0uw7e9juk',
setRevenueTFKey: '5',
setCurrencyTFKey: 'INR',
setProdRevenueTFKey: '5',
setProdCountTFKey: '1',
setPriceTFKey: '2',
setProdIdTFKey: 'ID122',
isRetargetingTrackersExpanded: false,
};
}
/* Keyboard hide/show*/
componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
(event) => {
Animated.timing(this.state.keyboardHeight, {
toValue: event.endCoordinates.height,
duration: 300,
useNativeDriver: false,
}).start();
}
);
this.keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() => {
Animated.timing(this.state.keyboardHeight, {
toValue: 0,
duration: 300,
useNativeDriver: false,
}).start();
}
);
}
componentWillUnmount() {
this.keyboardDidHideListener.remove();
this.keyboardDidShowListener.remove();
}
/* Jioads CacheAD*/
handleCacheAD = () => {
const { adspotKey } = this.state;
if (!adspotKey.trim()) {
console.log("AdspotKey is empty. Cannot load ad.");
return;
}
console.log("Requesting with adspotKey:", adspotKey);
this.setState({ showAd: true });
};
handleInvalidateAd = () => {
// Clear adspotKey and show ad
this.setState({ adType: 9, showAd: false, adspotKey: '' });
};
handleJioAds = () => {
this.setState({ activeFrame: 'jioads' });
console.log("Requesting JioAds:");
// Add your JioAds request handling logic here
};
handleRetargeting = () => {
this.setState({ activeFrame: 'retargeting' });
console.log("Requesting Retargeting:");
};
/* Retargeting fetch*/
handleFetch = () => {
const { setPackageTFKey } = this.state;
if (!setPackageTFKey.trim()) {
console.log("setPackageTFKey is empty. Cannot load ad.");
return;
}
console.log("Requesting with setPackageTFKey:", setPackageTFKey);
const { JioAdHandler } = NativeModules;
if (JioAdHandler && JioAdHandler.fetchPackage) {
JioAdHandler.fetchPackage(setPackageTFKey);
} else {
console.error('JioAdHandler.fetchPackage is not defined');
}
};
/* Retargeting Environment set*/
handleEnvironmentChange = (env) => {
console.log(`Environment changed to: ${env}`);
this.setState({
environment: env,
showAd: false,
adspotKey: '',
});
const { JioAdHandler } = NativeModules;
if (JioAdHandler && JioAdHandler.setEnvironment) {
JioAdHandler.setEnvironment(env);
} else {
console.error('JioAdHandler.fetchPackage is not defined');
}
};
/* Retargeting fire events item clicked*/
handleItemClick = (item) => {
this.setState({ selectedItem: item });
if (item === 'App Launch') {
const jsonDetails = {
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Add to cart') {
const jsonDetails = {
"productDetails": {
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID122",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "21"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Remove from cart') {
const jsonDetails = {
"productDetails": {
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID122",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Add to Wishlist') {
const jsonDetails = {
"productDetails": {
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID1234",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
},
{
"quantity": 10,
"id": "ID1234",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Remove from Wishlist') {
const jsonDetails = {
"productDetails": {
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID1234",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
},
{
"quantity": 10,
"id": "ID1235",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Purchase completed') {
const jsonDetails = {
"clickId": "123451234",
"transactionId": "121124343",
"productDetails": {
"currency": "INR",
"productList": [
{
"segment": "Boys",
"quantity": 10,
"id": "ID122",
"vertical": "Fashion jwellery",
"price": 10,
"sku": "1",
"brickname": "Traditional jwellery"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Purchase Cancelled event') {
const jsonDetails = {
"clickId": "123451234",
"transactionId": "121124343",
"productDetails": {
"currency": "INR",
"productList": [
{
"segment": "Boys",
"quantity": 10,
"id": "ID122",
"vertical": "Fashion jwellery",
"price": 10,
"sku": "1",
"brickname": "Traditional jwellery"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Purchase return event') {
const jsonDetails = {
"clickId": "123451234",
"transactionId": "121124343",
"productDetails": {
"currency": "INR",
"productList": [
{
"segment": "Boys",
"quantity": 10,
"id": "ID1234",
"vertical": "Fashion jwellery",
"price": 10,
"sku": "1",
"brickname": "Traditional jwellery"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Deep-Link launch event') {
const jsonDetails = {
"deeplinkUri": "https://www.ajio.com/teamspirit-track-pants-with-contrast-taping/p/441031716_ltblue/?cid=2583_9582_3468_3453_0_54deeaaec5_gth56fgr&utm_source=jioads&utm_medium=prism&utm_campaign=western_wear&utm_id=ID1234",
"referrerApp": "chrome"
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Cart view event') {
const jsonDetails = {
"startTime": "2019-04-17T13:13:09+0000",
"endTime": "2019-04-17T13:14:09+0000",
"productDetails": {
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID1234",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "1232132"
},
{
"quantity": 10,
"id": "ID1235",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "1232133"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Page view event') {
const jsonDetails = {
"pageName": "Productpage",
"endTime": "2018-01-17T13:00:13+0000",
"startTime": "2018-01-17T13:00:13+0000"
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Product list view event') {
const jsonDetails = {
"productDetails": {
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID1234",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
}
],
"listName": "Diwali sale"
},
"startTime": "2018-01-17T13:00:13+0000",
"endTime": "2018-01-17T13:00:13+0000"
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Product search view event') {
const jsonDetails = {
"searchDetails": {
"filters": [
{
"name": "size",
"value": [
"28",
"36"
]
}
],
"searchString": "Jeans for men",
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID1234",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Product view event') {
const jsonDetails = {
"startTime": "2018-01-17T13:00:13+0000",
"endTime": "2018-01-17T13:00:13+0000",
"productDetails": {
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID1234",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
}
]
}
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Custom data event') {
const jsonDetails = {
"customData": [{ "key": "value" }, { "key": "value" }]
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'User details event') {
const jsonDetails = {
"customerDetails": [
{
"type": 0,
"idValue": "abc@example.com"
}
]
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else if (item === 'Location event') {
const jsonDetails = {
"productDetails": {
"currency": "INR",
"productList": [
{
"quantity": 10,
"id": "ID1234",
"segment": "Boys",
"vertical": "Fashion jwellery",
"price": 10,
"brickname": "Traditional jwellery",
"sku": "32"
}
]
},
"longitude": "",
"pincode": "560000",
"latitude": "",
};
this.setState({ editableText: JSON.stringify(jsonDetails, null, 2) });
} else {
this.setState({ editableText: '' });
}
};
/* Retargeting fire events */
handleFireEvents = () => {
const { selectedItem, editableText } = this.state; // Destructure state values
const { JioAdHandler } = NativeModules;
this.setState({ activeFrame: 'retargeting' });
console.log(`Requesting handleFireEvents: selectedItem=${selectedItem}, editableText=${editableText}`);
if (JioAdHandler && JioAdHandler.fireEvent) {
JioAdHandler.fireEvent(selectedItem, editableText);
} else {
console.error('JioAdHandler.fireEvent is not defined');
}
};
/* handleRetargetingTrackers defaults values set*/
handleRetargetingTrackers = () => {
this.setState({ activeFrame: 'retargeting' });
const complexString = `{\"ad\":\"{\\\"imptrackers\\\":[\\\"https:\\/\\/mercury.akamaized-staging.net\\/cm\\/i-stg.gif?asi=59409&cb=fjs9gyk55k&dle=2&at=12&ob=8&cd=1&aud=-1&b=460416693_blue&c=402562&rl=1&li=&mi=&ro=&ag=&adg=93045&sbr=&rr=500.0000&rt=1&rc=1&rcs=1918844bbba067e7c05c78242dd0092a9d50c471&sm=1&vr=[vr]&os=[os]&a=77459&cn=&pn=&ct=&st=&ma=1&cid=77459_59409_402562_460416693_blue_1_fjs9gyk55k_[ccb]&trq=[trq]&bz=[bz]&ccb=[ccb]&[cmd]&pb=[pb]&lo=[lo]&dt=[dt]&la=[la]&br=[br]&sh=[sh]&s1i=[s1i]>s=[gts]&av=[av]&mn=[mn]&ifa=[ifa]&dai=[dai]&strm=[strm]&cc=[cc]&pr=[pr]&acc=[acc]&ip=[ip]&sw=[sw]&lc=[lc]&osv=[osv]&pa=[pa]&uid=[uid]&nc=[nc]\\\"],\\\"clktrackers\\\":[\\\"https:\\/\\/mercury-ck-stg.jio.com\\/delivery\\/ck.php?oaparams=2__asi=59409__cb=fjs9gyk55k__dle=2__at=12__ob=8__cd=1__aud=-1__b=460416693_blue__c=402562__rl=1__li=__mi=__ro=__ag=__adg=93045__sbr=__rr=500.0000__rt=1__rc=1__rcs=1918844bbba067e7c05c78242dd0092a9d50c471__sm=1__vr=[vr]__os=[os]__a=77459__cn=__pn=__ct=__st=__ma=1__cid=77459_59409_402562_460416693_blue_1_fjs9gyk55k_[ccb]__trq=[trq]__bz=[bz]__ccb=[ccb]__[cmd]__strm=[strm]__cc=[cc]__pr=[pr]__dai=[dai]__ip=[ip]__sw=[sw]__lc=[lc]__acc=[acc]__pa=[pa]__uid=[uid]__nc=[nc]__osv=[osv]__lo=[lo]__dt=[dt]__pb=[pb]__la=[la]__sh=[sh]__s1i=[s1i]__gts=[gts]__br=[br]__mn=[mn]__ifa=[ifa]__av=[av]__trackonly=1__oadest=\\\"],\\\"viewableimptrackers\\\":[\\\"https:\\/\\/mercury.akamaized-staging.net\\/cm\\/vi-stg.gif?asi=59409&cb=fjs9gyk55k&dle=2&at=12&ob=8&cd=1&aud=-1&b=460416693_blue&c=402562&rl=1&li=&mi=&ro=&ag=&adg=93045&sbr=&rr=500.0000&rt=1&rc=1&rcs=1918844bbba067e7c05c78242dd0092a9d50c471&sm=1&vr=[vr]&os=[os]&a=77459&cn=&pn=&ct=&st=&ma=1&cid=77459_59409_402562_460416693_blue_1_fjs9gyk55k_[ccb]&trq=[trq]&bz=[bz]&ccb=[ccb]&[cmd]&pb=[pb]&lo=[lo]&dt=[dt]&la=[la]&br=[br]&sh=[sh]&s1i=[s1i]>s=[gts]&av=[av]&mn=[mn]&ifa=[ifa]&dai=[dai]&strm=[strm]&cc=[cc]&pr=[pr]&acc=[acc]&ip=[ip]&sw=[sw]&lc=[lc]&osv=[osv]&pa=[pa]&uid=[uid]&nc=[nc]\\\"]}\\n\",\"config\":{\"cid\":\"77459_59409_402562_460416693_blue_1_fjs9gyk55k_[ccb]\",\"c\":\"402562\"}}`;
this.setState({ editableTextJson: complexString });
};
/* Retargeting Convertion Tracker */
handleImpTracker = () => {
const { editableTextJson } = this.state;
const { setproductIdTFKey } = this.state;
const { JioAdHandler } = NativeModules;
this.setState({ activeFrame: 'retargeting' });
if (JioAdHandler && JioAdHandler.fireImpTracker) {
JioAdHandler.fireImpTracker('impression', editableTextJson, setproductIdTFKey);
} else {
console.error('JioAdHandler.fireEvent is not defined');
}
};
handleViewableTracker = () => {
const { editableTextJson } = this.state;
const { setproductIdTFKey } = this.state;
const { JioAdHandler } = NativeModules;
this.setState({ activeFrame: 'retargeting' });
if (JioAdHandler && JioAdHandler.fireViewableTracker) {
JioAdHandler.fireViewableTracker('impression', editableTextJson, setproductIdTFKey);
} else {
console.error('JioAdHandler.fireViewableTracker is not defined');
}
};
handleClickTracker = () => {
const { editableTextJson } = this.state;
const { setproductIdTFKey } = this.state;
const { JioAdHandler } = NativeModules;
this.setState({ activeFrame: 'retargeting' });
if (JioAdHandler && JioAdHandler.fireClickTracker) {
JioAdHandler.fireClickTracker('impression', editableTextJson, setproductIdTFKey);
} else {
console.error('JioAdHandler.fireEvent is not defined');
}
};
/* Retargeting Fire Convertion Tracker */
handleConvertionTracker = () => {
const { setLevelTFKey } = this.state;
const { setClickIdTFKey } = this.state;
const { setRevenueTFKey } = this.state;
const { setCurrencyTFKey } = this.state;
const { setProdRevenueTFKey } = this.state;
const { setProdCountTFKey } = this.state;
const { setPriceTFKey } = this.state;
const { setProdIdTFKey } = this.state;
const { JioAdHandler } = NativeModules;
this.setState({ activeFrame: 'retargeting' });
if (JioAdHandler && JioAdHandler.fireCoversionTracker) {
JioAdHandler.fireCoversionTracker(setLevelTFKey, setClickIdTFKey, setRevenueTFKey, setCurrencyTFKey, setProdRevenueTFKey, setProdCountTFKey, setPriceTFKey, setProdIdTFKey);
} else {
console.error('JioAdHandler.handleConvertionTracker is not defined');
}
};
render() {
const { adspotKey, adType, showAd, environment, eventType, activeFrame, clubbableItems, nonClubbableItems, editableText, selectedItem, setPackageTFKey, keyboardHeight, editableTextJson, setproductIdTFKey, setLevelTFKey, setClickIdTFKey, setRevenueTFKey, setCurrencyTFKey, setProdRevenueTFKey, setProdCountTFKey, setPriceTFKey, setProdIdTFKey } = this.state;
return (
<ScrollView contentContainerStyle={styles.scrollContainer}>
<View style={styles.container}>
<Text style={styles.frameAboveTitle}>React Native Sample App</Text>
{/* JioAds Button */}
<TouchableOpacity style={styles.mainButton} onPress={this.handleJioAds}>
<Text style={styles.buttonText}>JioAds</Text>
</TouchableOpacity>
{/* Retargeting Button */}
<TouchableOpacity style={styles.mainButton} onPress={this.handleRetargeting}>
<Text style={styles.buttonText}>Retargeting</Text>
</TouchableOpacity>
{/* Conditionally Render JioAds Frame */}
{activeFrame === 'jioads' && (
<View style={styles.frame}>
<Text style={styles.frameTitle}>Select Adtype</Text>
<View style={styles.radioContainer}>
{[1, 2, 3, 4, 5].map(type => (
<TouchableOpacity
key={type}
style={[styles.radio, adType === type && styles.selectedRadio]}
onPress={() => this.setState({ adType: type, showAd: false, adspotKey: '' })}
>
<Text style={[styles.radioText, adType === type ? styles.selectedText : null]}>
{['Dynamic Display', 'Instream', 'Interstitial', 'NativeContentStream', 'CustomNative'][type - 1]}
</Text>
</TouchableOpacity>
))}
</View>
{/* Adspot ID Input and Cache AD Button */}
<View style={styles.content}>
<View style={styles.rowContainer}>
<View style={styles.textInputContainer}>
<TextInput
style={styles.textInput}
placeholder="Enter AdspotId"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={adspotKey}
onChangeText={(text) => this.setState({ adspotKey: text, showAd: false })}
/>
</View>
<TouchableOpacity style={styles.button} onPress={this.handleCacheAD}>
<Text style={styles.buttonText}>CacheAD</Text>
</TouchableOpacity>
</View>
{/* Native Ad Display */}
{showAd && (
<View style={styles.nativeViewContainer}>
{/* Native Ad */}
<JioAdHandler
style={styles.nativeView}
data={{
adType: adType,
adspotKey: adspotKey,
adHeight: 250,
adWidth: 300,
}}
/>
{/* Invalidate Ad Button */}
<TouchableOpacity style={styles.invalidateButton} onPress={this.handleInvalidateAd}>
<Text style={styles.buttonText}>Invalidate Ad</Text>
</TouchableOpacity>
</View>
)}
</View>
</View>
)}
{/* Conditionally Render Retargeting Frame */}
{activeFrame === 'retargeting' && (
<View style={styles.frame}>
<View style={styles.rowContainer}>
<View style={styles.textInputContainer}>
<TextInput
style={styles.textInput}
placeholder="Set PackageName"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setPackageTFKey}
onChangeText={(text) => this.setState({ setPackageTFKey: text, showAd: false })}
/>
</View>
<TouchableOpacity style={styles.button} onPress={this.handleFetch}>
<Text style={styles.buttonText}>Fetch</Text>
</TouchableOpacity>
</View>
<Text style={styles.frameTitle}>Select Environment</Text>
<View style={styles.radioContainer}>
{['SIT', 'STG', 'PROD'].map((env) => (
<TouchableOpacity
key={env}
style={[styles.radio, environment === env && styles.selectedRadio]}
onPress={() => this.handleEnvironmentChange(env)}
>
<Text style={[styles.radioText, environment === env ? styles.selectedText : null]}>{env}</Text>
</TouchableOpacity>
))}
</View>
<Text style={styles.frameTitle}>Select Event Type</Text>
<View style={styles.radioContainer}>
{['Clubbable', 'Non-Clubbable'].map(type => (
<TouchableOpacity
key={type}
style={[styles.radioClub, eventType === type && styles.selectedRadio]}
onPress={() => this.setState({ eventType: type, editableText: '' })}
>
<Text style={[styles.radioText, eventType === type ? styles.selectedText : null]}>{type}</Text>
</TouchableOpacity>
))}
</View>
{/* Conditionally Render Clubbable Items */}
{eventType === 'Clubbable' && (
<View style={styles.listContainer}>
{/* Clubbable Items List */}
<FlatList
data={clubbableItems}
keyExtractor={(_item, index) => index.toString()}
renderItem={({ item }) => (
<TouchableOpacity
style={[styles.listItem, selectedItem === item && styles.selectedItem]}
onPress={() => this.handleItemClick(item)}
>
<Text style={styles.listText}>{item}</Text>
</TouchableOpacity>
)}
/>
</View>
)}
{/* Conditionally Render Clubbable Items */}
{eventType === 'Non-Clubbable' && (
<View style={styles.listContainer}>
{/* Non Clubbable Items List */}
<FlatList
data={nonClubbableItems}
keyExtractor={(_item, index) => index.toString()}
renderItem={({ item }) => (
<TouchableOpacity
style={[styles.listItem, selectedItem === item && styles.selectedItem]}
onPress={() => this.handleItemClick(item)}
>
<Text style={styles.listText}>{item}</Text>
</TouchableOpacity>
)}
/>
</View>
)}
{/* Conditionally Render Editable TextInput */}
{editableText !== '' && (
<View style={styles.editableFrame}>
<Text style={styles.frameTitle}>Editable Text (Sample JSON)</Text>
<TextInput
style={styles.editableTextInput}
value={editableText}
onChangeText={(text) => this.setState({ editableText: text })}
multiline={true}
/>
<TouchableOpacity style={styles.retargetingButton} onPress={this.handleFireEvents}>
<Text style={styles.buttonText}>Fire event</Text>
</TouchableOpacity>
</View>
)}
{/* Retargeting Trackers Button */}
<TouchableOpacity
style={styles.retargetingButton}
onPress={() => {
// Toggle visibility of the retargeting section
this.setState(
(prevState) => ({
isRetargetingExpanded: !prevState.isRetargetingExpanded,
}),
() => {
// Call handleRetargetingTrackers if section is expanded
if (this.state.isRetargetingExpanded) {
this.handleRetargetingTrackers();
}
}
);
}}
>
<Text style={styles.buttonText}>Retargeting Trackers</Text>
</TouchableOpacity>
{/* Conditionally Render the Expandable Content */}
{this.state.isRetargetingExpanded && (
<View style={styles.editableFrame}>
{/* Display TextView */}
<Text style={styles.textView}>
Retargeting Trackers Activated. Please choose an action below:
</Text>
{/* Editable TextInput */}
<TextInput
style={styles.editableTextInput}
value={this.state.editableTextJson}
onChangeText={(text) => this.setState({ editableTextJson: text })}
multiline={true}
/>
<View style={styles.textInputContainer}>
<TextInput
style={styles.textInput}
placeholder="product id"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setproductIdTFKey}
onChangeText={(text) => this.setState({ setproductIdTFKey: text, showAd: false })}
/>
</View>
{/* Impression */}
<TouchableOpacity
style={styles.retargetingButton}
onPress={() => {
this.handleImpTracker();
this.setState({ isRetargetingExpanded: true });
}}
>
<Text style={styles.buttonText}>Impression tracker</Text>
</TouchableOpacity>
{/* Viewable */}
<TouchableOpacity
style={styles.retargetingButton}
onPress={() => {
this.handleViewableTracker();
this.setState({ isRetargetingExpanded: true });
}}
>
<Text style={styles.buttonText}>Viewable tracker</Text>
</TouchableOpacity>
{/* Click */}
<TouchableOpacity
style={styles.retargetingButton}
onPress={() => {
this.handleClickTracker();
this.setState({ isRetargetingExpanded: true });
}}
>
<Text style={styles.buttonText}>Click tracker</Text>
</TouchableOpacity>
</View>
)}
{/* Fire Conversion Trackers */}
<TouchableOpacity
style={styles.retargetingButton}
onPress={() => {
// Toggle visibility of the retargeting section
this.setState(
(prevState) => ({
isRetargetingTrackersExpanded: !prevState.isRetargetingTrackersExpanded,
}),
() => {
// Call handleRetargetingTrackers if section is expanded
if (this.state.isRetargetingTrackersExpanded) {
this.handleRetargetingTrackers();
}
}
);
}}
>
<Text style={styles.buttonText}>Fire Conversion Tracker</Text>
</TouchableOpacity>
{this.state.isRetargetingTrackersExpanded && (
<View style={styles.editableFrame}>
{/* Display TextView */}
<Text style={styles.textView}>
Fire Conversion Tracker
</Text>
<View style={styles.textInputTrackerContainer}>
<TextInput
style={styles.textInput}
placeholder="Level"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setLevelTFKey}
onChangeText={(text) => this.setState({ setLevelTFKey: text, showAd: false })}
/>
</View>
<View style={styles.textInputTrackerContainer}>
<TextInput
style={styles.textInput}
placeholder="Click id"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setClickIdTFKey}
onChangeText={(text) => this.setState({ setClickIdTFKey: text, showAd: false })}
/>
</View>
<View style={styles.textInputTrackerContainer}>
<TextInput
style={styles.textInput}
placeholder="Revenue"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setRevenueTFKey}
onChangeText={(text) => this.setState({ setRevenueTFKey: text, showAd: false })}
/>
</View>
<View style={styles.textInputTrackerContainer}>
<TextInput
style={styles.textInput}
placeholder="Currency"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setCurrencyTFKey}
onChangeText={(text) => this.setState({ setCurrencyTFKey: text, showAd: false })}
/>
</View>
<View style={styles.textInputTrackerContainer}>
<TextInput
style={styles.textInput}
placeholder="Product revenue"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setProdRevenueTFKey}
onChangeText={(text) => this.setState({ setProdRevenueTFKey: text, showAd: false })}
/>
</View>
<View style={styles.textInputTrackerContainer}>
<TextInput
style={styles.textInput}
placeholder="Product count"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setProdCountTFKey}
onChangeText={(text) => this.setState({ setProdCountTFKey: text, showAd: false })}
/>
</View>
<View style={styles.textInputTrackerContainer}>
<TextInput
style={styles.textInput}
placeholder="Price"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setPriceTFKey}
onChangeText={(text) => this.setState({ setPriceTFKey: text, showAd: false })}
/>
</View>
<View style={styles.textInputTrackerContainer}>
<TextInput
style={styles.textInput}
placeholder="Product id"
placeholderTextColor="gray"
underlineColorAndroid="transparent"
value={setProdIdTFKey}
onChangeText={(text) => this.setState({ setProdIdTFKey: text, showAd: false })}
/>
</View>
{/* Button 1 */}
<TouchableOpacity
style={styles.retargetingButton}
onPress={() => {
this.handleConvertionTracker();
this.setState({ isRetargetingTrackersExpanded: true });
}}
>
<Text style={styles.buttonText}>Fire now</Text>
</TouchableOpacity>
</View>
)}
</View>
)}
</View>
<Animated.View
style={[styles.footer, { paddingBottom: keyboardHeight }]}>
<Text style={styles.footerText}>Footer Content</Text>
</Animated.View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
alignItems: 'center',
paddingTop: 100,
},
frame: {
borderWidth: 1,
borderColor: 'black',
borderRadius: 5,
paddingHorizontal: 5,
width: '90%',
marginVertical: 10,
padding: 20,
},
frameTitle: {
fontSize: 13,
marginBottom: 5,
},
frameAboveTitle: {
fontSize: 20,
marginBottom: 5,
},
content: {
paddingHorizontal: 5,
},
rowContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: 10,
},
button: {
backgroundColor: '#157DEC',
paddingVertical: 10,
paddingHorizontal: 20,
borderRadius: 5,
width: '48%',
},
buttonText: {
color: 'white',
fontSize: 16,
textAlign: 'center',
},
textInputContainer: {
borderWidth: 1,
borderColor: 'gray',
borderRadius: 5,
width: '48%',
},
textInput: {
height: 40,
paddingHorizontal: 10,
color: 'black',
width: '100%',
},
radioContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
marginBottom: 10,
},
radio: {
backgroundColor: 'lightgray',
paddingVertical: 10,
paddingHorizontal: 5,
borderRadius: 5,
width: '30%',
alignItems: 'center',
marginVertical: 5,
},
selectedRadio: {
backgroundColor: '#157DEC',
},
radioText: {
color: 'black',
fontSize: 8,
textAlign: 'center',
},
selectedText: {
color: 'white',
},
radioClub: {
backgroundColor: 'lightgray',
paddingVertical: 10,
paddingHorizontal: 5,
borderRadius: 5,
width: '48%',
marginVertical: 5,
},
listContainer: {
marginTop: 10,
},
listItem: {
backgroundColor: 'lightgray',
paddingVertical: 10,
paddingHorizontal: 15,
borderRadius: 5,
marginVertical: 5,
width: '100%',
},
listText: {
fontSize: 12,
color: 'black',
},
retargetingButton: {
backgroundColor: '#157DEC',
paddingVertical: 10,
paddingHorizontal: 20,
borderRadius: 5,
marginTop: 10,
width: '90%',
alignSelf: 'center',
},
mainButton: {
backgroundColor: '#157DEC',
paddingVertical: 10,
paddingHorizontal: 20,
borderRadius: 5,
marginTop: 20,
width: '95%',
alignSelf: 'center',
},
scrollContainer: {
flexGrow: 1,
padding: 10,
backgroundColor: 'white',
},
nativeViewContainer: {
alignItems: 'center',
justifyContent: 'center',
marginTop: 10,
width: '100%',
paddingHorizontal: 10,
},
nativeView: {
width: '100%',
height: 250,
borderRadius: 5,
},
invalidateButton: {
backgroundColor: '#FF5733',
paddingVertical: 10,
paddingHorizontal: 20,
borderRadius: 5,
marginTop: 15,
},
buttonText: {
color: 'white',
fontSize: 16,
textAlign: 'center',
},
selectedItem: {
backgroundColor: 'dodgerblue',
},
editableTextInput: {
height: 250,
paddingHorizontal: 10,
color: 'black',
width: '100%',
marginBottom: 2,
textAlignVertical: 'top',
},
editableFrameTitle: {
fontSize: 8
},
editableFrame: {
borderWidth: 1,
borderColor: 'black',
borderRadius: 5,
paddingHorizontal: 5,
width: '100%',
marginVertical: 10,
padding: 20,
alignItems: 'center',
},
footer: {
padding: 300,
backgroundColor: 'white',
justifyContent: 'flex-end',
},
footerText: {
color: 'white',
textAlign: 'center',
},
header: {
backgroundColor: '#333',
padding: 15,
alignItems: 'center',
justifyContent: 'center',
},
headerText: {
color: 'white',
fontSize: 24,
fontWeight: 'bold',
},
textInputTrackerContainer: {
borderWidth: 1,
borderColor: 'gray',
borderRadius: 5,
width: '90%',
marginBottom: 5,
},
textView: {
marginBottom: 15,
},
editableFrame: {
borderWidth: 1,
borderColor: 'black',
borderRadius: 5,
paddingHorizontal: 5,
width: '100%',
marginVertical: 10,
padding: 20,
alignItems: 'center',
}
});
-jio-style-title
-jio-style-title
Create a swift wrapper class in native xcode project for the ad formats
For Your Reference, follow the below wrapper.
import UIKit
import JioAdsFramework
enum AdType: Int {
case dynamicDisplay = 1
case instreamVideo = 2
case interstitial = 3
case nativeContentStream = 4
case customNative = 5
}
class DisplayAdView: UIView, JIOAdViewProtocol {
@objc var displayadView: JioAdView?
@objc var instreamadView: JioAdView?
@objc var interstitaladView: JioAdView?
@objc var nativeContenadView: JioAdView?
@objc var customNativeadView: JioAdView?
var adType: AdType = .dynamicDisplay
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func setData(_ val: NSDictionary) {
print("============ set data =========", val)
if let adspotKey = val["adspotKey"] as? String,
let adHeight = val["adHeight"] as? Int,
let adWidth = val["adWidth"] as? Int,
let adTypeVal = val["adType"] as? Int {
setupAdView(adType: adTypeVal, adspotKey: adspotKey, adHeight: adHeight, adWidth: adWidth)
}
}
private func setupAdView(adType: Int, adspotKey: String, adHeight: Int, adWidth: Int) {
var container = UIView()
switch adType {
case 1:
self.adType = .dynamicDisplay
container = setupDisplayAdView(adspotKey: adspotKey, adHeight: adHeight, adWidth: adWidth) // h7d5wxyo //h9tw7nj0
case 2:
self.adType = .instreamVideo
container = setupInstreamAdView(adspotKey: adspotKey, adHeight: adHeight, adWidth: adWidth) // hlmq9pn2
case 3:
self.adType = .interstitial
container = setupInterstitialAdView(adspotKey: adspotKey, adHeight: adHeight, adWidth: adWidth) // hlmq9pn2
case 4:
self.adType = .nativeContentStream
container = setupNativeContentStreamAdView(adspotKey: adspotKey, adHeight: adHeight, adWidth: adWidth) // hlmq9pn2
case 5:
self.adType = .customNative
container = setupCustomNativeAdView(adspotKey: adspotKey, adHeight: adHeight, adWidth: adWidth) // hlmq9pn2
case 9:
DispatchQueue.main.async {
self.displayadView?.invalidateAd()
self.instreamadView?.invalidateAd()
self.interstitaladView?.invalidateAd()
self.nativeContenadView?.invalidateAd()
self.customNativeadView?.invalidateAd()
container = UIView(frame: CGRect(x: 0, y: 0, width: adWidth, height: adHeight))
}
default:
self.adType = .instreamVideo
container = setupInstreamAdView(adspotKey: adspotKey, adHeight: adHeight, adWidth: adWidth) // hlmq9pn2
}
addSubview(container)
}
private func setupDisplayAdView(adspotKey: String, adHeight: Int, adWidth: Int) -> UIView {
let container = UIView(frame: CGRect(x: 0, y: 0, width: adWidth, height: adHeight))
JioAdSdk.setLogLevel(logLevel: .debug)
//JioAdSdk.setPackageName(packageName: "com.jio.callkittest")
setValueInUserDefaults(objValue: "Production", for: "currentEnvironment")
displayadView = JioAdView(adSpotId: adspotKey, adType: .dynamicDisplay, delegate: self, forPresentionClass: UIViewController(), publisherContainer: container)
displayadView?.setDisplayAdSize(displaySizes: [.size300x250])
displayadView?.translatesAutoresizingMaskIntoConstraints = false
displayadView?.setCustomView(container: container)
displayadView?.cacheAd()
return container
}
private func setupInstreamAdView(adspotKey: String, adHeight: Int, adWidth: Int) -> UIView {
let container = UIView(frame: CGRect(x: 0, y: 0, width: adWidth, height: adHeight))
JioAdSdk.setLogLevel(logLevel: .debug)
setValueInUserDefaults(objValue: "Production", for: "currentEnvironment")
instreamadView = JioAdView(adSpotId: adspotKey, adType: .instreamVideo, delegate: self, forPresentionClass: UIViewController(), publisherContainer: container)
instreamadView?.translatesAutoresizingMaskIntoConstraints = false
instreamadView?.setCustomView(container: container)
instreamadView?.cacheAd()
return container
}
private func setupInterstitialAdView(adspotKey: String, adHeight: Int, adWidth: Int) -> UIView {
let container = UIView(frame: CGRect(x: 0, y: 0, width: adWidth, height: adHeight))
JioAdSdk.setLogLevel(logLevel: .debug)
setValueInUserDefaults(objValue: "Production", for: "currentEnvironment")
interstitaladView = JioAdView(adSpotId: adspotKey, adType: .interstitial, delegate: self, forPresentionClass: UIViewController(), publisherContainer: container)
interstitaladView?.translatesAutoresizingMaskIntoConstraints = false
interstitaladView?.setCustomView(container: container)
interstitaladView?.cacheAd()
return container
}
private func setupCustomNativeAdView(adspotKey: String, adHeight: Int, adWidth: Int) -> UIView {
let container = CustomNativeContentStremView(frame: CGRect(x: 0, y: 0, width: 300, height: 250))
JioAdSdk.setLogLevel(logLevel: .debug)
JioAdSdk.setPackageName(packageName: "com.jio.callkittest")
setValueInUserDefaults(objValue: "Production", for: "currentEnvironment")
customNativeadView = JioAdView(adSpotId: adspotKey, adType: .customNative, delegate: self, forPresentionClass: UIViewController(), publisherContainer: container)
customNativeadView?.translatesAutoresizingMaskIntoConstraints = false
customNativeadView?.setCustomView(container: container)
customNativeadView?.setCustomImageSize(width: 300, height: 250)
customNativeadView?.cacheAd()
return container
}
private func setupNativeContentStreamAdView(adspotKey: String, adHeight: Int, adWidth: Int) -> UIView {
let container = CustomNativeContentStremView(frame: CGRect(x: 0, y: 0, width: 300, height: 250))
JioAdSdk.setLogLevel(logLevel: .debug)
JioAdSdk.setPackageName(packageName: "com.jio.callkittest")
setValueInUserDefaults(objValue: "Production", for: "currentEnvironment")
nativeContenadView = JioAdView(adSpotId: adspotKey, adType: .nativeContentStream, delegate: self, forPresentionClass: UIViewController(), publisherContainer: container)
nativeContenadView?.translatesAutoresizingMaskIntoConstraints = false
nativeContenadView?.setCustomView(container: container)
nativeContenadView?.cacheAd()
return container
}
func setValueInUserDefaults(objValue: String, for key: String) {
let userDefaults = UserDefaults.standard
userDefaults.set(objValue, forKey: key)
userDefaults.synchronize()
}
// Implement JIOAdViewProtocol methods
func onAdReceived(adView: JioAdView) {
print("onAdReceived")
}
func onAdPrepared(adView: JioAdView) {
print( "onAdPrepared")
if adView == instreamadView {
self.instreamadView?.loadAd()
} else if adView == customNativeadView {
self.customNativeadView?.loadAd()
} else if adView == displayadView {
self.displayadView?.loadAd()
} else if adView == interstitaladView {
self.interstitaladView?.loadAd()
} else if adView == nativeContenadView {
self.nativeContenadView?.loadAd()
}
}
func onAdRender(adView: JioAdView) {
print("onAdRender")
}
func onAdClicked(adView: JioAdView) {
print("onAdClicked")
}
func onAdRefresh(adView: JioAdView) {
print("onAdRefresh")
}
func onAdFailedToLoad(adView: JioAdView, error: JioAdError) {
print("onAdFailedToLoad")
}
func onAdMediaEnd(adView: JioAdView) {
}
func onAdClosed(adView: JioAdView, isVideoCompleted: Bool, isEligibleForReward: Bool) {
}
func onAdMediaStart(adView: JioAdView) {
print("onAdMediaStart")
}
func onAdSkippable(adView: JioAdView) {
}
func onAdMediaExpand(adView: JioAdView) {
}
func onAdMediaCollapse(adView: JioAdView) {
}
func onMediaPlaybackChange(adView: JioAdView, mediaPlayBack: MediaPlayBack) {
}
func onAdDataPrepared(videoAd: VideoAd?, isLastAd: Bool) {
}
func onAdDataPrepared(nativeAd: NativeAd?, isLastAd: Bool) {
}
func onAdChange(adView: JioAdView, trackNo: Int) {
}
func mediationRequesting() {
}
func mediationLoadAd() {
}
}
-jio-style-title
Create a Bridging header file for connecting swift code into objc code and from objc to React.
//Import the below files in the bridging header file
#import "React/RCTBridgeModule.h"
#import "React/RCTViewManager.h"
#import "React/RCTEventEmitter.h"
-jio-style-title
Create a jioHandler .swift class and also create objective c class for the same name for managing the view and it will return the specific adView from the override func view() -> UIView! {} method. RCTViewManager will send the adView to the React.
Find the below swift code snippets for reference
import Foundation
import JioAdsFramework
import React
import AppTrackingTransparency
import AdSupport
@objc(JioAdHandler)
class JioAdHandler: RCTViewManager {
let TAG = "JioAdHandler"
override func view() -> UIView! {
print("\(TAG) | Native Method called from React! for JioAds")
return DisplayAdView()
}
override static func requiresMainQueueSetup() -> Bool {
return true
}
@objc func fetchPackage(_ packageName: String) {
print("\(TAG) | Retargetting | Native Method called from React! | fetchPackage: \(packageName)")
UserDefaults.standard.setValue(packageName, forKey: "parentPackage")
if let previousPackage = UserDefaults.standard.value(forKey: "parentPackage") as? String? {
JioAdSdk.setPackageName(packageName: previousPackage ?? "com.ril.ajiofnl")
}
JioAdSdk.setLogLevel(logLevel: .debug)
JioAdsFramework.RILEventManager.shared.initializeRetargettingSDK()
if #available(iOS 14, tvOS 14, *) {
requestAppTrackingPermission { (status) in
}
}
}
@objc func setEnvironment(_ env: String) {
guard let parentPackage = UserDefaults.standard.value(forKey: "parentPackage") as? String, !parentPackage.isEmpty else {
NSLog("Retargetting | set environment and try for setEnvironment setup!!")
return
}
print("\(TAG) | Retargetting | Native Method called from React! | setEnvironment:\(env)")
//if let newEnvName = UserDefaults.standard.value(forKey: "currentEnv") as? String? {
if env == "PROD" {
UserDefaults.standard.setValue("production", forKey: "currentEnv")
RILEventManager.shared.setEnvironment(environment: .production)
} else if env == "STG" {
UserDefaults.standard.setValue("staging", forKey: "currentEnv")
RILEventManager.shared.setEnvironment(environment: .staging)
} else {
//RILEventManager.shared.setEnvironment(environment: .sit)
UserDefaults.standard.setValue("SIT", forKey: "currentEnv")
RILEventManager.shared.setEnvironment(environment: .staging)
}
//}
}
//Events
@objc func fireEvent(_ eventType: String, json: String) {
print("\(TAG) | Retargetting | Native Method called from React! | fireEvent:: \(eventType) :: Json: \(json)")
guard let newEnvName = UserDefaults.standard.value(forKey: "currentEnv") as? String, ["production", "staging", "SIT"].contains(newEnvName) else {
NSLog("Retargetting | set environment and try for events !!")
// self.showToast(message: "Select environment")
return
}
var selectedEvent = ""
if (eventType == "App Launch") {
selectedEvent = "AppLaunch"
} else if (eventType == "Add to cart") {
selectedEvent = "AddToCart"
} else if (eventType == "Remove from cart") {
selectedEvent = "RemoveFromCart"
} else if (eventType == "Add to Wishlist") {
selectedEvent = "AddToWishlist"
} else if (eventType == "Remove from Wishlist") {
selectedEvent = "RemoveFromWishlist"
} else if (eventType == "Purchase completed") {
selectedEvent = "PurchaseCompleted"
} else if (eventType == "Purchase cancelled event") {
selectedEvent = "PurchaseCancelled"
} else if (eventType == "Purchase return event") {
selectedEvent = "PurchaseReturn"
} else if (eventType == "Deep-Link launch event") {
selectedEvent = "DeepLink"
} else if (eventType == "Cart view event") {
selectedEvent = "CartView"
} else if (eventType == "Page view event") {
selectedEvent = "PageView"
} else if (eventType == "Product list view event") {
selectedEvent = "ProductListView"
} else if (eventType == "Product search view event") {
selectedEvent = "ProductSearchView"
} else if (eventType == "Product view event") {
selectedEvent = "ProductView"
} else if (eventType == "Custom data event") {
selectedEvent = "CustomData"
} else if (eventType == "User details event") {
selectedEvent = "UserDetailsEvent"
} else if (eventType == "Location event") {
selectedEvent = "LocationEvent"
}
if let event = EventTypes(rawValue: selectedEvent) {
self.fireEvent(tagValue: event, updatedJsonString: json)
}
}
// Retargetting Imp Trackers
@objc func fireImpTracker(_ eventType: String, json: String, productId: String) {
guard let newEnvName = UserDefaults.standard.value(forKey: "currentEnv") as? String, ["production", "staging", "SIT"].contains(newEnvName) else {
NSLog("Retargetting | set environment and try for events !!")
// self.showToast(message: "Select environment")
return
}
print("\(TAG) | Retargetting | Native Method called from React! | fireEvent:: \(eventType) :: productId: \(productId) :: Json: \(json)")
let options = "{childIDs : [460128278_black, 460128278_blue]}"
RILEventManager.shared.fireTrackerAPI(trackerObject: json,
trackerType: .impression,
productId: productId,
adSize: "320x250",
productOptions: options)
NSLog("Retargetting | Impression event fired")
}
// Retargetting Viewable Trackers
@objc func fireViewableTracker(_ eventType: String, json: String, productId: String) {
print("\(TAG) | Retargetting | Native Method called from React! | fireEvent:: \(eventType) :: productId: \(productId) :: Json: \(json)")
let options = "{childIDs : [460128278_black, 460128278_blue]}"
RILEventManager.shared.fireTrackerAPI(trackerObject: json,
trackerType: .viewability,
productId: productId,
adSize: "320x250",
productOptions: options)
NSLog("Retargetting | Viewable event fired")
}
// Retargetting Click Trackers
@objc func fireClickTracker(_ eventType: String, json: String, productId: String) {
print("\(TAG) | Retargetting | Native Method called from React! | fireEvent:: \(eventType) :: productId: \(productId) :: Json: \(json)")
let options = "{childIDs : [460128278_black, 460128278_blue]}"
RILEventManager.shared.fireTrackerAPI(trackerObject: json,
trackerType: .click,
productId: productId,
adSize: "320x250",
productOptions: options)
NSLog("Retargetting | Click event fired")
}
// Fire Conversion Tracker
@objc func fireCoversionTracker(
_ level: String,
cid: String,
revenue: String,
currency: String,
prodRevenue: String,
prodQty: String,
prodPrice: String,
prodId: String
) {
print("\(TAG) | Retargetting | Native Method called from React! | level:: \(level) :: productId: \(prodId) ")
let options = ConversionOptions(revenue: revenue,
currency: currency,
prdrevenue: prodRevenue,
prdcount: Int(prodQty) ?? 0,
prdprice: prodPrice,
prdid: prodId)
RILEventManager.shared.fireConversionApi(clickId: cid,
level: Int(level) ?? 0,
options: options)
NSLog("Retargetting | Convertion Api Fired")
}
@objc func myNativeMethod(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
resolve("Native method executed successfully!")
}
private func fireEvent(tagValue: EventTypes, updatedJsonString: String) {
switch tagValue {
case .appLaunch: triggerAppLaunchEvent(updatedJsonString)
case .deeplink: triggerDeepLinkEvent(updatedJsonString)
case .addToCart: triggerAddToCartEvent(updatedJsonString)
case .addToWishlist: triggerAddToWishListEvent(updatedJsonString)
case .cartView: triggerCartViewEvent(updatedJsonString)
case .locationEvent: triggerLocationEvent(updatedJsonString)
case .pageView: triggerPageViewEvent(updatedJsonString)
case .productListView: triggerProductListViewEvent(updatedJsonString)
case .productView: triggerProductViewEvent(updatedJsonString)
case .purchaseCancelled: triggerPurchaseCancelledEvent(updatedJsonString)
case .purchaseCompleted: triggerPurchaseCompleteEvent(updatedJsonString)
case .purchaseReturn: triggerPurchaseReturnEvent(updatedJsonString)
case .removeFromCart: triggerRemoveFromCartEvent(updatedJsonString)
case .removeFromWishlist: triggerRemoveFromWishList(updatedJsonString)
case .userDetailsEvent: triggerUserDetailsEvent(updatedJsonString)
case .productSearchView: triggerProductSearchViewEvent(updatedJsonString)
case .customData: triggerCustomDataEvent(updatedJsonString)
}
}
}
extension JioAdHandler {
private func triggerAppLaunchEvent(_ jsonString: String) {
let test: [RILCustomerDetail] = [RILCustomerDetail(type: 0, idValue: "2abe7bdc1feba5d99ffc8bde4250e604", hashMethod: "md5"), RILCustomerDetail(type: 0, idValue: "2abe7bdc1feba5d99ffc8bde4250e604")]
RILEventManager.shared.trackEvent(AppLaunch(customerDetails: test))
}
private func triggerDeepLinkEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let deepLinkUrl = result?["deeplinkUri"]
let referApp = result?["referrerApp"]
let deepLinkEvent = RILDeepLinkLaunchEvent(deeplinkUri: deepLinkUrl as? String ?? "",
referrerApp: referApp as? String)
RILEventManager.shared.trackEvent(deepLinkEvent)
}
private func triggerProductSearchViewEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let details = result?["searchDetails"] as? [String: Any] ?? ["": ""]
let filters = details["filters"] as? [Any] ?? []
var rilFilters = [RILFilter]()
for filter in filters {
let filterDict: [String: Any] = filter as? [String: Any] ?? ["": ""]
let name = filterDict["name"] as? String ?? ""
let value = filterDict["value"] as? [String] ?? []
var selectedFilter = RILFilter()
selectedFilter.name = name
selectedFilter.value = value
rilFilters.append(selectedFilter)
}
let searchString = details["searchString"] as? String ?? ""
let currency = details["currency"] as? String ?? ""
let productList: Array = details["productList"] as? [Any] ?? []
var RILProducts = [RILProductListEvent]()
for product in productList {
let prdDict: [String: Any] = product as? [String: Any] ?? ["": ""]
let prod = RILProductListEvent(segment: prdDict["segment"] as? String ?? "",
id: prdDict["id"] as? String ?? "",
price: prdDict["price"] as? Int ?? 0,
quantity: prdDict["quantity"] as? Int ?? 0,
brickname: prdDict["brickname"] as? String ?? "",
vertical: prdDict["vertical"] as? String ?? "",
sku: prdDict["sku"] as? String)
RILProducts.append(prod)
}
var searchDetails = RILSearchDetails(productList: RILProducts, filters: rilFilters)
searchDetails.searchString = searchString
searchDetails.currency = currency
// searchDetails.filters = rilFilters
let searchViewEvent = RILSearchViewEvent(searchDetails: searchDetails)
RILEventManager.shared.trackEvent(searchViewEvent)
}
private func triggerUserDetailsEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
var customerDetail = [RILCustomerDetail]()
let custDetails = result?["customerDetails"] as? [Any] ?? []
for customer in custDetails {
let customerDict: [String: Any] = customer as? [String: Any] ?? ["": ""]
let type = customerDict["type"] as? Int ?? 0
let idValue = customerDict["idValue"] as? String ?? ""
let customerdet = RILCustomerDetail(type: type, idValue: idValue)
customerDetail.append(customerdet)
}
let event = RILAppUserDetailsEvent(customerDetails: customerDetail)
RILEventManager.shared.trackEvent(event)
}
private func triggerProductViewEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let startTime = result?["startTime"] as? String ?? ""
let endTime = result?["endTime"] as? String ?? ""
let event = RILProductViewEvent(startTime: startTime, endTime: endTime, productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerProductListViewEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let startTime = result?["startTime"] as? String ?? ""
let endTime = result?["endTime"] as? String ?? ""
let event = RILProductListViewEvent(startTime: startTime,
endTime: endTime,
productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerPageViewEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let pageName = result?["pageName"] as? String ?? ""
let startTime = result?["startTime"] as? String ?? ""
let endTime = result?["endTime"] as? String ?? ""
let event = RILPageViewEvent(pageName: pageName, startTime: startTime, endTime: endTime)
RILEventManager.shared.trackEvent(event)
}
private func triggerLocationEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let latitude = "\(JioAdSdk.userLocation?.coordinate.latitude ?? result?["latitude"] ?? "")"
let longitude = "\(JioAdSdk.userLocation?.coordinate.longitude ?? result?["longitude"] ?? "")"
let pincode = result?["pincode"] as? String ?? "123456"
let event = RILLocationEvent(productDetails: getProductDetails(eventType: jsonString),
latitude: latitude,
longitude: longitude,
pincode: pincode)
RILEventManager.shared.trackEvent(event)
}
private func triggerAddToCartEvent(_ jsonString: String) {
let event = RILAddToCartEvent(productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerRemoveFromCartEvent(_ jsonString: String) {
let event = RILRemoveFromCartEvent(productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerAddToWishListEvent(_ jsonString: String) {
let event = RILAddToWishListEvent(productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerRemoveFromWishList(_ jsonString: String) {
let event = RILRemoveFromWishListEvent(productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerPurchaseCompleteEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let transactionId = result?["transactionId"] as? String ?? ""
let event = RILPurchaseCompletedEvent(transactionId: transactionId,
productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event) { productsList in
NSLog("Retargetting | Products List: \(String(describing: productsList))")
}
}
private func triggerPurchaseCancelledEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let transactionId = result?["transactionId"] as? String ?? ""
let event = RILProductCancelledEvent(transactionId: transactionId,
productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerPurchaseReturnEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let transactionId = result?["transactionId"] as? String ?? ""
let event = RILPurchaseReturnEvent(transactionId: transactionId,
productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerCartViewEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let startTime = result?["startTime"] as? String ?? ""
let endTime = result?["endTime"] as? String ?? ""
let event = RILCartViewEvent(startTime: startTime,
endTime: endTime,
productDetails: getProductDetails(eventType: jsonString))
RILEventManager.shared.trackEvent(event)
}
private func triggerCustomDataEvent(_ jsonString: String) {
let result = sampleEventDictionary(eventType: jsonString)
guard result != nil else { return }
let customdataArr = result?["customData"] as? [Any] ?? []
let data = [String: Any]()
var dataArr = [data]
for custData in customdataArr {
let prdDict: [String: Any] = custData as? [String: Any] ?? ["": ""]
print(prdDict)
dataArr.append(prdDict)
}
let customEvent = RILCustomDataEvent(customData: dataArr)
RILEventManager.shared.trackEvent(customEvent)
}
private func getProductDetails(eventType: String) -> RILProductDetails {
let result = sampleEventDictionary(eventType: eventType)
let details = result?["productDetails"] as? [String: Any] ?? ["": ""]
let currency = details["currency"] as? String ?? ""
var listName = ""
if let listname = details["listName"] {
listName = listname as? String ?? ""
}
let productList: Array = details["productList"] as? [Any] ?? []
var RILProducts = [RILProductListEvent]()
for product in productList {
let prdDict: [String: Any] = product as? [String: Any] ?? ["": ""]
let prod = RILProductListEvent(segment: prdDict["segment"] as? String ?? "",
id: prdDict["id"] as? String ?? "",
price: prdDict["price"] as? Int ?? 0,
quantity: prdDict["quantity"] as? Int ?? 0,
brickname: prdDict["brickname"] as? String ?? "",
vertical: prdDict["vertical"] as? String ?? "",
sku: prdDict["sku"] as? String)
RILProducts.append(prod)
}
return RILProductDetails(currency: currency, productList: RILProducts, listName: listName)
}
private func sampleEventDictionary(eventType: String?) -> [String: Any]? {
if let jsonString = eventType {
return convertStringToDictionary(text: jsonString)
} else {
// self.showAlert(title: "Error", message: "Please provide a valid json string")
NSLog("\(TAG) | Retargetting | Please provide a valid json string")
return nil
}
}
func convertStringToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
if let jsonArray = try JSONSerialization.jsonObject(with: data, options: [.fragmentsAllowed]) as? [String: Any] {
return jsonArray
} else {
// self.showAlert(title: "Error", message: "Json serialization error")
print("json serialization error")
NSLog("\(TAG) | Retargetting | json serialization error")
}
} catch let error as NSError {
NSLog("\(TAG) | Retargetting | Invalid Json Error: \(error.localizedDescription)")
// self.showAlert(title: "Invalid Json Error", message: error.localizedDescription)
print(error)
}
}
return nil
}
}
enum EventTypes: String {
case deeplink = "DeepLink"
case appLaunch = "AppLaunch"
case addToCart = "AddToCart"
case addToWishlist = "AddToWishlist"
case cartView = "CartView"
case customData = "CustomData"
case locationEvent = "LocationEvent"
case pageView = "PageView"
case productListView = "ProductListView"
case productView = "ProductView"
case productSearchView = "ProductSearchView"
case purchaseCancelled = "PurchaseCancelled"
case purchaseCompleted = "PurchaseCompleted"
case purchaseReturn = "PurchaseReturn"
case removeFromCart = "RemoveFromCart"
case removeFromWishlist = "RemoveFromWishlist"
case userDetailsEvent = "UserDetailsEvent"
}
extension JioAdHandler {
@available(iOS 14, tvOS 14, *)
func requestAppTrackingPermission(_ completion: @escaping (ATTrackingManager.AuthorizationStatus) -> Void) {
ATTrackingManager.requestTrackingAuthorization { (status) in
switch status {
case .authorized:
// racking authorization dialog was shown and we are authorized
JioAdSdk.fetchBpid()
case .denied:
// Tracking authorization dialog was shown and permission is denied
SDKLog("AdTracking | status: Denied")
case .notDetermined:
// Tracking authorization dialog has not been shown
SDKLog("AdTracking | status: Not Determined")
case .restricted:
SDKLog("AdTracking | status: Restricted")
@unknown default:
SDKLog("AdTracking | status: Unknown")
}
completion(status)
}
}
}
-jio-style-title
#import "React/RCTViewManager.h"
@interface RCT_EXTERN_MODULE(JioAdHandler, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(data, NSDictionary);
RCT_EXTERN_METHOD(fetchPackage: (NSString *)packageName);
RCT_EXTERN_METHOD(setEnvironment: (NSString *)env);
RCT_EXTERN_METHOD(fireEvent: (NSString *)eventType
json: (NSString *)json);
RCT_EXTERN_METHOD(fireImpTracker: (NSString *)eventType
json: (NSString *)json
productId: (NSString *)productId);
RCT_EXTERN_METHOD(fireViewableTracker: (NSString *)eventType
json: (NSString *)json
productId: (NSString *)productId);
RCT_EXTERN_METHOD(fireClickTracker: (NSString *)eventType
json: (NSString *)json
productId: (NSString *)productId);
RCT_EXTERN_METHOD(fireCoversionTracker: (NSString *)level
cid: (NSString *)cid
revenue: (NSString *)revenue
currency: (NSString *)currency
prodRevenue: (NSString *)prodRevenue
prodQty: (NSString *)prodQty
prodPrice: (NSString *)prodPrice
prodId: (NSString *)prodId);
RCT_EXTERN_METHOD(myNativeMethod:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
@end
Drag and drop xib file and classes from sample app to project.
NativeContentStreamLayout.swift
NativeContentStreamLayout.xib
CustomNativeContentStremView.swift
CustomNativeContentStremView.xib
-jio-style-title
Conform the JioAdViewProtocol Call backs & delegate methods in each wrapper class for each ad format to catch the SDK events.
//SDK callbacks
// Implement JIOAdViewProtocol methods
func onAdReceived(adView: JioAdView) {
print("onAdReceived")
}
func onAdPrepared(adView: JioAdView) {
print( "onAdPrepared")
if adView == instreamadView {
self.instreamadView?.loadAd()
} else if adView == customNativeadView {
self.customNativeadView?.loadAd()
} else if adView == displayadView {
self.displayadView?.loadAd()
} else if adView == interstitaladView {
self.interstitaladView?.loadAd()
} else if adView == nativeContenadView {
self.nativeContenadView?.loadAd()
}
}
func onAdRender(adView: JioAdView) {
print("onAdRender")
}
func onAdClicked(adView: JioAdView) {
print("onAdClicked")
}
func onAdRefresh(adView: JioAdView) {
print("onAdRefresh")
}
func onAdFailedToLoad(adView: JioAdView, error: JioAdError) {
print("onAdFailedToLoad")
}
func onAdMediaEnd(adView: JioAdView) {
}
func onAdClosed(adView: JioAdView, isVideoCompleted: Bool, isEligibleForReward: Bool) {
}
func onAdMediaStart(adView: JioAdView) {
print("onAdMediaStart")
}
func onAdSkippable(adView: JioAdView) {
}
func onAdMediaExpand(adView: JioAdView) {
}
func onAdMediaCollapse(adView: JioAdView) {
}
func onMediaPlaybackChange(adView: JioAdView, mediaPlayBack: MediaPlayBack) {
}
func onAdDataPrepared(videoAd: VideoAd?, isLastAd: Bool) {
}
func onAdDataPrepared(nativeAd: NativeAd?, isLastAd: Bool) {
}
func onAdChange(adView: JioAdView, trackNo: Int) {
}
func mediationRequesting() {
}
func mediationLoadAd() {
}
For more understanding, Follow the Shared Test app.
-jio-style-title
-jio-style-title
1. Passing Custom Data to ad request
JioAdSdk.setMetaData(metaDataDict: self.SDKcustomMetaDataDict)
-jio-style-title
2. Setting Child Application Package name
Below API can be used to set Child application package name. This API will only work for trusted parent apps. If null string is passed it will be considered as rese
JioAdSdk.setPackageName(packageName:“bundleId”)
-jio-style-title
3.Global Ad Settings
JioAdSdk.setLogLevel(logLevel: .debug)
Follow the below link more info:
https://jioads.jio.com/getstarted-docs
-jio-end-block-type-2