Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

@adadapted/react-native-sdk

1.0.5 • Public • Published

AdAdapted React Native SDK

The AdAdapted react-native SDK.

[[TOC]]

Features

  • Ad zone creation
  • In-app ad display popup/browser
  • In-list add suggestion based on available keywords
  • Event tracking enabling reporting
  • Supported ad types:
    • Add to list (reports a product to add to a list)
    • Add to list circular (opens in-app within a popup view and displays a multi-item "add to list" circular)
    • Standard external link (opens in external browser)
    • Popup external link (opens in-app within popup view)

Installation

npm install --save @adadapted/react-native-sdk

Once the NPM install script above is complete, navigate to your /ios directory in your project and run the following:

pod install

This will ensure that iOS is linked up to the AdAdapted SDK dependency properly.

NOTE: This SDK uses base64 images and requires a minimum version of flipper used in your Podfile. Please see Potential Issue 3 for more details.

Usage

The following is an example of how to use the SDK.

Start by importing the AdadaptedReactNativeSdk namespace that contains all available SDK actions. You should do this in your main component file so you are defining the SDK reference once and passing down the reference as needed through props.

import { AdadaptedReactNativeSdk } from "@adadapted/react-native-sdk";

Within the component's constructor() assign the reference to the SDK. You will also want to initialize a state property to hold a reference to the Ad Zones that will be generated by the SDK when initialized.

constructor(props) {
    super(props);
 
    this.aaSdk = new AdadaptedReactNativeSdk.Sdk();
 
    this.state = {
        adZoneDataList: undefined
    };
}

Within the componentDidMount() react lifecycle method, trigger the SDK initialization by calling the initialize() method on your SDK reference. In the below example, you will need to replace the string YOUR_APP_ID with the app ID provided to you by AdAdapted. The initialize() method is promise based, so once the .then() callback occurs, the SDK is initialized and you can start interfacing as needed with your reference of the SDK.

It is important to also provide the initialize() method a definition for the onAdZonesRefreshed() method. Since the SDK will periodically refresh the Ad Zone data, this will enable you to keep your references to the Ad Zone data up to date. See Available Callbacks: onAdZonesRefreshed() for more details.

You can also provide a definition for the onAddToListTriggered() method if you would like to use the "add to list" feature of the SDK. See Available Callbacks: onAddToListTriggered() for more details.

componentDidMount(): void {
    this.aaSdk
        .initialize({
            appId: "YOUR_APP_ID",
            onAdZonesRefreshed: () => {
                this.setState({
                    adZoneDataList: this.aaSdk.getAdZones()
                });
            },
            onAddToListTriggered: (items) => {
                for (const item of items) {
                    // Add the item to the users list.
                }
            }
        })
        .then(() => {
            // SDK session has been created.
            // Ad Zones are now available.
            this.setState({
                adZoneDataList: this.aaSdk.getAdZones()
            });
        })
        .catch((err) => {
            console.error(err);
        });
}

You will want to make sure to clean up the reference to the SDK when you unmount your component. To do this, call the unmount() method on your SDK reference from within the componentWillUnmount() react lifecycle method. This will ensure certain features of the SDK are cleaned up and will allow you to avoid memory leaks.

componentWillUnmount(): void {
    if (this.aaSdk) {
        this.aaSdk.unmount();
    }
}

The following is a simple example of using the Ad Zones that were supplied by the SDK and stored in the component state. In this example, we are just iterating the Ad Zone list and displaying each one after the other.

A more likely use-case would be for you to reference the ID of the Ad Zone within each object and based on that ID, determine the placement within your app for each Ad Zone.

render() {
    return (
        <SafeAreaView>
            {this.state.adZoneDataList && this.state.adZoneDataList.map((adZoneInfo, idx) => {
                return (
                    <View key={idx} style={styles.adZoneContainer}>
                        {adZoneInfo.adZone}
                    </View>
                );
            })}
        </SafeAreaView>
    );
}

Available Methods

initialize()

The initialize method is where your SDK session is created. This method returns a promise that when complete, your reference to the SDK will have a valid SDK session going forward. Once you have a valid session, you will be able to successfully use other SDK methods. You should call this method from within the componentDidMount() react lifecycle method to ensure it is only called once upon component mount.

aaSdk.initialize({
    /**
     * The app ID provided to you by AdAdapted.
     * If you have multiple variations of the app, you will be provided with multiple App IDs.
     * For each App ID you have, you will need to determine the correct one to provide the SDK when initializing based on the users variation of the app. 
     * Must be provided for the SDK to initialize.
     */
    appId: string,
    /**
     * (Optional)
     * Provide this value to define what API environment the SDK should use.
     *
     * Possible Values:
     *     - Production: AdadaptedReactNativeSdk.ApiEnv.Prod
     *     - Development: AdadaptedReactNativeSdk.ApiEnv.Dev
     * 
     * Production is the default value if you don't provide this property in your config. 
     */
    apiEnv: AdadaptedReactNativeSdk.ApiEnv,
    /**
     * (Optional)
     * Triggered when the available ad zones have
     * refreshed their data with the AdAdapted API.
     */
    onAdZonesRefreshed(() => {}),
    /**
     * (Optional)
     * Triggered when an "add to list" action has
     * taken place by a user.
     */
    onAddToListTriggered((items[]) => {})
})

Return Type:

Promise<void>

unmount()

This method will ensure the SDK is cleaned up when the component it is defined within is being destroyed. This method must be called within the componentWillUnmount() react lifecycle method.

NOTE: If you do not call this method, you risk creating a memory leak.

aaSdk.unmount();

Return Type:

void

getSessionId()

Once the SDK is initialized, this method returns the current session ID.

aaSdk.getSessionId();

Return Type:

string

getDeviceInfo()

Once the SDK is initialized, this method exposes device information based on the users current device.

aaSdk.getDeviceInfo();

Return Type:

{
    /**
     * The unique device ID.
     */
    udid: string;
    /**
     * The device name.
     */
    deviceName: string;
    /**
     * The operating system name.
     */
    systemName: string;
    /**
     * The operating system version.
     */
    systemVersion: string;
    /**
     * The device model.
     */
    deviceModel: string;
    /**
     * The device screen width.
     */
    deviceWidth: string;
    /**
     * The device screen height.
     */
    deviceHeight: string;
    /**
     * The device screen density.
     */
    deviceScreenDensity: string;
    /**
     * The current device local.
     */
    deviceLocale: string;
    /**
     * The bundle ID.
     */
    bundleId: string;
    /**
     * The bundle version.
     */
    bundleVersion: string;
    /**
     * The current device timezone.
     */
    deviceTimezone: string;
    /**
     * If true, ad tracking is enabled for the device.
     */
    isAdTrackingEnabled: boolean;
}

getAdZones()

Once the SDK is initialized, this method gets all available ad zones that can be used. The resulting array of ad zone objects each contain a property called adZone which is a react-native component that manages all ad related operations for the ad zone. All you need to do with these components is to display them in the locations you would like the ads displayed in your app.

aaSdk.getAdZones();

Return Type:

[
    {
        /**
         * The ad zone ID.
         */
        zoneId: string;
        /**
         * The ad zone component.
         */
        adZone: JSX.Element;
    }
]

performKeywordSearch()

Once the SDK is initialized, this method can be called when performing a search operation within your app. Call this method either as the user types in a search term or when the user executes a search after the term is entered. A list of keyword search results will be returned by this method that can then be used to display dynamically along with the search results your app displays to the user. The final result of the search may have many items, in which case you would determine how many of them you would like to display.

aaSdk.performKeywordSearch(searchTerm: string);

Return Type:

[
    /**
     * The search term ID.
     */
    term_id: string;
    /**
     * The search term that was used to validate
     * the provided search string against.
     */
    term: string;
    /**
     * The display string you can use to display the
     * resulting item in your search results list.
     */
    replacement: string;
    /**
     * The display priority of this item amongst all
     * other keyword search results. The priority acts
     * as a secondary sort. The primary sort is based
     * on whether the "term" starts with the provided
     * search term characters or not.
     *
     * NOTE: Sorting is already handled for you by the SDK.
     * The results will already be in the correct sort order.
     */
    priority: number;
]

The final result is sorted based on the following criteria:

  • First, the items are sorted based on which ones "started" with the characters in the provided search string
  • Second, they are then sorted by the "priority" property for each keyword that satisfied the search

Search Example: che

Keyword Term Priority
Chex Mix 2
Cheddar Cheese 3
Sweet Cherries 1
Mac & Cheese 4
Water Chestnuts 5

reportKeywordInterceptTermsPresented()

This method must be called anytime a keyword suggestion(provided by the performKeywordSearch() method) is displayed to the user. Calling this method reports back these suggested keywords to AdAdapted.

NOTE: Making sure to call this method when a keyword is displayed will ensure AdAdapted can provide you with the most accurate reporting results.

This method accepts a list of term_id of the displayed keywords. See performKeywordSearch() return type for more info on the term_id property.

aaSdk.reportKeywordInterceptTermsPresented(termIds: string[]);

Return Type:

void

reportKeywordInterceptTermSelected()

This method must be called anytime a keyword suggestion(provided by the performKeywordSearch() method) is selected by the user from your displayed search result list. Calling this method reports back the selected keyword to AdAdapted.

NOTE: Making sure to call this method when a keyword is selected will ensure AdAdapted can provide you with the most accurate reporting results.

This method accepts the term_id from the selected keyword. See performKeywordSearch() return type for more info on the term_id property.

aaSdk.reportKeywordInterceptTermSelected(termId: string);

Return Type:

void

Available Callbacks

onAdZonesRefreshed()

This callback method is useful for knowing when the Ad Zone data gets refreshed by the API. This automatically happens based on a threshold of time to wait in between refresh attempts.

NOTE: It is recommended that you store the Ad Zone data in your component state and update the state within this callback with the refreshed Ad Zone data.

If there are any other actions you need to take place when the Ad Zone data is refreshed, you can do so at this time.

aaSdk.initialize({
    ...other_props,
    onAdZonesRefreshed=(() => {
        // Update your state by pulling the refreshed
        // Ad Zone data with aaSdk.getAdZones()
    })
});

onAddToListTriggered()

This callback method is triggered when a user clicks an add to list ad zone. This method receives an items list that contains each item the user selected to add to their list.

If there are any other actions you need to perform when the user adds an ad item to their list, you can do so at this time.

aaSdk.initialize({
    ...other_props,
    onAddToListTriggered=((items) => {
        // See below for the type definition of the "items" list.
    })
});

Type Definition: items

[
    {
        /**
         * The barcode of the product.
         */
        product_barcode: string;
        /**
         * The brand of the product.
         */
        product_brand: string;
        /**
         * The category of the product.
         */
        product_category: string;
        /**
         * The discount given for the product.
         */
        product_discount: string;
        /**
         * The image used for display of the product.
         */
        product_image: string;
        /**
         * The SKU of the product.
         */
        product_sku: string;
        /**
         * The name/title of the product.
         */
        product_title: string;
    }
]

Possible Implementation Issues And Fixes

Potential Issue 1

NOTE: This error is only related to Android.

The first potential issue you can have when setting up the SDK is the following error:

Android Studio Could not initialize class org.codehaus.groovy.runtime.InvokerHelper

If this occurs, you can fix it by updating your gradle version in the gradle-wrapper.properties file as suggested in this post.


Potential Issue 2

The second potential issue is related to one of the NPM packages required by the SDK.

Invariant Violation: requireNativeComponent: "RNCWebView" was not found in the UIManager

If this occurs, you can fix it by directly installing the react-native-webview package if your project doesn't already use it.

npm install --save react-native-webview

NOTE: Make sure to re-run pod install from your ios folder once the react-native-webview package finishes installing.


Potential Issue 3

NOTE: This error is only related to iOS.

The third potential issue can occur due to the use of base64 images within the SDK. This issue is harder to debug, as it just causes the app to crash/close without much information as to why it did so. The solution for this is to update your Podfile to use newer versions of Flipper.

versions["Flipper"] ||= "~> 0.37.0";
versions["Flipper-Folly"] ||= "~> 2.2";
versions["Flipper-RSocket"] ||= "~> 1.1";

These versions seem to be the minimum versions to support base64 images and were the versions suggested for use in this post.

Limitations

  • This SDK uses timers in order to know when session data needs to be refreshed. You will most likely see the following warning message displayed in the debug console when running in an emulator:

    Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info. (Saw setTimeout with duration 300000ms)
    

License

AdAdapted Platform License

Install

npm i @adadapted/react-native-sdk

DownloadsWeekly Downloads

15

Version

1.0.5

License

AdAdapted Platform License

Unpacked Size

510 kB

Total Files

73

Last publish

Collaborators

  • avatar