Getting Started#

Install the SDK (Cocoapods)#

Add the pod information into the app's Podfile.

For XCODE v12 iOS 14 support: pod 'TapResearch','2.3.0'

For XCODE v11: pod 'TapResearch','2.0.15'

Then run in the Terminal: pod install

Install the SDK (Manually)#

You can download the latest version of the SDK from this GitHub page.

Xcode Project Setup#

TapResearch requires a small number of settings changes that are not included by default.


  • Add the TapResearchSDK.framework to the Link Binary With Libraries section under the Build Phases tab.
  • In the same section, add the following frameworks:
    • Foundation.framework
    • UIKit.framework
    • SystemConfiguration.framework
    • MobileCoreServices.framework
    • AdSupport.framework
    • Security.framework


Select the Build Settings under the Other Linker Flags. In the search field, add the following flags:

  • -ObjC
  • -fobjc-arc (Only add this flag if you are not using ARC)

TapResearchSDK v2.3.0 introduces a new way of getting and showing placements.#

The SDK now internally gets the placements that are available for your app, caches them and lets you know when they are ready or become unavailable.


A new protocol has been added which is used by the SDK to let the app know a placement is ready or not available.

@protocol TapResearchPlacementDelegate <NSObject>
- (void)placementReady:(nonnull TRPlacement *)placement;
- (void)placementUnavailable:(nonnull NSString *)placementId;
`placementReady` is called when a placement has been received and is available to show.`placementUnavailable` is called when a placement is not currently available. An unavailable placement could become available later and at that time `placmeentReady` will be called.

v2.3.0 Note: placementExpired has been deprecated in place of placementUnavailable.

Initialize TapResearch#

It is best to initialize the SDK as early as possible, it is recommend doing it in the AppDelegate as follows:

// AppDelegate.h
#import <TapResearchSDK/TapResearchSDK.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>

Now you are ready to initialize the TapResearch SDK. Add the following line of code inside the applicationDidFinishLaunchingWithOptions method.

TapResearchSDK v2.3.0 Initialization#

A new initialization method has been added to add passing of a TapResearchPlacementDelegate object. This is the recommended method for initializing the SDK.

+ (void)initWithApiToken:(NSString * _Nonnull)apiToken
rewardDelegate:(id<TapResearchRewardDelegate> _Nonnull)rewardDelegate
placementDelegate:(id<TapResearchPlacementDelegate> _Nonnull)placementDelegate;

The existing initialization method, initWithApiToken:delegate, has been deprecated and will be removed in a future version of the SDK.

If you are using in-app rewards, make sure to add TapResearchRewardDelegate to the AppDelegate or any Controller and implement the tapResearchDidReceiveReward:placement: method to be notified when a player has earned a reward. Also make sure to pass that object to the initWithAppToken:delegate method:

// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// Your code logic
[TapResearch initWithApiToken:#{API_TOKEN} delegate:#{TapResearchRewardDelegate object}];

The next step is to send a unique user identifier. Keep in mind that without a unique user identifier, the survey wall will not be available.

[TapResearch setUniqueUserIdentifier:@"UNIQUE_USER_IDENTIFIER"];

Our system only accepts User IDs with ASCII characters.


A Placement is an object that should be attached to the app's call to action that will direct the users to TapResearch.

To view the available placements or to create a new one, navigate to the app settings in the Supplier Dashboard, and copy the placement's identifier.

The Placement is encapsulated in the TRPlacement object which contains metadata and the method to display the survey wall.

Showing a placement#

Previously when showing a placement the placement had to be initialised first by calling one of the initPlacementWithIdentifier SDK methods:

+ (void)initPlacementWithIdentifier:(nonnull NSString *)placementIdentifier
placementBlock:(nonnull void(^)(TRPlacement * _Nonnull placement))block;
+ (void)initPlacementWithIdentifier:(nonnull NSString *)placementIdentifier
placementCustomParameters:(nullable TRPlacementCustomParameterList *)placementParameterList
placementBlock:(nonnull void(^)(TRPlacement * _Nonnull placement))block;

This is no longer required, the SDK initialises placements for you internally.

If placementReady has been called for the placement you would like to show then you can just call one of the placement show methods:

- (void)showSurveyWallWithDelegate:(id<TapResearchSurveyDelegate>)surveyDelegate;
- (void)showSurveyWallWithDelegate:(id<TapResearchSurveyDelegate>)surveyDelegate
customParameters:(TRPlacementCustomParameterList *)customParameters;

More About Placements#

  • If initPlacementWithIdentifier was called before the SDK initialization was completed, the SDK will return two placements: the first will return a placementCode with a value of PLACEMENT_CODE_SDK_NOT_READY and won't display the survey wall. The second placement response will occur once the SDK is initialized. The placement request will be fired and the callback will be triggered with a live placement.

  • The survey wall may or may not be available to a specific user. It's important to check survey availability before displaying the call to action.

  • A placement can only show the survey wall once. After the survey wall is dismissed, you'll have to initialize a new TRPlacement object if you want the user to go back to TapResearch.

Display the survey wall#

To display the survey wall, you need to call the showSurveyWallWithDelegate method of the TRPlacement object.

- (IBAction)surveyButtonTouched:(id)sender
[self.tapresearchPlacement showSurveyWallWithDelegate:nil];

To listen to the survey wall status, make the placement's ViewController adopt the TapResearchSurveyDelegate:

@interface MainViewController : UIViewController<TapResearchSurveyDelegate>
- (IBAction)surveyButtonTouched:(id)sender
[self.tapresearchPlacement showSurveyWallWithDelegate:self];
- (void)tapResearchSurveyWallOpenedWithPlacement:(TRPlacement *)placement
// App went to the background
- (void)tapResearchSurveyWallDismissedWithPlacement:(TRPlacement *)placement
// Resume app

Going Live#

Learn how to take the app live.


Server to server callbacks#

You can read more about server to server callbacks.

In-app Callbacks#

The SDK will check if the user has unredeemed rewards in the following events:

  • On SDK initialization
  • When the user exits TapResearch

Add TapResearchRewardDelegate to the AppDelegate or any Controller to be notified when a player has earned a reward. A reward will fire: tapResearchDidReceiveReward:placement: or tapResearchDidReceiveRewards:placement: method depending on your implementation preference.

The reward information will be encapsulated in the TRReward object with the following methods:

Property nameTypeDescription
transactionIdentifierNSStringThe unique reward identifier
currencyNameNSStringThe virtual currency name
PlacementIdentifierNSStringThe placement that started the session identifier
rewardAmountNSIntegerThe reward amount in virtual currency. The value will automatically be converted to your virtual currency based on the exchange rate you specified in the app settings.
payoutEventNSIntegerThe action that the user was rewarded for. 0 - Profile Complete, 3 - Survey Complete.

// AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate, TapResearchRewardDelegate>
- (void)tapResearchDidReceiveReward:(TRReward *)reward
NSString *message = [NSString stringWithFormat:@"You have just received %lu %@ for your efforts.",
(long)reward.rewardAmount, reward.currencyName];
//your reward login

If you opted for the tapResearchDidReceiveRewards:placement: to receive multiple rewards your implementation should look like:

// AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate, TapResearchRewardDelegate>
- (void)tapResearchDidReceiveRewards:(NSArray<TRReward *>*)rewards
for (TRReward* reward in rewards) {
NSString *message = [NSString stringWithFormat:@"You have just received %lu %@ for your efforts.",
(long)reward.rewardAmount, reward.currencyName];
//your reward logic

It is important to note that tapResearchDidReceiveReward will be called back-to-back if the player completed multiple surveys in one session.

Hot Survey#

hasHotSurvey is a placement attribute that indicates a special high-yield survey is available for this user. When this attribute is true, the user should be shown a special call to action to encourage them to take advantage of this opportunity. These special survey opportunities may only be available for a few minutes, so initPlacementWithIdentifier should be called whenever the parent view is loaded. If you want to use Hot Surveys, please contact

Custom Parameters (Server to Server callbacks only)#

Apps that require additional data on server callback can send it using custom parameters. Custom parameters are attached to the placement request and will be fired back in the callback.

To use custom parameters, there are two objects that must be constructed:

  • TRPlacementCustomParameterList will contain a list of TRPlacementCustomParameter objects
  • TRPlacementCustomParameter which uses the builder design pattern

Custom parameters, TRPlacementCustomParameterList, are now passed at the time of showing a placement, no longer when initialising a placement.

To pass TRPlacementCustomParameterList when showing a placement call:

- (void)showSurveyWallWithDelegate:(id<TapResearchSurveyDelegate>)surveyDelegate
customParameters:(TRPlacementCustomParameterList *)customParameters;

The previous method of passing TRPlacementCustomParameterList has been deprecated and will be removed in a future version: initPlacementWithIdentifier:placementCustomParameters:placementBlock:.

Note: may return nil and TRPlacementCustomParameterList addParameter may return NO to enforce the following rules:

  • TRPlacementCustomParameter max character length is 256
  • The TRPlacementCustomParameter key and value can’t be null and length should be bigger than 0
  • TRPlacementCustomParameterList is restricted to maximum of 5 TRPlacementCustomParameter objects

A full example will look like:

TRPlacementCustomParameter *param = [TRPlacementCustomParameter new];
[[[[param builder] key: @"foo"] value: @"bar"] build];
TRPlacementCustomParameterList *parameterList = [[TRPlacementCustomParameterList alloc] init];
[parameterList addParameter:param];
[TapResearch initPlacementWithIdentifier:identifier placementCustomParameters: parameterList placementBlock:^(TRPlacement *placement) {

Customize the survey wall#

If you wish to customize the look of the survey wall modal to fit with the rest of your app, use the following:

[TapResearch setNavigationBarText:@"Title"];
[TapResearch setNavigationBarColor:[UIColor colorWithRed:1.0f green:0.5f blue:0.5f alpha:1.0f];];
[TapResearch setNavigationBarTextColor:[UIColor colorWithRed:0.5f green:0.5f blue:1.0f alpha:1.0f];];

Upgrade To v2.3.0#

Calling theses methods are no longer required for showing placements:

+ (void)initPlacementWithIdentifier:(nonnull NSString *)placementIdentifier
placementBlock:(nonnull void(^)(TRPlacement * _Nonnull placement))block;
+ (void)initPlacementWithIdentifier:(nonnull NSString *)placementIdentifier
placementCustomParameters:(nullable TRPlacementCustomParameterList *)placementParameterList
placementBlock:(nonnull void(^)(TRPlacement * _Nonnull placement))block;

Custom parameters are now called when showing a placement instead of init:

+ (void)showSurveyWallWithDelegate:(id<TapResearchSurveyDelegate>)surveyDelegate
customParameters:(TRPlacementCustomParameterList *)customParameters;

Upgrade to v2.2.1#

The following method was added to the SDK:

+ (void)tapResearchDidReceiveRewards:(NSArray<TRReward *>*)rewards

Upgrade to v2.0.0#

The following methods and protocols were removed from the SDK:

+ (BOOL)isSurveyAvailable;
+ (BOOL)isSurveyAvailableForIdentifier:(NSString *)identifier;
+ (void)showSurvey;
+ (void)showSurveyWithDelegate:(id<TapResearchSurveyDelegate>)delegate
+ (void)showSurveyWithIdentifier:(NSString *)identifier delegate:(id<TapResearchSurveyDelegate>)surveyDelegate;
@protocol TapResearchDelegate <NSObject>
@protocol TapResearchSurveyDelegate <NSObject>

Test Devices#

Before you are ready to go live, it is important that your reward callback is working properly. Navigate to your dashboard and click the Add Devices button. Add a device name and your advertiser identifier. Now, when you enter our survey flow through your app, you will be able to complete a test survey and receive a test reward when you re-open your app.


Survey wall isn't available#

When placement.isSurveyWallAvailable returns false, check the console output for the following message template:

"Placement isn't available reason - %lu, comment - %@"

Common reason codes are:

  • 2 - The placement was initialized from a non test device when the app is in test mode
  • 4 - Non-supported country
  • 6 - The app opted for server to server callback but no unique user identifier was set
  • 17 - The placement identifier isn't associated with the App


Please send all questions, concerns, or bug reports to