com-tapp-so-adjust-sdk
v1.1.0
Published
tapp's react native tapp-adjust sdk
Readme
com-tapp-so-adjust-sdk
React Native SDK for integrating Tapp + Adjust flows (link generation/resolution, deferred links, and event tracking) in iOS and Android apps.
This package is published as com-tapp-so-adjust-sdk and is intended for production React Native integrations.
Table of Contents
- Overview
- Features
- Architecture Support
- Requirements
- Installation
- iOS Setup
- Android Setup
- Recommended App Entry Setup
- Quick Start
- API Reference
- Example App
- Production Integration Notes
- Troubleshooting
- Contributing
- License
Overview
com-tapp-so-adjust-sdk is a React Native bridge over native Tapp/Tapp-Adjust SDK layers.
It exposes APIs to:
- initialize SDK configuration
- generate attribution URLs
- process deep links and deferred links
- track predefined/custom Tapp events
- call Adjust helper APIs for attribution, consent/state, ad IDs, and purchase/subscription flows
Features
- Startup initialization via
start({ authToken, env, tappToken }) - URL generation via
url(...) - Deep-link processing via
shouldProcess(...),fetchLinkData(...),fetchOriginLinkData() - Event listeners:
addDeferredLinkListener(...)addDidFailResolvingURLListener(...)
- Event tracking:
handleEvent(eventToken)handleTappEvent({ eventAction, customValue?, metadata? })
- Extended Adjust helper methods (platform-dependent)
Architecture Support
This repository contains explicit support paths for both Legacy Architecture and New Architecture, but support is not fully symmetrical across platforms in practice.
Legacy Architecture
- JS side uses
TurboModuleRegistry.getEnforcing(...), while native modules provide legacy bridge-compatible exports. - iOS legacy path is explicitly implemented with
RCTBridgeModulemethod exports and conditional compilation whenRCT_NEW_ARCH_ENABLEDis not set. - Android module is a classic
ReactContextBaseJavaModulewith@ReactMethodexports and is used byReactPackage#createNativeModules.
New Architecture
- Package is configured as a TurboModule library via
codegenConfigand Bob targets. - iOS has explicit New Architecture implementation:
- class adopts generated
NativeComTappSoAdjustSdkSpecandRCTTurboModule getTurboModule(...)returns generatedNativeComTappSoAdjustSdkSpecJSI- generated iOS code is present under
ios/generated
- class adopts generated
- Android enables new-arch-aware build flags and applies
com.facebook.react, and module implementsTurboModule, but uses aReactPackageimplementation (not a dedicated generated/spec subclass), so validation on your exact RN/new-arch setup is recommended.
Verified Example Configuration in This Repo
- iOS example:
RCT_NEW_ARCH_ENABLED = '1'(New Architecture enabled) - Android example:
newArchEnabled=false(Legacy path)
Architecture Caveats You Should Know
shouldProcessandadjustAppTrackingAuthorizationStatusare exposed as synchronous values across iOS Legacy and New Architecture paths.adjustVerifyPlayStorePurchaseuses the object input shape ({ transactionId, productId }) and the JS wrapper also accepts legacy positional args for compatibility.- Architecture test coverage in the example app is asymmetric (iOS New Architecture on, Android New Architecture off by default).
Requirements
Current repository configuration and tested baseline:
| Area | Value from repository |
| --- | --- |
| Package name | com-tapp-so-adjust-sdk |
| React Native (example) | 0.81.1 |
| React (example) | 19.1.0 |
| Node.js | v20.19.0 (.nvmrc) |
| iOS minimum | 11.0 (ComTappSoAdjustSdk.podspec) |
| Android minSdk | 24 |
| Android targetSdk | 34 |
| Android compileSdk | 35 |
| Kotlin (library default) | 2.0.21 |
| CocoaPods (example Gemfile) | >= 1.13 |
Peer dependencies:
reactreact-native
Installation
npm install com-tapp-so-adjust-sdkor
yarn add com-tapp-so-adjust-sdkor
pnpm add com-tapp-so-adjust-sdkReact Native autolinking is expected in standard RN projects.
Install iOS pods:
cd ios
pod installiOS Setup
1. Deployment target
Set your app iOS target to 11.0+.
2. Podfile
This SDK depends on Swift pods (Tapp, Tapp-Adjust, Tapp-Networking).
In the repository example, static frameworks are enabled:
use_frameworks! :linkage => :staticIf you hit Swift/static linking issues, mirror this setup.
3. Install pods
cd ios
pod install4. ATT permissions (if using ATT APIs)
If you call:
adjustRequestAppTrackingAuthorization()adjustAppTrackingAuthorizationStatus()
add NSUserTrackingUsageDescription in Info.plist.
5. Deep links and universal links
Configure your app URL schemes / universal links as usual in your own app target. Then route URLs in JS through SDK helpers (shouldProcess, fetchLinkData).
Android Setup
1. Add JitPack repository
The Android library depends on:
com.github.tapp-so.Tapp-Android:Tapp-Adjust:1.1.4
Ensure JitPack is available in your repositories.
settings.gradle (recommended modern setup):
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}2. SDK versions
Ensure your app config is compatible with at least:
minSdkVersion >= 24compileSdkVersion >= 35
3. Internet permission
<uses-permission android:name="android.permission.INTERNET" />4. Deep link intent filters
Add your own app-specific intent-filter entries for handled schemes/hosts if you use deep links.
5. Architecture toggle
To test Android New Architecture behavior in your app, set:
newArchEnabled=truein your app android/gradle.properties and validate key SDK calls.
Recommended App Entry Setup
The attached helper-hook pattern is the right integration intent: initialize early, process cold-start/runtime links, and register deferred/error listeners.
The original helper file is from older naming (com-tapp-sdk) and includes an affiliate config field that is no longer part of current InitConfig. Use the updated pattern below.
import { useEffect } from 'react';
import { Linking, Platform } from 'react-native';
import {
start,
shouldProcess,
fetchLinkData,
addDeferredLinkListener,
addDidFailResolvingURLListener,
type InitConfig,
} from 'com-tapp-so-adjust-sdk';
function getTappConfig(): InitConfig {
const env = __DEV__ ? 'SANDBOX' : 'PRODUCTION';
const authToken = Platform.select({
ios: process.env.EXPO_PUBLIC_TAPP_IOS_AUTHTOKEN,
android: process.env.EXPO_PUBLIC_TAPP_ANDROID_AUTHTOKEN,
});
const tappToken = Platform.select({
ios: process.env.EXPO_PUBLIC_TAPP_IOS_TAPPTOKEN,
android: process.env.EXPO_PUBLIC_TAPP_ANDROID_TAPPTOKEN,
});
if (!authToken || !tappToken) {
throw new Error('Missing Tapp SDK credentials in environment variables');
}
return { authToken, tappToken, env };
}
export function useTappConfig() {
useEffect(() => {
start(getTappConfig());
const handleDeepLink = async (url: string) => {
const should = shouldProcess(url);
if (!should) return;
const data = await fetchLinkData(url);
console.log('Resolved link data:', data);
};
Linking.getInitialURL().then((initialUrl) => {
if (initialUrl) {
void handleDeepLink(initialUrl);
}
});
const runtimeSub = Linking.addEventListener('url', ({ url }) => {
if (url) {
void handleDeepLink(url);
}
});
const deferredSub = addDeferredLinkListener((linkData) => {
console.log('Deferred link data:', linkData);
});
const failSub = addDidFailResolvingURLListener(({ url, error }) => {
console.warn('Failed resolving URL:', url, error);
});
return () => {
runtimeSub.remove();
deferredSub.remove();
failSub.remove();
};
}, []);
}Expo note:
- If you use Expo Linking utilities, adapt
Linkingcalls accordingly.
Quick Start
import {
start,
url,
handleEvent,
handleTappEvent,
EventAction,
} from 'com-tapp-so-adjust-sdk';
start({
authToken: 'YOUR_AUTH_TOKEN',
tappToken: 'YOUR_TAPP_TOKEN',
env: 'PRODUCTION',
});
const generatedUrl = await url('influencer_name');
await handleEvent('ADJUST_EVENT_TOKEN');
await handleTappEvent({
eventAction: EventAction.TAPP_PURCHASE,
metadata: {
source: 'rn_app',
screen: 'checkout',
value: 42,
isTester: true,
},
});
console.log(generatedUrl);API Reference
InitConfig
type InitConfig = {
authToken: string;
env: 'PRODUCTION' | 'SANDBOX';
tappToken: string;
};TappEventType
type TappMetadataValue = string | number | boolean;
type TappEventType = {
eventAction: EventAction;
customValue?: string;
metadata?: Record<string, TappMetadataValue>;
};Core APIs
| Method | Signature | Returns | iOS | Android |
| --- | --- | --- | --- | --- |
| start | start(config) | void | Yes | Yes |
| url | url(influencer, adGroup?, creative?, data?) | Promise<string> | Yes | Yes |
| handleEvent | handleEvent(eventToken) | Promise<string> | Yes | Yes |
| handleTappEvent | handleTappEvent({ eventAction, customValue?, metadata? }) | Promise<string> | Yes | Yes |
| shouldProcess | shouldProcess(deepLink) | boolean | Yes | Yes |
| fetchLinkData | fetchLinkData(deepLink) | Promise<TappLinkDataResponse> | Yes | Yes |
| fetchOriginLinkData | fetchOriginLinkData() | Promise<TappLinkDataResponse> | Yes | Yes |
Compatibility Notes
adjustAppTrackingAuthorizationStatus():
- Declared and exposed as synchronous
numberon iOS.
adjustVerifyPlayStorePurchase(...):
- Preferred input shape is
{ transactionId, productId }. - JS wrapper also accepts a legacy positional call form:
adjustVerifyPlayStorePurchase(transactionId, productId, completion?). adjustVerifyAndTrackPlayStorePurchase(...)remains a good alternative for event-token based Play Store flows.
Event Listener APIs
| Method | Signature | Returns | iOS | Android |
| --- | --- | --- | --- | --- |
| addDeferredLinkListener | (listener) | EmitterSubscription | Yes | Yes |
| addDidFailResolvingURLListener | (listener) | EmitterSubscription | Yes | Yes |
Adjust + Tapp Helper APIs
| Method | Returns | iOS | Android | Notes |
| --- | --- | --- | --- | --- |
| adjustTrackAdRevenue | void | Yes | Yes | |
| adjustVerifyAppStorePurchase | void | Yes | Yes | iOS callback payload currently not forwarded |
| adjustSetPushToken | void | Yes | Yes | |
| adjustGetAdid | Promise<string> | Yes | Yes | |
| adjustGetIdfa | Promise<string> | Yes | Yes | |
| adjustGdprForgetMe | void | Yes | Yes | |
| getAdjustAttribution | Promise<{ attribution: AdjustAttributionType }> | Yes | Yes | some fields are platform placeholders |
| adjustTrackThirdPartySharing | void | Yes | Yes | completion behavior differs by platform |
| adjustTrackAppStoreSubscription | void | Yes | No | JS-gated to iOS |
| adjustTrackPlayStoreSubscription | void | No | Yes | JS-gated to Android |
| adjustVerifyAndTrackPlayStorePurchase | void | No | Yes | JS-gated to Android |
| adjustGetGoogleAdId | Promise<string> | No | Yes | JS-gated to Android |
| adjustGetAmazonAdId | Promise<string> | Not supported | Yes | iOS call is not supported; avoid calling on iOS |
| adjustGetGooglePlayInstallReferrer | Promise<string> | Not supported | Yes | iOS call is not supported; avoid calling on iOS |
| adjustOnResume / adjustOnPause | void | No | Yes | JS-gated to Android |
| adjustEnable / adjustDisable | void | Yes | Yes | |
| adjustIsEnabled | Promise<boolean> | Yes | Yes | |
| adjustSwitchToOfflineMode / adjustSwitchBackToOnlineMode | void | Yes | Yes | |
| adjustAddGlobalCallbackParameter | void | Yes | Yes | |
| adjustAddGlobalPartnerParameter | void | Yes | Yes | |
| adjustRemoveGlobalCallbackParameter | void | Yes | Yes | |
| adjustRemoveGlobalPartnerParameter | void | Yes | Yes | |
| adjustRemoveGlobalCallbackParameters | void | Yes | Yes | |
| adjustRemoveGlobalPartnerParameters | void | Yes | Yes | |
| adjustTrackMeasurementConsent | void | Yes | Yes | |
| adjustGetSdkVersion | Promise<string> | No (JS-gated) | Yes | native iOS exists but JS wrapper gates to Android |
| adjustConvert | Promise<string \| null> | Yes | No | JS-gated to iOS |
| adjustSetReferrer | void | No | Yes | JS-gated to Android |
| adjustRequestAppTrackingAuthorization | Promise<number \| null> | Yes | No | JS-gated to iOS |
| adjustAppTrackingAuthorizationStatus | number | Yes | No | iOS-only |
| adjustUpdateSkanConversionValue | Promise<void> | Yes | No | JS-gated to iOS |
| adjustVerifyPlayStorePurchase | void | No | Yes | Preferred object param { transactionId, productId }; JS wrapper also supports legacy positional args for compatibility |
Exported types
The package exports:
EventActionInitConfig,EnvironmentTypeTappEventType,TappMetadata,TappMetadataValue,TappLinkDataResponseAdjustTrackAdRevenueType,AdjustAttributionTypeAppStoreSubscription,PlayStoreSubscriptionUpdateSkanConversionValueTypeVerifyResult,VerifyPlayStorePurchaseType, callback types
Example App
Example app location: example/
Important files:
example/src/App.tsx(SDK usage showcase)example/ios/Podfile(iOS architecture setting)example/android/gradle.properties(Android architecture setting)
Run from repository root:
yarn
yarn example startIn another terminal:
yarn example androidor:
yarn example iosFirst-time iOS setup:
cd example
bundle install
bundle exec pod install --project-directory=iosArchitecture note from example:
- iOS example is configured with New Architecture enabled.
- Android example is configured with New Architecture disabled.
Production Integration Notes
- Initialize once and early (app entry/root level), not lazily in feature screens.
- Use environment-specific credentials and avoid hardcoding production tokens in source.
- Keep deep-link handling centralized (cold start + runtime + deferred listener path).
- Always gate platform-specific APIs with
Platform.OSin app code. - For release readiness, test both architecture modes in your target app:
- iOS legacy/new
- Android legacy/new
- If migrating from older generated hook templates:
- update import package to
com-tapp-so-adjust-sdk - remove
affiliatefrom init config - keep listener cleanup in
useEffectteardown
- update import package to
Troubleshooting
| Problem | Check |
| --- | --- |
| Android dependency resolution fails | Ensure maven { url 'https://jitpack.io' } is configured |
| iOS build issues with Swift pods | Use static frameworks (use_frameworks! :linkage => :static) and rerun pod install |
| No deferred link callback | Confirm start(...) is called before listener-dependent logic |
| Deep links not processed | Verify URL format, app deep-link config, and shouldProcess/fetchLinkData pipeline |
| adjustVerifyPlayStorePurchase issues | Use object input { transactionId, productId } (or legacy positional args in JS wrapper) and consider adjustVerifyAndTrackPlayStorePurchase |
Contributing
License
MIT
