React Native
Notes on apps in test mode! If your app is in test mode, you MUST use a test user. These are defined in "Test Devices" on the dashboard.
Installation
See latest versions at https://www.npmjs.com/package/react-native-tapresearch
Run the following command:
$ yarn add react-native-tapresearch
- iOS
- Android
In project_folder/iOS
, update cocoapods:
"TapResearch", "3.2.2"
$ pod install
In build.gradle of your app, add maven { url "https://artifactory.tools.tapresearch.io/artifactory/tapresearch-android-sdk/" }
in the allprojects/repositories
section:
allprojects {
repositories {
...
maven { url "https://artifactory.tools.tapresearch.io/artifactory/tapresearch-android-sdk/" }
...
}
}
Integration
Import the TapResearchSDK components
import {
PlacementCustomParamsProps,
TapSdkAdapter,
TapSdkUI,
TapUserAttributes,
TapSdkReward,
} from 'react-native-tapresearch';
Initialization
Initialize the TapResearchSDK as early as possible so TapResearch can start getting surveys ready for your users. The initializeSdk()
method only needs to be called once after the main component has been mounted. It's recommended that you use separate API tokens for iOS and Android so you can track performance metrics separately in the dashboard.
- Caveat: Initialize the sdk as early as possible once user identifier is known. Do NOT use an anonymized user identifier.
Parameters
- apiKey - from settings on publisher dashboard
- userIdentifier - unique identifier assigned to the current user of your app
- userAttributes - map with string key and number or string value, used for targeting content
- clearPreviousAttributes - boolean, remove all user attributes previously assigned to userIdentifier
// export type TapUserAttributes = Record<string, number | string>;
// TapSdkAdapter.initializeSdk(apiKey: string, userIdentifier: string, userAttributes: TapUserAttributes, clearPreviousAttributes: boolean)
TapSdkAdapter.initializeSdk("YOUR_IOS_OR_ANDROID_API_TOKEN", "USER_IDENTIFIER", userAttributes, clearPreviousAttributes);
SDK Callbacks setup
The SDK will call delegate functions to notify the app of certain events, for example to pass rewards or to notify the SDK has taken over the UI.
Define the callback functions with the following signatures:
onDidReceiveRewards: (rewards: Array<TapSdkReward>) => void;
onDidReceiveError: (error: TapSdkError) => void;
onContentShown: (contentMessage: any) => void;
onContentDismissed: (contentMessage: any) => void;
onTapResearchSdkReady: () => void;
onDidReceiveQQResponse: (qqResponse: TRQQDataPayload) => void;
For example, a reward callback may look like this:
function doRewards(rewards: Array<TapSdkReward>) {
console.log('Received some rewards', rewards);
}
Make sure to render the TapSDK component with the previously defined callbacks as its properties:
<TapSdkUI
onDidReceiveRewards={doRewards}
onContentDismissed={contentDismissed}
onContentShown={contentShown}
onDidReceiveError={onError}
onTapResearchSdkReady={onTapResearchSdkReady}
/>
Receiving Rewards
In the reward callback onDidReceiveRewards: (rewards: Array<TapSdkReward>) => void;
you will receive an array of TapSdkReward
objects which contain information about each reward such as amount and currency name:
export type TapSdkReward = {
transactionIdentifier: string;
placementTag: string;
placementIdentifier: string;
currencyName: string;
payoutEvent: string;
rewardAmount: number;
};
isReady SDK Method
As mentioned above, you can determine when the SDK is ready via the onTapResearchSdkReady callback.
Alternatively, you can also call the isReady method:
TapSdkAdapter.isReady()
It may look something like this (example in Typescript):
const isReady = useCallback(() => {
TapSdkAdapter.isReady()
.then((result: any) => {
console.log(`TapSdkAdapter.isReady() - Result: ${result}`);
Toast.hide();
Toast.show({
type: result ? 'success' : 'error',
text1: 'TapSdkAdapter.isReady?',
text2: result.toString(),
});
})
.catch((error: any) => {
console.error(error);
});
}, []);
<Button
onPress={isReady}
>
User Attributes
User attributes are used to target specific users with surveys. They can be set at any time and we will use the most recent values when determining which surveys to show.
User attributes are passed as a dictionary of key-value pairs.
If user attributes are known at SDK initialization, it is preferable to pass them through initOptions
compared to using sendUserAttributes
. This will result in quicker load times for targeted content.
User attributes prefixed with tapresearch_
are reserved for internal use. Please do not use this prefix for user attributes as doing so will result in an error
The keys must be strings and the values must be one of:
- String
- Float
- Boolean
- Integer
If you want to use a date, please stringify an ISO8601 date or use a timestamp.
// const clearPreviousAttributes = false; // combine new attributes with user attributes previously assigned to current user
const clearPreviousAttributes = "true"; // remove any user attributes previously assigned to current user
const now = new Date();
const userAttributes: TapUserAttributes = {
boolean: true,
integer: 1,
double: 1.1,
string: 'string',
isVIP: "true",
now: now.toISOString();
};
TapSdkAdapter.sendUserAttributes(userAttributes, clearPreviousAttributes);
Update User Identifier
You can set the user identifier at any time. This is done by calling setUniqueUserIdentifier
with a string.
TapSdkAdapter.setUniqueUserIdentifier("USER_IDENTIFIER");
Checking that a placement is available
You can check wether a placement is available by using canShowContentForPlacement()
. It is recommended that you wrap showContentForPlacement
calls with canShowContentForPlacement()
to handle situations when a placement may not be available.
TapSdkAdapter.canShowContentForPlacement(placementTag)
.then((canShowPlacement: boolean) => {
console.log(`canShowPlacement is ${canShowPlacement}`);
if (canShowPlacement) {
TapSdkAdapter.showContentForPlacement("YOUR_PLACEMENT_TAG");
}
}
})
.catch((error: any) => {
console.error(error);
});
Displaying a placement
Placements are locations and moments inside the app when content can be shown. To show content for a placement, you'll need to specify a placement tag
.
Note that the show content calls are wrapped in a canShowContent
check. This is to ensure that the placement is ready to be shown. If the placement is not ready, the SDK will return false
.
This helps guard against showing the user something that is not ready to be shown yet.
Placement tags can be found in your TapResearch dashboard on the App Settings page.
TapSdkAdapter.showContentForPlacement("YOUR_PLACEMENT_TAG");
Passing custom parameters
Custom parameters allow you to receive additional information about the user when they complete a survey. This can be used to filter out users who have already completed a survey, or to target specific users.
These params will be returned via server-to-server callbacks.
Parameters can only be ascii characters, Unicode is not supported. You can send a maximum of 5 custom parameters.
let customParams: PlacementCustomParamsProps = {
number: 1,
string: 'string',
boolean: true
};
TapSdkAdapter.showContentForPlacement("YOUR_PLACEMENT_TAG", customParams);
Quick Question Response
Quick Question Response is a beta feature!
A new callback is called whenever a Quick Question is completed:
onDidReceiveQQResponse: (qqResponse: TRQQDataPayload) => void;
This callback will return a TRQQDataPayload object (see below). This callback will get called regardless of whether or not a quick question server to server postback url is set on your dashboard (unlike the onDidReceiveRewards). This in app callback allows process and handle the response client side in a way that may otherwise be delayed with server to server postbacks. Ex: If a user likes your application, direct them to a link to the app store where they can leave a review.
Quick Question Types
export type TRQQDataPayload = {
survey_identifier : string;
app_name : string;
api_token : string;
sdk_version : string;
platform : string;
placement_tag : string;
user_identifier : string;
user_locale : string;
seen_at : string;
questions : [TRQQDataPayloadQuestion];
target_audience? : [TRQQDataPayloadTargetFilter];
complete? : TRQQComplete;
};
export type TRQQComplete = {
complete_identifier : string;
completed_at : string;
};
export type TRQQUserAnswer = {
value : string;
identifiers : [string];
};
export type TRQQDataPayloadQuestion = {
question_identifier : string;
question_text : string;
question_type : string;
rating_scale_size? : number;
user_answer? : TRQQUserAnswer;
};
export type TRQQDataPayloadTargetFilter = {
filter_attribute_name : string;
filter_operator : string;
filter_value : string;
user_value : string;
};