Affise Attribution Library
npm install affise-attribution-lib| Package | Version |
|--------------------------|:----------------------------------------------------------------------------------------------------------------------------------------:|
| affise-attribution-lib |  |
- Affise Attribution React Native Library
- Description
- Quick start
- SDK compatibility
- Integration
- Integrate npm package
- Modules
- Android
- iOS
- Installed active modules
- Manual exclude modules
- Module AdService
- Module Advertising
- Module AppsFlyer
- Module Huawei
- Module Link
- Module Meta
- Module Persistent
- Module Status
- Module Subscription
- AffiseProductType
- Module TikTok
- Initialize
- Initialization callbacks
- Before application is published
- Domain
- Requirements
- Android
- iOS
- Persistent data
- Reinstall tracking
- Features
- ProviderType identifiers collection
- Attribution
- AdService
- Advertising
- AndroidId
- Huawei
- Meta
- Network
- Phone
- Event send control
- Events tracking
- Custom events tracking
- Predefined event parameters
- PredefinedString
- PredefinedLong
- PredefinedFloat
- PredefinedObject
- PredefinedListObject
- PredefinedListString
- Events buffering
- Advertising Identifier (google) tracking
- Open Advertising Identifier (huawei) tracking
- Install referrer tracking
- Push token tracking
- Native
- iOS APNs
- Firebase NPM package
- iOS APNs
- Uninstall tracking
- APK preinstall tracking
- Links
- Deeplinks
- Android
- iOS
- AppLinks
- Android
- iOS
- Get deferred deeplink
- Get deferred deeplink value
- Offline mode
- Disable tracking
- Disable background tracking
- Get random user Id
- Get Affice device Id
- Get providers
- Is first run
- Get referrer
- Get referrer value
- Referrer keys
- Get module status
- Platform specific
- GDPR right to be forgotten
- StoreKit Ad Network
- SDK to SDK integrations
- Debug
- Validate credentials
- Version
- Version native
- Troubleshoots
- iOS
Affise SDK is a software you can use to collect app usage statistics, device identifiers, deeplink usage, track install
referrer.
- Xcode 14.2+
- iOS 12+
- Android 24+
This is a Node.js module available through the npm registry.
Installation using npm
``console`
npm install affise-attribution-lib
Installation using yarn
`console`
yarn add affise-attribution-lib
#### Android
Add modules to Android project
| Module | Version |
|----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ADVERTISING |  |ANDROIDID
| |  |APPSFLYER
| |  |LINK
| |  |NETWORK
| |  |PHONE
| |  |STATUS
| |  |SUBSCRIPTION
| |  |RUSTORE
| |  |HUAWEI
| |  |META
| |  |TIKTOK
| |  |
Example example/android/app/build.gradle
`gradle
final affise_version = '1.6.74'
dependencies {
// Affise modules
implementation "com.affise:module-advertising:$affise_version"
implementation "com.affise:module-androidid:$affise_version"
implementation "com.affise:module-link:$affise_version"
implementation "com.affise:module-network:$affise_version"
implementation "com.affise:module-phone:$affise_version"
implementation "com.affise:module-status:$affise_version"
implementation "com.affise:module-subscription:$affise_version"
implementation "com.affise:module-meta:$affise_version"
implementation "com.affise:module-rustore:$affise_version"
implementation "com.affise:module-huawei:$affise_version"
implementation "com.affise:module-appsflyer:$affise_version"
implementation "com.affise:module-tiktok:$affise_version"
}
`
#### iOS
Add modules to iOS project
| Module | Version |
|----------------|:------------------------------------------------------------------------------------:|
| ADSERVICE | 1.6.59 |ADVERTISING
| | 1.6.59 |APPSFLYER
| | 1.6.59 |LINK
| | 1.6.59 |PERSISTENT
| | 1.6.59 |STATUS
| | 1.6.59 |SUBSCRIPTION
| | 1.6.59 |TIKTOK
| | 1.6.59 |
Example example/ios/Podfile
`ruby
target 'YourAppProject' do
# ...
affise_version = '1.6.59'
# Affise Modules
pod 'AffiseModule/AdService', affise_version
pod 'AffiseModule/Advertising', affise_version
pod 'AffiseModule/AppsFlyer', affise_version
pod 'AffiseModule/Link', affise_version
pod 'AffiseModule/Persistent', affise_version
pod 'AffiseModule/Status', affise_version
pod 'AffiseModule/Subscription', affise_version
pod 'AffiseModule/TikTok', affise_version
end
`
#### Installed active modules
Get list of installed modules:
`typescriptModules: ${modules}
Affise.module.getModulesInstalled().then((modules) => {
console.log();`
});
#### Manual exclude modules
To manually stop modules from starting use Affise.settings.setDisableModules:
`typescript`
Affise
.settings({
affiseAppId: 'Your appId',
secretKey: 'Your SDK secretKey',
})
.setDisableModules([
// Exclude modules from start
AffiseModules.ADVERTISING,
AffiseModules.SUBSCRIPTION,
])
.start(); // Start Affise SDK
#### Module AdService
iOS 14.3+
Sends attributionToken from AdServices framework AAAttribution.attributionToken() to Affise server
#### Module Advertising
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> iOS only
>
> Advertising Module starting Manually
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
`typescript`
Affise.module.advertising.startModule()
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> iOS onlyNSUserTrackingUsageDescription
>
> Module Advertising requires key in info.plist
>
> Application will crash if key not present
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
This module required to Use IDFA (Identifier for advertisers)
Open info.plist and add key NSUserTrackingUsageDescription with string value. For more information read requirements
#### Module AppsFlyer
Send AppsFlyer event data to Affise
`typescript`
//AppsFlyer event data
const eventName = "af_add_to_wishlist"
const eventValues = {
af_price: 1234.56,
af_content_id: "1234567",
};
// Send AppsFlyer event
appsFlyer.logEvent(
eventName,
eventValues,
(res) => console.log(res),
(err) => console.error(err)
);
// Send AppsFlyer data to Affise
Affise.module.appsflyer.logEvent(eventName, eventValues);
Is Module present:
`typescript`
Affise.module.appsflyer.hasModule().then((hasModule) => {
// Check is module present
})
#### Module Huawei
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> Use Android Huawei Module to get OAID (Open Advertising Identifier)
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
`typescript`
Affise.getProviders().then((providers) => {
const oaid = providers[ProviderType.OAID];
});
#### Module Link
Return last url in chan of redirection
π₯Support MAX 10 redirectionsπ₯
`typescript`
Affise.module.link.resolve("SITE_WITH_REDIRECTION", (redirectUrl) => {
// handle redirect url
});
Is Module present:
`typescript`
Affise.module.link.hasModule().then((hasModule) => {
// Check is module present
})
#### Module Meta
- Meta Install Referrer Docs
- Google's Install Referral Docs
1. Add queries to your AndroidManifest.xml
`xml
...
`
2. Add your Facebook App Id as config value AffiseConfig.FB_APP_ID in Affise.settings
`typescript`
Affise
.settings({
affiseAppId: 'Your appId', //Change to your app id
secretKey: 'Your SDK secretKey', //Change to your SDK secretKey
})
.setConfigValue(AffiseConfig.FB_APP_ID, "Your Facebook App Id")
.start(); // Start Affise SDK
#### Module Persistent
iOS Only
> [!NOTE]
>
> Module requires user phone to be authenticated by Apple ID
>
> It uses Apple Security framework to store protected information in user account
Persist device id value for Get random device Id on application reinstall
#### Module Status
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> If getStatus return an error or working more than 2 minutes
>
> Please see section validation credentials
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
`typescript`
Affise.module.getStatus(AffiseModules.STATUS, (response) => {
// handle status response
});
#### Module Subscription
Get products by ids:
`typescript
const ids = ["exampple.product.id_1", "exampple.product.id_2"];
Affise.module.subscription.fetchProducts(ids, (result) => {
if (result.isSuccess) {
const value = result.asSuccess;
const products: AffiseProduct[] = value.products;
const invalidIds: string[] = value.invalidIds;
} else {
const error: string = result.asFailure;
}
});
`
Purchase product:
`typescript`
// Specify product type for correct affise event
Affise.module.subscription.purchase(product, AffiseProductType.CONSUMABLE, (result) => {
if (result.isSuccess) {
const purchasedInfo: AffisePurchasedInfo = result.asSuccess;
} else {
const error: string = result.asFailure;
}
});
Is Module present:
`typescript`
Affise.module.subscription.hasModule().then((hasModule) => {
// Check is module present
})
##### AffiseProductType
- CONSUMABLENON_CONSUMABLE
- RENEWABLE_SUBSCRIPTION
- NON_RENEWABLE_SUBSCRIPTION
-
#### Module TikTok
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> There are no official React Native TikTok package.
>
> You have to add native dependency manually.
>
> Add the Android TikTok SDK dependency TikTok Docs
>
> Add the iOS TikTok SDK dependency TikTok Docs
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
`typescript
let eventName = "AddToCart";
let eventId = "eventId";
let properties = {
"currency": "USD",
"value": 4.99,
"contents": [
{
"price": "4.99",
"quantity": "1",
"content_name": "Name of the product",
"brand": "Brand of the product"
}
],
};
// Send TikTok data to Affise
Affise.module.tikTok.sendEvent(eventName, properties, eventId);
`
Is Module present:
`typescript`
Affise.module.tikTok.hasModule().then((hasModule) => {
// Check is module present
})
After dependency is added, and project is sync with npm install and initialize.
> Demo app App.tsx
`typescript jsx
import {
Affise,
AffiseInitProperties
} from 'affise-attribution-lib';
export default function App() {
React.useEffect(() => {
Affise
.settings({
affiseAppId: 'Your appId', //Change to your app id
secretKey: 'Your SDK secretKey', //Change to your SDK secretKey
})
.start(); // Start Affise SDK
});
return (
);
}
`
#### Initialization callbacks
Check Affise library initialization
`typescriptAffise: init success
Affise
.settings({
affiseAppId: "Your appId",
secretKey: "Your SDK secretKey",
})
.setOnInitSuccess(() => {
// Called if library initialization succeeded
console.log();Affise: init error ${error}
})
.setOnInitError((error) => {
// Called if library initialization failed
console.log();`
})
.start(); // Start Affise SDK
#### Before application is published
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> Please make sure your credentials are valid
>
> Visit section validation credentials
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
#### Domain
Set SDK server domain:
`typescript`
Affise
.settings({
affiseAppId: 'Your appId',
secretKey: 'Your SDK secretKey',
})
.setDomain("https://YoureCustomDomain/") // Set custom domain
.start(); // Start Affise SDK
#### Android
Minimal Android SDK version is 21
For a minimal working functionality your app needs to declare internet permission:
`xml`
OAID certificate in your project (Optional)
example/android/app/src/main/assets/oaid.cert.pem
#### iOS
Affise Advertising module uses AppTrackingTransparency framework to get advertisingIdentifierNSUserTrackingUsageDescription
For working functionality your app needs to declare permission:
Open XCode project info.plist and add key NSUserTrackingUsageDescription with string value
Example info.plist:
`xml`
...
Some methods require to return same data on application reinstall
It is achieved by using Affise Persistent Module for iOS and Affise AndroidId Module for Android
Such SDK methods are:
To simulate multiple device install for testing purpose you can use one of two options:
1. Disable module dependencies:
iOS
`ruby`Disable module dependency
pod 'AffiseModule/Persistent', affise_version
Android
`groovy`
// Disable module dependency
// implementation("com.affise:module-androidid:$affise_version")
2. Disable module programmatically:
`typescript`
Affise
.settings({
affiseAppId: 'Your appId',
secretKey: 'Your SDK secretKey',
})
.setDisableModules([
AffiseModules.PERSISTENT, // Disable module programmatically for iOS
AffiseModules.ANDROIDID, // Disable module programmatically for Android
])
.start();
> [!NOTE]
>
> Read more about Persistent data
There are two working mode for Affice device Id:
1. Return persistent value on each reinstall
2. Return new value on each reinstall
First mode require:
- Enabling Affise Persistent Module for iOS
`ruby`Enable module dependency
pod 'AffiseModule/Persistent', affise_version
- Enabling Affise AndroidId Module for Android
`groovy`
// Enable module dependency
implementation("com.affise:module-androidid:$affise_version")
Even after deleting application Affice device Id will be preserved and will restore on next installation
Second mode is convenient for testing.
By removing dependency or disabling module programmatically, a new Affice device Id will be generated for each new installation.
To match users with events and data library is sending, these ProviderType identifiers are collected:
- AFFISE_APP_IDAFFISE_PKG_APP_NAME
- AFF_APP_NAME_DASHBOARD
- APP_VERSION
- APP_VERSION_RAW
- STORE
- TRACKER_TOKEN
- TRACKER_NAME
- FIRST_TRACKER_TOKEN
- FIRST_TRACKER_NAME
- LAST_TRACKER_TOKEN
- LAST_TRACKER_NAME
- OUTDATED_TRACKER_TOKEN
- INSTALLED_TIME
- FIRST_OPEN_TIME
- INSTALLED_HOUR
- FIRST_OPEN_HOUR
- INSTALL_FIRST_EVENT
- INSTALL_BEGIN_TIME
- INSTALL_FINISH_TIME
- REFERRER_INSTALL_VERSION
- REFERRAL_TIME
- REFERRER_CLICK_TIME
- REFERRER_CLICK_TIME_SERVER
- REFERRER_GOOGLE_PLAY_INSTANT
- CREATED_TIME
- CREATED_TIME_MILLI
- CREATED_TIME_HOUR
- UNINSTALL_TIME
- REINSTALL_TIME
- LAST_SESSION_TIME
- CPU_TYPE
- HARDWARE_NAME
- DEVICE_MANUFACTURER
- DEEPLINK_CLICK
- DEVICE_ATLAS_ID
- AFFISE_DEVICE_ID
- AFFISE_ALT_DEVICE_ID
- REFTOKEN
- REFTOKENS
- REFERRER
- USER_AGENT
- MCCODE
- MNCODE
- REGION
- COUNTRY
- LANGUAGE
- DEVICE_NAME
- DEVICE_TYPE
- OS_NAME
- PLATFORM
- SDK_PLATFORM
- API_LEVEL_OS
- AFFISE_SDK_VERSION
- OS_VERSION
- RANDOM_USER_ID
- AFFISE_SDK_POS
- TIMEZONE_DEV
- AFFISE_EVENT_NAME
- AFFISE_EVENT_TOKEN
- LAST_TIME_SESSION
- TIME_SESSION
- AFFISE_SESSION_COUNT
- LIFETIME_SESSION_COUNT
- AFFISE_DEEPLINK
- AFFISE_PART_PARAM_NAME
- AFFISE_PART_PARAM_NAME_TOKEN
- AFFISE_APP_TOKEN
- LABEL
- AFFISE_SDK_SECRET_ID
- UUID
- AFFISE_APP_OPENED
- PUSHTOKEN
- PUSHTOKEN_SERVICE
- AFFISE_EVENTS_COUNT
- AFFISE_SDK_EVENTS_COUNT
- AFFISE_METRICS_EVENTS_COUNT
- AFFISE_INTERNAL_EVENTS_COUNT
- IS_ROOTED
- IS_EMULATOR
-
- AD_SERVICE_ATTRIBUTION
- GAID_ADIDGAID_ADID_MD5
- ADID
- ALTSTR_ADID
- FIREOS_ADID
- COLOROS_ADID
-
- ANDROID_IDANDROID_ID_MD5
-
- OAIDOAID_MD5
-
- META
- MAC_SHA1MAC_MD5
- CONNECTION_TYPE
- PROXY_IP_ADDRESS
-
- NETWORK_TYPEISP
-
There are two ways to send events
1. Cache event to later scheduled send in batch
`typescript`
AddToCartEvent()
.send();
2. Send event right now
`typescript`
AddToCartEvent()
.sendNow(() => {
// handle event send success
}, (status) => {
// handle event send failed
// π₯Warningπ₯: event is NOT cached for later send
});
> Demo app DefaultEventsFactory.ts
For example, we want to track what items usually user adds to shopping cart. To send event first create it with
following code
`typescript
import { Affise, AddToCartEvent } from 'affise-attribution-lib';
class Presenter {
onUserAddsItemsToCart(item: string) {
const items = {
items: 'cookies, potato, milk',
};
new AddToCartEvent({
userData: item,
timeStampMillis: Date.now()
})
.addPredefinedString(PredefinedString.DESCRIPTION, 'groceries')
.addPredefinedObject(PredefinedObject.CONTENT, items)
.send();
}
}
`
With above example you can implement other events:
- AchieveLevelAddPaymentInfo
- AddToCart
- AddToWishlist
- AdRevenue
- ClickAdv
- CompleteRegistration
- CompleteStream
- CompleteTrial
- CompleteTutorial
- Contact
- ContentItemsView
- CustomizeProduct
- DeepLinked
- Donate
- FindLocation
- InitiateCheckout
- InitiatePurchase
- InitiateStream
- Invite
- LastAttributedTouch
- Lead
- ListView
- Login
- OpenedFromPushNotification
- Order
- OrderItemAdded
- OrderItemRemove
- OrderCancel
- OrderReturnRequest
- OrderReturnRequestCancel
- Purchase
- Rate
- ReEngage
- Reserve
- Sales
- Schedule
- Search
- Share
- SpendCredits
- StartRegistration
- StartTrial
- StartTutorial
- SubmitApplication
- Subscribe
- TravelBooking
- UnlockAchievement
- Unsubscribe
- Update
- ViewAdv
- ViewCart
- ViewContent
- ViewItem
- ViewItems
- InitialSubscription
- InitialTrial
- InitialOffer
- ConvertedTrial
- ConvertedOffer
- TrialInRetry
- OfferInRetry
- SubscriptionInRetry
- RenewedSubscription
- FailedSubscriptionFromRetry
- FailedOfferFromRetry
- FailedTrialFromRetry
- FailedSubscription
- FailedOfferise
- FailedTrial
- ReactivatedSubscription
- RenewedSubscriptionFromRetry
- ConvertedOfferFromRetry
- ConvertedTrialFromRetry
- Unsubscription
-
Use any of custom events if default doesn't fit your scenario:
- CustomId01CustomId02
- CustomId03
- CustomId04
- CustomId05
- CustomId06
- CustomId07
- CustomId08
- CustomId09
- CustomId10
-
If above event functionality still limits your usecase, you can use UserCustomEvent
`typescript`
new UserCustomEvent({eventName: "MyCustomEvent"})
.send();
To enrich your event with another dimension, you can use predefined parameters for most common cases.
Add it to any event:
`typescript
import {
Affise,
AddToCartEvent,
PredefinedString,
PredefinedObject,
} from 'affise-attribution-lib';
class Presenter {
onUserAddsItemsToCart(item: string) {
const items = {
items: 'cookies, potato, milk',
};
new AddToCartEvent({
userData: item,
})
.addPredefinedString(PredefinedString.DESCRIPTION, 'best before 2029')
.addPredefinedObject(PredefinedObject.CONTENT, items)
.send();
}
}
`
In examples above PredefinedString.DESCRIPTION and PredefinedObject.CONTENT is used, but many others is available:
| PredefinedParameter | Type |
|-----------------------------------------------|--------------------------------------------|
| PredefinedString | string |
| PredefinedLong | bigint |
| PredefinedFloat | number |
| PredefinedObject | Record<string, unknown> |
| PredefinedListObject | Array<Record<string, unknown>> |
| PredefinedListString | Array<string> |
- ACHIEVEMENT_IDADREV_AD_TYPE
- BRAND
- BRICK
- CAMPAIGN_ID
- CATALOGUE_ID
- CHANNEL_TYPE
- CITY
- CLASS
- CLICK_ID
- CONTENT_ID
- CONTENT_NAME
- CONTENT_TYPE
- CONVERSION_ID
- COUNTRY
- COUPON_CODE
- CURRENCY
- CUSTOMER_SEGMENT
- CUSTOMER_TYPE
- CUSTOMER_USER_ID
- DEEP_LINK
- DESCRIPTION
- DESTINATION_A
- DESTINATION_B
- DESTINATION_LIST
- EVENT_NAME
- NEW_VERSION
- NETWORK
- OLD_VERSION
- ORDER_ID
- PARAM_01
- PARAM_02
- PARAM_03
- PARAM_04
- PARAM_05
- PARAM_06
- PARAM_07
- PARAM_08
- PARAM_09
- PARAM_10
- PAYMENT_INFO_AVAILABLE
- PID
- PLACEMENT
- PREFERRED_NEIGHBORHOODS
- PRODUCT_ID
- PRODUCT_NAME
- PURCHASE_CURRENCY
- RECEIPT_ID
- REGION
- REGISTRATION_METHOD
- REVIEW_TEXT
- SEARCH_STRING
- SEGMENT
- SOURCE
- STATUS
- SUBSCRIPTION_ID
- SUCCESS
- SUGGESTED_DESTINATIONS
- SUGGESTED_HOTELS
- TUTORIAL_ID
- UNIT
- UTM_CAMPAIGN
- UTM_MEDIUM
- UTM_SOURCE
- VALIDATED
- VERTICAL
- VIRTUAL_CURRENCY_NAME
- VOUCHER_CODE
-
- AMOUNTDATE_A
- DATE_B
- DEPARTING_ARRIVAL_DATE
- DEPARTING_DEPARTURE_DATE
- HOTEL_SCORE
- LEVEL
- MAX_RATING_VALUE
- NUM_ADULTS
- NUM_CHILDREN
- NUM_INFANTS
- PREFERRED_NUM_STOPS
- PREFERRED_STAR_RATINGS
- QUANTITY
- RATING_VALUE
- RETURNING_ARRIVAL_DATE
- RETURNING_DEPARTURE_DATE
- SCORE
- TRAVEL_START
- TRAVEL_END
- USER_SCORE
- EVENT_START
- EVENT_END
-
- PREFERRED_PRICE_RANGEPRICE
- REVENUE
- LAT
- LONG
-
- CONTENT
- CONTENT_LIST
- CONTENT_IDS
Affise library will send any pending events with first opportunity,
but if there is no network connection or device is disabled, events are kept locally for 7 days before deletion.
> [!NOTE]
>
> Requires Affise Advertising Module
Advertising Identifier (google) tracking is supported automatically, no actions needed
> [!NOTE]
>
> Requires Affise Huawei Module
Open Advertising Identifier is supported automatically, no actions needed
Install referrer tracking is supported automatically, no actions needed
To let affise track push token you need to receive it from your push service provider, and pass to Affise library.
Supported service providers:
- APPLE - iOS onlyFIREBASE
-
#### iOS APNs
For swift edit AppDelegate.swift`swift
import AffiseAttributionLib
class AppDelegate ... {
...
override func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let pushToken = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
// Pass APNs token to Affise
Affise.addPushToken(pushToken, .APPLE)
}
}
`
For Objective-C edit AppDelegate.mm
`objective-c
#import
- (void)application:(UIApplication)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData)devToken
{
// parse token bytes to string
const char data = (char )[devToken bytes];
NSMutableString *token = [NSMutableString string];
for (NSUInteger i = 0; i < [devToken length]; i++)
{
[token appendFormat:@"%02.2hhX", data[i]];
}
[Affise addPushTokenWithPushToken:[token copy] service:APPLE];
}
`
@react-native-firebase/app
@react-native-firebase/messaging
Add Firebase integration by completing steps in React Native Firebase Docs
After you have done with firebase integration, setup Messaging
`typescript
import { Affise, PushTokenService } from 'affise-attribution-lib';
import firebase from '@react-native-firebase/app';
import messaging from '@react-native-firebase/messaging';
async function firebaseSetup() {
const credentials = {
appId: '',
projectId: '',
// ...
};
await firebase.initializeApp(credentials);
}
function getToken() {
messaging().getToken().then((fcmToken) => {
Affise.addPushToken(fcmToken, PushTokenService.FIREBASE);
});
}
`
#### iOS APNs
After you have done with firebase integration, get APNs token from firebase
`typescript
import { Affise, PushTokenService } from 'affise-attribution-lib';
import { Platform } from 'react-native';
import messaging from '@react-native-firebase/messaging';
function getToken() {
if (Platform.OS == 'ios') {
messaging().getAPNSToken().then((apnsToken) => {
if (!apnsToken) return
Affise.addPushToken(apnsToken, PushTokenService.APPLE);
});
}
}
`
Affise automatically track reinstall events by using silent-push technology, to make this feature work, pass push token when it is recreated by user and on you application starts up
`typescript`
Affise.addPushToken(token);
SDK is also supports scenario when APK is installed not from one of application markets, such as google play, huawei appgallery or amazon appstore
To use this feature, create file with name partner_key in your app assets directory, and write unique identifier inside, this key will be passed to our backend so you can track events by partner later in your Affise console.
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> Deeplinks support only CUSTOM scheme NOT http or httpshttp
>
> For or https read how to setup AppLinks
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
To integrate deeplink support you need:
- Follow how to set up deeplinks for Android or iOS
- Register deeplink callback right after Affise.settings({affiseAppId, secretKey}).start()
`typescript
Affise.registerDeeplinkCallback((value) => {
// full uri "scheme://host/path?parameters"
const deeplink = value.deeplink;
// separated for convenience
const scheme = value.scheme;
const host = value.host;
const path = value.path;
const queryParametersMap = value.parameters;
if((queryParametersMap["
// handle value
}
});
`
Test Android DeepLink via terminal command:
`terminal`
adb shell am start -a android.intent.action.VIEW -d "YOUR_SCHEME://YOUR_DOMAIN/somepath?param=1\&list=some\&list=other\&list="
Test iOS DeepLink via terminal command:
`terminal`
xcrun simctl openurl booted "YOUR_SCHEME://YOUR_DOMAIN/somepath?param=1&list=some&list=other&list=1"
#### Android
To integrate deeplink support in android you need:
- Add intent filter to one of your activities AndroidManifest.xml example
- Add custom scheme (NOT http or https) and host to filter
Example: YOUR_SCHEME://YOUR_DOMAIN
Example: myapp://mydomain.com
`xml
android:host="YOUR_DOMAIN"
android:scheme="YOUR_SCHEME" />
`
#### iOS
To integrate deeplink support in iOS you need:
- Add deeplink handler React Docs. example AppDelegate.mm
`objective-c`
- (BOOL)application:(UIApplication )application openURL:(NSURL )url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
- Add key CFBundleURLTypes to Info.plist example Info.plist
Example: YOUR_SCHEME://YOUR_DOMAIN
Example: myapp://mydomain.com
`xml`
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> You must owne website domain.
>
> And has ability to add file https://yoursite/.well-known/apple-app-site-association for iOS supporthttps://yoursite/.well-known/assetlinks.json
>
> And has ability to add file for Android support
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
- Follow how to set up AppLinks for Android or iOS
#### Android
To integrate applink support in android you need:
- Add intent filter to one of your activities AndroidManifest.xml example
- Add https or http scheme and host to filter
Example: https://YOUR_DOMAIN
Example: https://mydomain.com
`xml
android:host="YOUR_DOMAIN"
android:scheme="https" />
`
- Associate your app with your website. Read Google instructions
How To Associate your app with your website
---
After setting up URL support for your app, the App Links Assistant generates a Digital Assets Links file you can use to associate your website with your app.
As an alternative to using the Digital Asset Links file, you can associate your site and app in Search Console.
If you're using Play App Signing for your app, then the certificate fingerprint produced by the App Links Assistant usually doesn't match the one on users' devices. In this case, you can find the correct Digital Asset Links JSON snippet for your app in your Play Console developer account under Release > Setup > App signing.
To associate your app and your website using the App Links Assistant, click Open Digital Asset Links File Generator from the App Links Assistant and follow these steps:
!app-links-assistant-dal-file-generator_2x
Figure 2. Enter details about your site and app to generate a Digital Asset Links file.
1. Enter your Site domain and your Application ID.
2. To include support in your Digital Asset Links file for One Tap sign-in, select Support sharing credentials between the app and the website and enter your site's sign-in URL.This adds the following string to your Digital Asset Links file declaring that your app and website share sign-in credentials: delegate_permission/common.get_login_creds.
3. Specify the signing config or select a keystore file.
Make sure you select the right release config or keystore file for the release build or the debug config or keystore file for the debug build of your app. If you want to set up your production build, use the release config. If you want to test your build, use the debug config.
4. Click Generate Digital Asset Links file.
5. Once Android Studio generates the file, click Save file to download it.
6. Upload the assetlinks.json file to your site, with read access for everyone, at https://yoursite/.well-known/assetlinks.json.
> [!CAUTION]
>
> The system verifies the Digital Asset Links file via the encrypted HTTPS protocol. Make sure that the assetlinks.json file is accessible over an HTTPS connection, regardless of whether your app's intent filter includes https.
7. Click Link and Verify to confirm that you've uploaded the correct Digital Asset Links file to the correct location.
Learn more about associating your website with your app through the Digital Asset Links file in Declare website associations.
---
#### iOS
To integrate deeplink support in iOS you need:
- Follow how to set up applink in the official documentation.
- Associate your app with your website. Supporting associated domains
- Configuring an associated domain
- Add key com.apple.developer.associated-domains to Info.plist
Example: https://YOUR_DOMAIN
Example: https://mydomain.com
`xml`
> [!NOTE]
>
> Requires Affise Status Module
Use the next public method of SDK to get deferred deeplink from server
`typescript`
Affise.getDeferredDeeplink((deferredDeeplink) => {
// handle deferred deeplink
});
> [!NOTE]
>
> Requires Affise Status Module
Use the next public method of SDK to get deferred deeplink value from server
`typescript`
Affise.getDeferredDeeplinkValue(ReferrerKey.CLICK_ID, (deferredDeeplinkValue) => {
// handle deferred deeplink value
})
In some scenarios you would want to limit Affise network usage, to pause that activity call anywhere in your application following code after Affise start:
`typescript`
Affise.settings({affiseAppId, secretKey}).start(); // Start Affise SDK
Affise.setOfflineModeEnabled(true); // to enable offline mode
Affise.setOfflineModeEnabled(false); // to disable offline mode
While offline mode is enabled, your metrics and other events are kept locally, and will be delivered once offline mode is disabled.
Offline mode is persistent as Application lifecycle, and will be disabled with process termination automatically.
To check current offline mode status call:
`typescript`
Affise.isOfflineModeEnabled().then((enabled) => {
// returns true or false describing current offline Mode state
});
To disable any tracking activity, storing events and gathering device identifiers and metrics call anywhere in your application following code after Affise start:
`typescript`
Affise.settings({affiseAppId, secretKey}).start(); // Start Affise SDK
Affise.setTrackingEnabled(true); // to enable tracking
Affise.setTrackingEnabled(false); // to disable tracking
By default, tracking is enabled.
While tracking mode is disabled, metrics and other identifiers is not generated locally.
Keep in mind that this flag is persistent until app reinstall, and don't forget to reactivate tracking when needed.
To check current status of tracking call:
`typescript`
Affise.isTrackingEnabled().then((enabled) => {
// returns true or false describing current tracking state
});
To disable any background tracking activity, storing events and gathering device identifiers and metrics call anywhere in your application following code after Affise start:
`typescript`
Affise.settings({affiseAppId, secretKey}).start(); // Start Affise SDK
Affise.setBackgroundTrackingEnabled(true); // to enable background tracking
Affise.setBackgroundTrackingEnabled(false); // to disable background tracking
By default, background tracking is enabled.
While background tracking mode is disabled, metrics and other identifiers is not generated locally.
Background tracking mode is persistent as Application lifecycle, and will be re-enabled with process termination automatically.
To check current status of background tracking call:
`typescript`
Affise.isBackgroundTrackingEnabled().then((enabled) => {
// returns true or false describing current background tracking state
});
`typescript`
Affise.getRandomUserId();
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> Return 11111111-1111-1111-1111-111111111111 if Affise SDK not initialized22222222-2222-2222-2222-222222222222
>
> Return if no valid methods to retrieve id for current deviceAffiseError.UUID_NOT_INITIALIZED
>
> == 11111111-1111-1111-1111-111111111111AffiseError.UUID_NO_VALID_METHOD
>
> == 22222222-2222-2222-2222-222222222222
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
> [!NOTE]
>
> To make device id more persistent on application reinstallPersistent
>
> use Affise Module for iOSAndroidId
>
> use Affise Module for Android
> [!NOTE]
>
> Read more about Persistent data and Reinstall tracking
`typescript`
Affise.getRandomDeviceId();
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> Return 11111111-1111-1111-1111-111111111111 if Affise SDK not initialized22222222-2222-2222-2222-222222222222
>
> Return if no valid methods to retrieve id for current deviceAffiseError.UUID_NOT_INITIALIZED
>
> == 11111111-1111-1111-1111-111111111111AffiseError.UUID_NO_VALID_METHOD
>
> == 22222222-2222-2222-2222-222222222222
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Returns providers map with ProviderType as key
As Promise:
`typescript`
Affise.getProviders().then((providers) => {
const key = ProviderType.AFFISE_APP_TOKEN;
const value = providers[key];
// handle provider value
});
As async / await:
`typescript
const fetchData = async () => {
const providers = await Affise.getProviders();
const key = ProviderType.AFFISE_APP_TOKEN;
const value = providers[key];
// handle provider value
};
fetchData()
.catch(console.error);
`
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> Return Empty Map if Affise SDK not initialized
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
`typescript`
Affise.isFirstRun().then((isFirstRun) => {
// handle
});
Use the next public method of SDK
> To get Install referrer by installing from Android RuStore include module RuStore
> To get Install referrer by installing from Android AppGallery include module Huawei
`typescript`
Affise.getReferrerUrl().then((referrer) => {
// handle referrer
});
Use the next public method of SDK to get referrer value by
> To get Install referrer by installing from Android RuStore include module RuStore
> To get Install referrer by installing from Android AppGallery include module Huawei
`typescript`
Affise.getReferrerUrlValue(ReferrerKey.CLICK_ID, (value) => {
// handle referrer
})
In examples above ReferrerKey.CLICK_ID is used, but many others is available:
- AD_IDCAMPAIGN_ID
- CLICK_ID
- AFFISE_AD
- AFFISE_AD_ID
- AFFISE_AD_TYPE
- AFFISE_ADSET
- AFFISE_ADSET_ID
- AFFISE_AFFC_ID
- AFFISE_CHANNEL
- AFFISE_CLICK_LOOK_BACK
- AFFISE_COST_CURRENCY
- AFFISE_COST_MODEL
- AFFISE_COST_VALUE
- AFFISE_DEEPLINK
- AFFISE_KEYWORDS
- AFFISE_MEDIA_TYPE
- AFFISE_MODEL
- AFFISE_OS
- AFFISE_PARTNER
- AFFISE_REF
- AFFISE_SITE_ID
- AFFISE_SUB_SITE_ID
- AFFISE_SUB_1
- AFFISE_SUB_2
- AFFISE_SUB_3
- AFFISE_SUB_4
- AFFISE_SUB_5
- AFFC
- PID
- SUB_1
- SUB_2
- SUB_3
- SUB_4
- SUB_5
-
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> If getStatus return an error or working more than 2 minutes
>
> Please see section validation credentials
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
`typescript`
Affise.module.getStatus(AffiseModules.STATUS, (response) => {
// handle status response
});
> Android Only
Under the EU's General Data Protection Regulation (GDPR): An individual has the right to have their personal data erased.
To provide this functionality to user, as the app developer, you can call
`typescript`
Affise.settings({affiseAppId, secretKey}).start(); // Start Affise SDK
Affise.android.forget(); // to forget users data
After processing such request our backend servers will delete all user's data.
To prevent library from generating new events, disable tracking just before calling Affise.forget:
`typescript`
Affise.settings({affiseAppId, secretKey}).start(); // Start Affise SDK
Affise.setTrackingEnabled(false);
Affise.android.forget(); // to forget users data
> iOS Only
For ios prior 16.1 first call
`typescript`
Affise.ios.registerAppForAdNetworkAttribution((error) => {
// Handle error
});
Updates the fine and coarse conversion values, and calls a completion handler if the update fails.
Second argument coarseValue is available in iOS 16.1+
`typescript`
Affise.ios.updatePostbackConversionValue(1n, SKAdNetwork.CoarseConversionValue.medium, (error) => {
// Handle error
});
Configure your app to send postback copies to Affise:
Add key NSAdvertisingAttributionReportEndpoint to Info.plisthttps://affise-skadnetwork.com/
Set key value to
Example: example/ios/AffiseAttributionLibExample/Info.plist
`xml`
`typescript`
// Send AdRevenue info
new AffiseAdRevenue(AffiseAdSource.ADMOB)
.setRevenue(2.5, "ImpressionData_Currency")
.setNetwork("ImpressionData_Network")
.setUnit("ImpressionData_Unit")
.setPlacement("ImpressionData_Placement")
.send();
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> Debug methods WON'T work on Production
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Validate your credentials by receiving ValidationStatus values:
- VALID - your credentials are validINVALID_APP_ID
- - your app id is not validINVALID_SECRET_KEY
- - your SDK secretKey is not validPACKAGE_NAME_NOT_FOUND
- - your application package name not foundNOT_WORKING_ON_PRODUCTION
- - you using debug method on productionNETWORK_ERROR
- - network or server not available (for example Airoplane mode is active)
`typescript
Affise
.settings({
affiseAppId: 'Your appId',
secretKey: 'Your SDK secretKey',
})
.setProduction(false) //To enable debug methods set Production to false
.start(); // Start Affise SDK
Affise.debug.validate((status) =>
{
// Handle validation status
});
`
Get Affise flutter library version
`typescript`
Affise.debug.version()
Get Affise native Android/iOS library version
`typescript`
Affise.debug.versionNative().then((version) => {
// Native version
});
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> If Affise settings doesn't change after version update or api is working incorrectly.
>
> First: try reset cache for React Native. npm start -- --reset-cache or npm cache clean --forceReact Native
>
> Second: completely stop application on device and stop Metro serverJavaScript
>
> React Native relaunch /TypeScript on live code change,
> but native code (such as Affise native library) won't restart
> unless Android application is manually restarted or completely rebuild
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
> [!NOTE]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> Then reporting a BUG
>
> Please provide information:
>
> 1. From command npx react-native doctornpx react-native info
>
> 2. From command iOS
>
> 3. On which platform bug occurred or Android
>
> 4. Detailed log of a bug
>
> 5. Steps to reproduse a bug
>
> 6. Code which cause a bug
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
> [!CAUTION]
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
>
> This app has crashed because Affise Advertising Module is attempted to access privacy-sensitive data without a usage description.
>
> The app's Info.plist must contain an NSUserTrackingUsageDescription key with a string value explaining
>
> to the user how the app uses this data.
>
> π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Open info.plist and add key NSUserTrackingUsageDescription` with string value. For more information read requirements