adjust归因

This commit is contained in:
玉峰 2025-08-30 18:46:34 +08:00
parent 8a11506a78
commit 9e1dd78d95
103 changed files with 10106 additions and 4 deletions

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
</manifest>

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 147d3bb1ca0da2b448667eec3a82bb26
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -833,6 +833,8 @@ GameObject:
- component: {fileID: 2137923634}
- component: {fileID: 2137923635}
- component: {fileID: 2137923636}
- component: {fileID: 2137923637}
- component: {fileID: 2137923638}
m_Layer: 0
m_Name: '[SDKManager]'
m_TagString: Untagged
@ -880,6 +882,30 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: a550f9677d329f940876ee3d139f8289, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &2137923637
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2137923633}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5019ae7cf0c6d3d4c89b8921e4beab15, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &2137923638
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2137923633}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f925ec84be5d37d4ba2ee62fc7ffb464, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7612045c73134949a914f701ff109389
timeCreated: 1756549078

View File

@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
using AdjustSdk;
using Unity.VisualScripting;
using UnityEngine;
public class AdjustManager : MonoBehaviour
{
private string appToken = "你的App Token"; // 替换为你的实际App Token
private AdjustEnvironment environment = AdjustEnvironment.Sandbox; // 测试用Sandbox发布用Production
public void Awake()
{
AdjustConfig config = new AdjustConfig(appToken, environment);
// 设置归因变更回调函数
config.AttributionChangedDelegate = AttributionChangedDelegate;
// (可选)设置其他配置,如日志级别
config.LogLevel = AdjustLogLevel.Verbose;
// 初始化Adjust SDK
Adjust.InitSdk(config);
}
/// <summary>
/// 归因信息
/// </summary>
/// <param name="attribution"></param>
private void AttributionChangedDelegate(AdjustAttribution attribution)
{
Debug.Log("Attribution changed");
AdjustNetwork.SetNetwork(attribution.Network);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f925ec84be5d37d4ba2ee62fc7ffb464
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,48 @@
using UnityEngine;
public static class AdjustNetwork
{
private const string KEY_USER_NETWORK = "KEY_USER_NETWORK";
public static void SetNetwork(string network)
{
if (string.IsNullOrEmpty(network))
{
return;
}
if (network.ToLower().Replace(" ", "") == "Organic".ToLower().Replace(" ", ""))
{
return;
}
string curNetwork = PlayerPrefs.GetString(KEY_USER_NETWORK, "");
if (string.IsNullOrEmpty(curNetwork))
{
PlayerPrefs.SetString(KEY_USER_NETWORK, network);
PlayerPrefs.Save();
}
}
/// <summary>
/// 是否是自然量用户
/// 默认买量用户
/// </summary>
/// <returns></returns>
public static bool InOrganic()
{
string network = PlayerPrefs.GetString(KEY_USER_NETWORK, "");
if (string.IsNullOrEmpty(network))
{
return true;
}
//去除大小写和空格之后再对比
if (network.ToLower().Replace(" ", "") == "Untrusted Devices".ToLower().Replace(" ", "") || network.ToLower().Replace(" ", "") == "Google Organic Search".ToLower().Replace(" ", ""))
{
return true;
}
return false;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9292edbac2294418af38b6f95a185127
timeCreated: 1756550070

8
Assets/rd3/Adjust.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b7941c48bfc3e44aea0300ced4d12b47
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 48d8fb88fe43540d48dd33b18a151507
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 99903aebed26d46a2aa9f9aa2b17a339
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"/>
<!-- Permissions needed by the Adjust SDK. -->
<!-- For more information, check: https://github.com/adjust/unity_sdk#post-build-android -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
<queries>
<package android:name="com.facebook.katana" />
</queries>
<queries>
<package android:name="com.instagram.android" />
</queries>
<application
android:theme="@style/UnityThemeSelector"
android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:debuggable="true">
<!-- Adjust broadcast receiver used to capture referrer content from INSTALL_REFERRER intent. -->
<receiver
android:name="com.adjust.sdk.AdjustReferrerReceiver"
android:permission="android.permission.INSTALL_PACKAGES"
android:exported="true" >
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<activity
android:name="com.unity3d.player.UnityPlayerActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application>
</manifest>

View File

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: a13ef442648c346a79f9ff24875c037a
TextScriptImporter:
userData:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c11a8a7fc7bfd4937bac95b31f1fb273
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<androidPackages>
<androidPackage spec="com.adjust.sdk:adjust-android:5.4.2">
</androidPackage>
<androidPackage spec="com.android.installreferrer:installreferrer:2.2">
</androidPackage>
</androidPackages>
<iosPods>
<iosPod name="Adjust" version="5.4.3" minTargetSdk="12.0"/>
</iosPods>
</dependencies>

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d4241857b233d46ee874c8f80bb65fdb
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c8400ff077d6c4583b0f85a46cd1d50b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,37 @@
//
// AdjustUnity.h
// Adjust SDK
//
// Created by Pedro Silva (@nonelse) on 27th March 2014.
// Copyright © 2012-2018 Adjust GmbH. All rights reserved.
//
/**
* @brief The main interface to Adjust Unity bridge.
*/
@interface AdjustUnity : NSObject
// app callbacks as method parameters
typedef void (*AdjustDelegateIsEnabledGetter)(bool isEnabled);
typedef void (*AdjustDelegateAttributionGetter)(const char* attribution);
typedef void (*AdjustDelegateAdidGetter)(const char* adid);
typedef void (*AdjustDelegateIdfaGetter)(const char* idfa);
typedef void (*AdjustDelegateIdfvGetter)(const char* idfv);
typedef void (*AdjustDelegateLastDeeplinkGetter)(const char* lastDeeplink);
typedef void (*AdjustDelegateSdkVersionGetter)(const char* sdkVersion);
typedef void (*AdjustDelegateAttCallback)(int status);
typedef void (*AdjustDelegatePurchaseVerificationCallback)(const char* verificationResult, int callbackId);
typedef void (*AdjustDelegateVerifyAndTrackCallback)(const char* verificationResult, int callbackId);
typedef void (*AdjustDelegateResolvedDeeplinkCallback)(const char* deeplink);
typedef void (*AdjustDelegateSkanErrorCallback)(const char* error);
// app callbacks as subscriptions
typedef void (*AdjustDelegateAttributionCallback)(const char* attribution);
typedef void (*AdjustDelegateSessionSuccessCallback)(const char* sessionSuccess);
typedef void (*AdjustDelegateSessionFailureCallback)(const char* sessionFailure);
typedef void (*AdjustDelegateEventSuccessCallback)(const char* eventSuccess);
typedef void (*AdjustDelegateEventFailureCallback)(const char* eventFailure);
typedef void (*AdjustDelegateDeferredDeeplinkCallback)(const char* deeplink);
typedef void (*AdjustDelegateSkanUpdatedCallback)(const char* skanData);
@end

View File

@ -0,0 +1,110 @@
fileFormatVersion: 2
guid: 9ffff8839c6ab418b983add4c597fb87
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
Exclude tvOS: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: None
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
iPhone: iOS
second:
enabled: 1
settings:
CompileFlags:
FrameworkDependencies:
- first:
tvOS: tvOS
second:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,929 @@
//
// AdjustUnity.mm
// Adjust SDK
//
// Created by Pedro Silva (@nonelse) on 27th March 2014.
// Copyright © 2012-2018 Adjust GmbH. All rights reserved.
//
#import <AdjustSdk/AdjustSdk.h>
#import "AdjustUnity.h"
#import "AdjustUnityDelegate.h"
#import "AdjustUnityAppDelegate.h"
@implementation AdjustUnity
#pragma mark - Object lifecycle methods
+ (void)load {
// swizzle AppDelegate on the load
// it should be done as early as possible
[AdjustUnityAppDelegate swizzleAppDelegateCallbacks];
}
@end
#pragma mark - Helper C methods
// method for converting JSON stirng parameters into NSArray object
NSArray* convertArrayParameters(const char* cStringJsonArrayParameters) {
if (cStringJsonArrayParameters == NULL) {
return nil;
}
NSError *error = nil;
NSArray *arrayParameters = nil;
NSString *stringJsonArrayParameters = [NSString stringWithUTF8String:cStringJsonArrayParameters];
if (stringJsonArrayParameters != nil) {
NSData *dataJson = [stringJsonArrayParameters dataUsingEncoding:NSUTF8StringEncoding];
arrayParameters = [NSJSONSerialization JSONObjectWithData:dataJson options:0 error:&error];
}
if (error != nil) {
NSString *errorMessage = @"Failed to parse json parameters!";
NSLog(@"%@", errorMessage);
}
return arrayParameters;
}
BOOL isStringValid(const char* cString) {
if (cString == NULL) {
return false;
}
NSString *objcString = [NSString stringWithUTF8String:cString];
if (objcString == nil) {
return false;
}
if ([objcString isEqualToString:@"ADJ_INVALID"]) {
return false;
}
return true;
}
void addValueOrEmpty(NSMutableDictionary *dictionary, NSString *key, NSObject *value) {
if (nil != value) {
if ([value isKindOfClass:[NSString class]]) {
[dictionary setObject:[NSString stringWithFormat:@"%@", value] forKey:key];
} else if ([value isKindOfClass:[NSNumber class]]) {
[dictionary setObject:[NSString stringWithFormat:@"%@", [((NSNumber *)value) stringValue]] forKey:key];
} else {
[dictionary setObject:@"" forKey:key];
}
} else {
[dictionary setObject:@"" forKey:key];
}
}
#pragma mark - Publicly available C methods
extern "C"
{
void _AdjustInitSdk(
const char* appToken,
const char* environment,
const char* sdkPrefix,
const char* defaultTracker,
const char* externalDeviceId,
const char* jsonUrlStrategyDomains,
const char* storeName,
const char* storeAppId,
int allowSuppressLogLevel,
int logLevel,
int attConsentWaitingInterval,
int eventDeduplicationIdsMaxSize,
int shouldUseSubdomains,
int isCoppaComplianceEnabled,
int isDataResidency,
int isSendingInBackgroundEnabled,
int isAdServicesEnabled,
int isIdfaReadingEnabled,
int isIdfvReadingEnabled,
int isSkanAttributionEnabled,
int isLinkMeEnabled,
int isCostDataInAttributionEnabled,
int isDeviceIdsReadingOnceEnabled,
int isAppTrackingTransparencyUsageEnabled,
int isFirstSessionDelayEnabled,
int isDeferredDeeplinkOpeningEnabled,
AdjustDelegateAttributionCallback attributionCallback,
AdjustDelegateEventSuccessCallback eventSuccessCallback,
AdjustDelegateEventFailureCallback eventFailureCallback,
AdjustDelegateSessionSuccessCallback sessionSuccessCallback,
AdjustDelegateSessionFailureCallback sessionFailureCallback,
AdjustDelegateDeferredDeeplinkCallback deferredDeeplinkCallback,
AdjustDelegateSkanUpdatedCallback skanUpdatedCallback) {
NSString *strAppToken = isStringValid(appToken) == true ? [NSString stringWithUTF8String:appToken] : nil;
NSString *strEnvironment = isStringValid(environment) == true ? [NSString stringWithUTF8String:environment] : nil;
NSString *strSdkPrefix = isStringValid(sdkPrefix) == true ? [NSString stringWithUTF8String:sdkPrefix] : nil;
NSString *strDefaultTracker = isStringValid(defaultTracker) == true ? [NSString stringWithUTF8String:defaultTracker] : nil;
NSString *strExternalDeviceId = isStringValid(externalDeviceId) == true ? [NSString stringWithUTF8String:externalDeviceId] : nil;
NSString *strStoreName = isStringValid(storeName) == true ? [NSString stringWithUTF8String:storeName] : nil;
NSString *strStoreAppId = isStringValid(storeAppId) == true ? [NSString stringWithUTF8String:storeAppId] : nil;
ADJConfig *adjustConfig;
if (allowSuppressLogLevel != -1) {
adjustConfig = [[ADJConfig alloc] initWithAppToken:strAppToken
environment:strEnvironment
suppressLogLevel:(BOOL)allowSuppressLogLevel];
} else {
adjustConfig = [[ADJConfig alloc] initWithAppToken:strAppToken
environment:strEnvironment];
}
// set SDK prefix
[adjustConfig setSdkPrefix:strSdkPrefix];
// check if user has selected to implement any of the callbacks
if (attributionCallback != nil ||
sessionSuccessCallback != nil ||
sessionFailureCallback != nil ||
eventSuccessCallback != nil ||
eventFailureCallback != nil ||
deferredDeeplinkCallback != nil ||
skanUpdatedCallback != nil) {
[adjustConfig setDelegate:
[AdjustUnityDelegate getInstanceWithAttributionCallback:attributionCallback
eventSuccessCallback:eventSuccessCallback
eventFailureCallback:eventFailureCallback
sessionSuccessCallback:sessionSuccessCallback
sessionFailureCallback:sessionFailureCallback
deferredDeeplinkCallback:deferredDeeplinkCallback
skanUpdatedCallback:skanUpdatedCallback
shouldLaunchDeferredDeeplink:isDeferredDeeplinkOpeningEnabled]];
}
// log level
if (logLevel != -1) {
[adjustConfig setLogLevel:(ADJLogLevel)logLevel];
}
// COPPA compliance.
if (isCoppaComplianceEnabled != -1) {
if ((BOOL)isCoppaComplianceEnabled == YES) {
[adjustConfig enableCoppaCompliance];
}
}
// Send in background.
if (isSendingInBackgroundEnabled != -1) {
if ((BOOL)isSendingInBackgroundEnabled == YES) {
[adjustConfig enableSendingInBackground];
}
}
// AdServices.framework handling
if (isAdServicesEnabled != -1) {
if ((BOOL)isAdServicesEnabled == NO) {
[adjustConfig disableAdServices];
}
}
// SKAN attribution
if (isSkanAttributionEnabled != -1) {
if ((BOOL)isSkanAttributionEnabled == NO) {
[adjustConfig disableSkanAttribution];
}
}
// IDFA reading
if (isIdfaReadingEnabled != -1) {
if ((BOOL)isIdfaReadingEnabled == NO) {
[adjustConfig disableIdfaReading];
}
}
// IDFV reading
if (isIdfvReadingEnabled != -1) {
if ((BOOL)isIdfvReadingEnabled == NO) {
[adjustConfig disableIdfvReading];
}
}
// LinkMe
if (isLinkMeEnabled != -1) {
if ((BOOL)isLinkMeEnabled == YES) {
[adjustConfig enableLinkMe];
}
}
// ATT dialog delay
if (attConsentWaitingInterval != -1) {
[adjustConfig setAttConsentWaitingInterval:attConsentWaitingInterval];
}
// disable AppTrackingTransparency.framework interaction
if (isAppTrackingTransparencyUsageEnabled != -1) {
if ((BOOL)isAppTrackingTransparencyUsageEnabled == NO) {
[adjustConfig disableAppTrackingTransparencyUsage];
}
}
// first session delay
if (isFirstSessionDelayEnabled != -1) {
if ((BOOL)isFirstSessionDelayEnabled == YES) {
[adjustConfig enableFirstSessionDelay];
}
}
// deduplication IDs max number
if (eventDeduplicationIdsMaxSize != -1) {
[adjustConfig setEventDeduplicationIdsMaxSize:eventDeduplicationIdsMaxSize];
}
// cost data in attribution callback
if (isCostDataInAttributionEnabled != -1) {
if ((BOOL)isCostDataInAttributionEnabled == YES) {
[adjustConfig enableCostDataInAttribution];
}
}
// read device info only once
if (isDeviceIdsReadingOnceEnabled != -1) {
if ((BOOL)isDeviceIdsReadingOnceEnabled == YES) {
[adjustConfig enableDeviceIdsReadingOnce];
}
}
// default tracker
if (strDefaultTracker != nil) {
[adjustConfig setDefaultTracker:strDefaultTracker];
}
// external device identifier
if (strExternalDeviceId != nil) {
[adjustConfig setExternalDeviceId:strExternalDeviceId];
}
// URL strategy
if (shouldUseSubdomains != -1 && isDataResidency != -1) {
NSArray *urlStrategyDomains = convertArrayParameters(jsonUrlStrategyDomains);
if (urlStrategyDomains != nil) {
[adjustConfig setUrlStrategy:urlStrategyDomains
useSubdomains:(BOOL)shouldUseSubdomains
isDataResidency:(BOOL)isDataResidency];
}
}
// custom store
if (strStoreName != nil) {
ADJStoreInfo *storeInfo = [[ADJStoreInfo alloc] initWithStoreName:strStoreName];
if (strStoreAppId != nil) {
[storeInfo setStoreAppId:strStoreAppId];
}
[adjustConfig setStoreInfo:storeInfo];
}
// initialize the SDK
[Adjust initSdk:adjustConfig];
}
void _AdjustTrackEvent(const char* eventToken,
double revenue,
const char* currency,
const char* productId,
const char* transactionId,
const char* callbackId,
const char* deduplicationId,
const char* jsonCallbackParameters,
const char* jsonPartnerParameters) {
NSString *strEventToken = isStringValid(eventToken) == true ? [NSString stringWithUTF8String:eventToken] : nil;
ADJEvent *event = [[ADJEvent alloc] initWithEventToken:strEventToken];
// revenue and currency
if (revenue != -1 && currency != NULL) {
NSString *stringCurrency = [NSString stringWithUTF8String:currency];
[event setRevenue:revenue currency:stringCurrency];
}
// callback parameters
NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters);
if (arrayCallbackParameters != nil) {
NSUInteger count = [arrayCallbackParameters count];
for (int i = 0; i < count;) {
NSString *key = arrayCallbackParameters[i++];
NSString *value = arrayCallbackParameters[i++];
[event addCallbackParameter:key value:value];
}
}
// partner parameters
NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters);
if (arrayPartnerParameters != nil) {
NSUInteger count = [arrayPartnerParameters count];
for (int i = 0; i < count;) {
NSString *key = arrayPartnerParameters[i++];
NSString *value = arrayPartnerParameters[i++];
[event addPartnerParameter:key value:value];
}
}
// transaction ID
if (transactionId != NULL) {
NSString *strTransactionId = [NSString stringWithUTF8String:transactionId];
[event setTransactionId:strTransactionId];
}
// product ID
if (productId != NULL) {
NSString *strProductId = [NSString stringWithUTF8String:productId];
[event setProductId:strProductId];
}
// callback ID
if (callbackId != NULL) {
NSString *strCallbackId = [NSString stringWithUTF8String:callbackId];
[event setCallbackId:strCallbackId];
}
// deduplication ID
if (deduplicationId != NULL) {
NSString *strDeduplicationId = [NSString stringWithUTF8String:deduplicationId];
[event setDeduplicationId:strDeduplicationId];
}
// track event
[Adjust trackEvent:event];
}
void _AdjustTrackSubsessionStart() {
[Adjust trackSubsessionStart];
}
void _AdjustTrackSubsessionEnd() {
[Adjust trackSubsessionEnd];
}
void _AdjustEnable() {
[Adjust enable];
}
void _AdjustDisable() {
[Adjust disable];
}
void _AdjustSwitchToOfflineMode() {
[Adjust switchToOfflineMode];
}
void _AdjustSwitchBackToOnlineMode() {
[Adjust switchBackToOnlineMode];
}
void _AdjustSetPushToken(const char* pushToken) {
if (pushToken != NULL) {
NSString *strPushToken = [NSString stringWithUTF8String:pushToken];
[Adjust setPushTokenAsString:strPushToken];
}
}
void _AdjustProcessDeeplink(const char* deeplink, const char* referrer) {
if (deeplink != NULL) {
NSString *strDeeplink = [NSString stringWithUTF8String:deeplink];
NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink];
ADJDeeplink *adjustDeeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink];
if (referrer != NULL) {
NSString *strReferrer = [NSString stringWithUTF8String:referrer];
NSURL *urlReferrer = [NSURL URLWithString:strReferrer];
[adjustDeeplink setReferrer:urlReferrer];
}
[Adjust processDeeplink:adjustDeeplink];
}
}
void _AdjustIsEnabled(AdjustDelegateIsEnabledGetter callback) {
[Adjust isEnabledWithCompletionHandler:^(BOOL isEnabled) {
callback(isEnabled);
}];
}
void _AdjustGetAttribution(AdjustDelegateAttributionGetter callback) {
[Adjust attributionWithCompletionHandler:^(ADJAttribution * _Nullable attribution) {
// TODO: nil checks
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
addValueOrEmpty(dictionary, @"trackerToken", attribution.trackerToken);
addValueOrEmpty(dictionary, @"trackerName", attribution.trackerName);
addValueOrEmpty(dictionary, @"network", attribution.network);
addValueOrEmpty(dictionary, @"campaign", attribution.campaign);
addValueOrEmpty(dictionary, @"creative", attribution.creative);
addValueOrEmpty(dictionary, @"adgroup", attribution.adgroup);
addValueOrEmpty(dictionary, @"clickLabel", attribution.clickLabel);
addValueOrEmpty(dictionary, @"costType", attribution.costType);
addValueOrEmpty(dictionary, @"costAmount", attribution.costAmount);
addValueOrEmpty(dictionary, @"costCurrency", attribution.costCurrency);
if (attribution.jsonResponse != nil) {
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:attribution.jsonResponse
options:0
error:nil];
NSString *strJsonResponse = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
addValueOrEmpty(dictionary, @"jsonResponse", strJsonResponse);
}
NSData *dataAttribution = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
NSString *stringAttribution = [[NSString alloc] initWithBytes:[dataAttribution bytes]
length:[dataAttribution length]
encoding:NSUTF8StringEncoding];
const char* attributionCString = [stringAttribution UTF8String];
callback(attributionCString);
}];
}
void _AdjustGetAdid(AdjustDelegateAdidGetter callback) {
[Adjust adidWithCompletionHandler:^(NSString * _Nullable adid) {
// TODO: nil checks
callback([adid UTF8String]);
}];
}
void _AdjustGetIdfa(AdjustDelegateIdfaGetter callback) {
[Adjust idfaWithCompletionHandler:^(NSString * _Nullable idfa) {
// TODO: nil checks
callback([idfa UTF8String]);
}];
}
void _AdjustGetIdfv(AdjustDelegateIdfvGetter callback) {
[Adjust idfvWithCompletionHandler:^(NSString * _Nullable idfv) {
// TODO: nil checks
callback([idfv UTF8String]);
}];
}
void _AdjustGetLastDeeplink(AdjustDelegateLastDeeplinkGetter callback) {
[Adjust lastDeeplinkWithCompletionHandler:^(NSURL * _Nullable lastDeeplink) {
// TODO: nil checks
NSString *strLastDeeplink = [lastDeeplink absoluteString];
callback([strLastDeeplink UTF8String]);
}];
}
void _AdjustGetSdkVersion(AdjustDelegateSdkVersionGetter callback) {
[Adjust sdkVersionWithCompletionHandler:^(NSString * _Nullable sdkVersion) {
// TODO: nil checks
callback([sdkVersion UTF8String]);
}];
}
void _AdjustGdprForgetMe() {
[Adjust gdprForgetMe];
}
void _AdjustAddGlobalPartnerParameter(const char* key, const char* value) {
if (key != NULL && value != NULL) {
NSString *strKey = [NSString stringWithUTF8String:key];
NSString *strValue = [NSString stringWithUTF8String:value];
[Adjust addGlobalPartnerParameter:strValue forKey:strKey];
}
}
void _AdjustAddGlobalCallbackParameter(const char* key, const char* value) {
if (key != NULL && value != NULL) {
NSString *strKey = [NSString stringWithUTF8String:key];
NSString *strValue = [NSString stringWithUTF8String:value];
[Adjust addGlobalCallbackParameter:strValue forKey:strKey];
}
}
void _AdjustRemoveGlobalPartnerParameter(const char* key) {
if (key != NULL) {
NSString *strKey = [NSString stringWithUTF8String:key];
[Adjust removeGlobalPartnerParameterForKey:strKey];
}
}
void _AdjustRemoveGlobalCallbackParameter(const char* key) {
if (key != NULL) {
NSString *strKey = [NSString stringWithUTF8String:key];
[Adjust removeGlobalCallbackParameterForKey:strKey];
}
}
void _AdjustRemoveGlobalPartnerParameters() {
[Adjust removeGlobalPartnerParameters];
}
void _AdjustRemoveGlobalCallbackParameters() {
[Adjust removeGlobalCallbackParameters];
}
void _AdjustTrackAdRevenue(const char* source,
double revenue,
const char* currency,
int adImpressionsCount,
const char* adRevenueNetwork,
const char* adRevenueUnit,
const char* adRevenuePlacement,
const char* jsonCallbackParameters,
const char* jsonPartnerParameters) {
NSString *stringSource = isStringValid(source) == true ? [NSString stringWithUTF8String:source] : nil;
ADJAdRevenue *adRevenue = [[ADJAdRevenue alloc] initWithSource:stringSource];
// revenue and currency
if (revenue != -1 && currency != NULL) {
NSString *stringCurrency = [NSString stringWithUTF8String:currency];
[adRevenue setRevenue:revenue currency:stringCurrency];
}
// ad impressions count
if (adImpressionsCount != -1) {
[adRevenue setAdImpressionsCount:adImpressionsCount];
}
// ad revenue network
if (adRevenueNetwork != NULL) {
NSString *stringAdRevenueNetwork = [NSString stringWithUTF8String:adRevenueNetwork];
[adRevenue setAdRevenueNetwork:stringAdRevenueNetwork];
}
// ad revenue unit
if (adRevenueUnit != NULL) {
NSString *stringAdRevenueUnit = [NSString stringWithUTF8String:adRevenueUnit];
[adRevenue setAdRevenueUnit:stringAdRevenueUnit];
}
// ad revenue placement
if (adRevenuePlacement != NULL) {
NSString *stringAdRevenuePlacement = [NSString stringWithUTF8String:adRevenuePlacement];
[adRevenue setAdRevenuePlacement:stringAdRevenuePlacement];
}
// callback parameters
NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters);
if (arrayCallbackParameters != nil) {
NSUInteger count = [arrayCallbackParameters count];
for (int i = 0; i < count;) {
NSString *key = arrayCallbackParameters[i++];
NSString *value = arrayCallbackParameters[i++];
[adRevenue addCallbackParameter:key value:value];
}
}
// partner parameters
NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters);
if (arrayPartnerParameters != nil) {
NSUInteger count = [arrayPartnerParameters count];
for (int i = 0; i < count;) {
NSString *key = arrayPartnerParameters[i++];
NSString *value = arrayPartnerParameters[i++];
[adRevenue addPartnerParameter:key value:value];
}
}
// track ad revenue
[Adjust trackAdRevenue:adRevenue];
}
// TODO: consider non-string types for some fields?
void _AdjustTrackAppStoreSubscription(const char* price,
const char* currency,
const char* transactionId,
const char* transactionDate,
const char* salesRegion,
const char* jsonCallbackParameters,
const char* jsonPartnerParameters) {
// mandatory fields
NSDecimalNumber *mPrice;
NSString *mCurrency;
NSString *mTransactionId;
// price
if (price != NULL) {
mPrice = [NSDecimalNumber decimalNumberWithString:[NSString stringWithUTF8String:price]];
}
// currency
if (currency != NULL) {
mCurrency = [NSString stringWithUTF8String:currency];
}
// transaction ID
if (transactionId != NULL) {
mTransactionId = [NSString stringWithUTF8String:transactionId];
}
ADJAppStoreSubscription *subscription =
[[ADJAppStoreSubscription alloc] initWithPrice:mPrice
currency:mCurrency
transactionId:mTransactionId];
// optional fields below
// transaction date
if (transactionDate != NULL) {
NSTimeInterval transactionDateInterval = [[NSString stringWithUTF8String:transactionDate] doubleValue] / 1000.0;
NSDate *oTransactionDate = [NSDate dateWithTimeIntervalSince1970:transactionDateInterval];
[subscription setTransactionDate:oTransactionDate];
}
// sales region
if (salesRegion != NULL) {
NSString *oSalesRegion = [NSString stringWithUTF8String:salesRegion];
[subscription setSalesRegion:oSalesRegion];
}
// callback parameters
NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters);
if (arrayCallbackParameters != nil) {
NSUInteger count = [arrayCallbackParameters count];
for (int i = 0; i < count;) {
NSString *key = arrayCallbackParameters[i++];
NSString *value = arrayCallbackParameters[i++];
[subscription addCallbackParameter:key value:value];
}
}
// partner parameters
NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters);
if (arrayPartnerParameters != nil) {
NSUInteger count = [arrayPartnerParameters count];
for (int i = 0; i < count;) {
NSString *key = arrayPartnerParameters[i++];
NSString *value = arrayPartnerParameters[i++];
[subscription addPartnerParameter:key value:value];
}
}
// track subscription
[Adjust trackAppStoreSubscription:subscription];
}
void _AdjustTrackThirdPartySharing(int enabled, const char* jsonGranularOptions, const char* jsonPartnerSharingSettings) {
NSNumber *nEnabled = enabled >= 0 ? [NSNumber numberWithInt:enabled] : nil;
ADJThirdPartySharing *adjustThirdPartySharing = [[ADJThirdPartySharing alloc] initWithIsEnabled:nEnabled];
NSArray *arrayGranularOptions = convertArrayParameters(jsonGranularOptions);
if (arrayGranularOptions != nil) {
for (int i = 0; i < [arrayGranularOptions count];) {
NSString *partnerName = arrayGranularOptions[i++];
NSString *key = arrayGranularOptions[i++];
NSString *value = arrayGranularOptions[i++];
[adjustThirdPartySharing addGranularOption:partnerName
key:key
value:value];
}
}
NSArray *arrayPartnerSharingSettings = convertArrayParameters(jsonPartnerSharingSettings);
if (arrayPartnerSharingSettings != nil) {
for (int i = 0; i < [arrayPartnerSharingSettings count];) {
NSString *partnerName = arrayPartnerSharingSettings[i++];
NSString *key = arrayPartnerSharingSettings[i++];
NSString *value = arrayPartnerSharingSettings[i++];
[adjustThirdPartySharing addPartnerSharingSetting:partnerName
key:key
value:[value boolValue]];
}
}
[Adjust trackThirdPartySharing:adjustThirdPartySharing];
}
void _AdjustTrackMeasurementConsent(int enabled) {
BOOL bEnabled = (BOOL)enabled;
[Adjust trackMeasurementConsent:bEnabled];
}
void _AdjustRequestAppTrackingAuthorization(AdjustDelegateAttCallback callback) {
[Adjust requestAppTrackingAuthorizationWithCompletionHandler:^(NSUInteger status) {
callback((int)status);
}];
}
void _AdjustUpdateSkanConversionValue(int conversionValue,
const char* coarseValue,
int lockWindow,
AdjustDelegateSkanErrorCallback callback) {
if (coarseValue != NULL) {
NSString *strCoarseValue = [NSString stringWithUTF8String:coarseValue];
BOOL bLockWindow = (BOOL)lockWindow;
[Adjust updateSkanConversionValue:conversionValue
coarseValue:strCoarseValue
lockWindow:[NSNumber numberWithBool:bLockWindow]
withCompletionHandler:^(NSError * _Nullable error) {
// TODO: nil checks
NSString *errorString = [error localizedDescription];
const char* errorChar = [errorString UTF8String];
callback(errorChar);
}];
}
}
int _AdjustGetAppTrackingAuthorizationStatus() {
return [Adjust appTrackingAuthorizationStatus];
}
void _AdjustVerifyAppStorePurchase(const char* transactionId,
const char* productId,
int callbackId,
AdjustDelegatePurchaseVerificationCallback callback) {
NSString *strTransactionId;
NSString *strProductId;
// transaction ID
if (transactionId != NULL) {
strTransactionId = [NSString stringWithUTF8String:transactionId];
}
// product ID
if (productId != NULL) {
strProductId = [NSString stringWithUTF8String:productId];
}
// verify the purchase
ADJAppStorePurchase *purchase =
[[ADJAppStorePurchase alloc] initWithTransactionId:strTransactionId
productId:strProductId];
[Adjust verifyAppStorePurchase:purchase
withCompletionHandler:^(ADJPurchaseVerificationResult * _Nonnull verificationResult) {
// TODO: nil checks
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
addValueOrEmpty(dictionary, @"verificationStatus", verificationResult.verificationStatus);
addValueOrEmpty(dictionary, @"code", [NSString stringWithFormat:@"%d", verificationResult.code]);
addValueOrEmpty(dictionary, @"message", verificationResult.message);
NSData *dataVerificationInfo = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
NSString *strVerificationInfo = [[NSString alloc] initWithBytes:[dataVerificationInfo bytes]
length:[dataVerificationInfo length]
encoding:NSUTF8StringEncoding];
const char* verificationInfoCString = [strVerificationInfo UTF8String];
callback(verificationInfoCString, callbackId);
}];
}
void _AdjustProcessAndResolveDeeplink(const char* deeplink, AdjustDelegateResolvedDeeplinkCallback callback) {
if (deeplink != NULL) {
NSString *strDeeplink = [NSString stringWithUTF8String:deeplink];
NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink];
ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink];
[Adjust processAndResolveDeeplink:deeplink withCompletionHandler:^(NSString * _Nullable resolvedLink) {
// TODO: nil checks
const char* resolvedLinkCString = [resolvedLink UTF8String];
callback(resolvedLinkCString);
}];
}
}
void _AdjustVerifyAndTrackAppStorePurchase(
const char* eventToken,
double revenue,
const char* currency,
const char* productId,
const char* transactionId,
const char* callbackId,
const char* deduplicationId,
const char* jsonCallbackParameters,
const char* jsonPartnerParameters,
int verificationCallbackId,
AdjustDelegateVerifyAndTrackCallback callback) {
NSString *strEventToken = isStringValid(eventToken) == true ? [NSString stringWithUTF8String:eventToken] : nil;
ADJEvent *event = [[ADJEvent alloc] initWithEventToken:strEventToken];
// revenue and currency
if (revenue != -1 && currency != NULL) {
NSString *stringCurrency = [NSString stringWithUTF8String:currency];
[event setRevenue:revenue currency:stringCurrency];
}
// callback parameters
NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters);
if (arrayCallbackParameters != nil) {
NSUInteger count = [arrayCallbackParameters count];
for (int i = 0; i < count;) {
NSString *key = arrayCallbackParameters[i++];
NSString *value = arrayCallbackParameters[i++];
[event addCallbackParameter:key value:value];
}
}
// partner parameters
NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters);
if (arrayPartnerParameters != nil) {
NSUInteger count = [arrayPartnerParameters count];
for (int i = 0; i < count;) {
NSString *key = arrayPartnerParameters[i++];
NSString *value = arrayPartnerParameters[i++];
[event addPartnerParameter:key value:value];
}
}
// transaction ID
if (transactionId != NULL) {
NSString *strTransactionId = [NSString stringWithUTF8String:transactionId];
[event setTransactionId:strTransactionId];
}
// product ID
if (productId != NULL) {
NSString *strProductId = [NSString stringWithUTF8String:productId];
[event setProductId:strProductId];
}
// callback ID
if (callbackId != NULL) {
NSString *strCallbackId = [NSString stringWithUTF8String:callbackId];
[event setCallbackId:strCallbackId];
}
// deduplication ID
if (deduplicationId != NULL) {
NSString *strDeduplicationId = [NSString stringWithUTF8String:deduplicationId];
[event setDeduplicationId:strDeduplicationId];
}
[Adjust verifyAndTrackAppStorePurchase:event
withCompletionHandler:^(ADJPurchaseVerificationResult * _Nonnull verificationResult) {
// TODO: nil checks
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
addValueOrEmpty(dictionary, @"verificationStatus", verificationResult.verificationStatus);
addValueOrEmpty(dictionary, @"code", [NSString stringWithFormat:@"%d", verificationResult.code]);
addValueOrEmpty(dictionary, @"message", verificationResult.message);
NSData *dataVerificationInfo = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
NSString *strVerificationInfo = [[NSString alloc] initWithBytes:[dataVerificationInfo bytes]
length:[dataVerificationInfo length]
encoding:NSUTF8StringEncoding];
const char* verificationInfoCString = [strVerificationInfo UTF8String];
callback(verificationInfoCString, verificationCallbackId);
}];
}
void _AdjustEndFirstSessionDelay() {
[Adjust endFirstSessionDelay];
}
void _AdjustEnableCoppaComplianceInDelay() {
[Adjust enableCoppaComplianceInDelay];
}
void _AdjustDisableCoppaComplianceInDelay() {
[Adjust disableCoppaComplianceInDelay];
}
void _AdjustSetExternalDeviceIdInDelay(const char* externalDeviceId) {
if (externalDeviceId != NULL) {
NSString *strExternalDeviceId = [NSString stringWithUTF8String:externalDeviceId];
[Adjust setExternalDeviceIdInDelay:strExternalDeviceId];
}
}
void _AdjustSetTestOptions(const char* overwriteUrl,
const char* extraPath,
long timerIntervalInMilliseconds,
long timerStartInMilliseconds,
long sessionIntervalInMilliseconds,
long subsessionIntervalInMilliseconds,
int teardown,
int deleteState,
int noBackoffWait,
int adServicesFrameworkEnabled,
int attStatus,
const char *idfa) {
NSMutableDictionary *testOptions = [NSMutableDictionary dictionary];
NSString *strOverwriteUrl = isStringValid(overwriteUrl) == true ? [NSString stringWithUTF8String:overwriteUrl] : nil;
if (strOverwriteUrl != nil) {
testOptions[@"testUrlOverwrite"] = strOverwriteUrl;
}
NSString *strExtraPath = isStringValid(extraPath) == true ? [NSString stringWithUTF8String:extraPath] : nil;
if (strExtraPath != nil && [strExtraPath length] > 0) {
testOptions[@"extraPath"] = strExtraPath;
}
NSString *strIdfa = isStringValid(idfa) == true ? [NSString stringWithUTF8String:idfa] : nil;
if (strIdfa != nil && [strIdfa length] > 0) {
testOptions[@"idfa"] = strIdfa;
}
testOptions[@"timerIntervalInMilliseconds"] = [NSNumber numberWithLong:timerIntervalInMilliseconds];
testOptions[@"timerStartInMilliseconds"] = [NSNumber numberWithLong:timerStartInMilliseconds];
testOptions[@"sessionIntervalInMilliseconds"] = [NSNumber numberWithLong:sessionIntervalInMilliseconds];
testOptions[@"subsessionIntervalInMilliseconds"] = [NSNumber numberWithLong:subsessionIntervalInMilliseconds];
testOptions[@"attStatusInt"] = [NSNumber numberWithInt:attStatus];
if (teardown != -1) {
[AdjustUnityDelegate teardown];
testOptions[@"teardown"] = [NSNumber numberWithInt:teardown];
}
if (deleteState != -1) {
testOptions[@"deleteState"] = [NSNumber numberWithInt:deleteState];
}
if (noBackoffWait != -1) {
testOptions[@"noBackoffWait"] = [NSNumber numberWithInt:noBackoffWait];
}
if (adServicesFrameworkEnabled != -1) {
testOptions[@"adServicesFrameworkEnabled"] = [NSNumber numberWithInt:adServicesFrameworkEnabled];
}
[Adjust setTestOptions:testOptions];
}
}

View File

@ -0,0 +1,131 @@
fileFormatVersion: 2
guid: 3e17e20d987e4449489d9e3accbd8602
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
Exclude tvOS: 1
- first:
'': Editor
second:
enabled: 0
settings:
CPU: AnyCPU
OS: AnyOS
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: None
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXIntel
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXIntel64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
iPhone: iOS
second:
enabled: 1
settings:
CompileFlags:
FrameworkDependencies:
- first:
tvOS: tvOS
second:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
//
// AdjustUnityAppDelegate.h
// Adjust SDK
//
// Copyright © 2012-2021 Adjust GmbH. All rights reserved.
//
/**
* @brief The interface to Adjust App Delegate. Used to do callback methods swizzling for deep linking.
*/
@interface AdjustUnityAppDelegate : NSObject
/**
* @brief Swizzle AppDelegate deep linking callbacks.
*/
+ (void)swizzleAppDelegateCallbacks;
@end

View File

@ -0,0 +1,115 @@
fileFormatVersion: 2
guid: ac4b0b80967dd499b94e6bd430ac6662
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
Exclude tvOS: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: None
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
WebGL: WebGL
second:
enabled: 0
settings: {}
- first:
iPhone: iOS
second:
enabled: 1
settings:
CompileFlags:
FrameworkDependencies:
- first:
tvOS: tvOS
second:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,75 @@
//
// AdjustUnityAppDelegate.mm
// Adjust SDK
//
// Copyright © 2012-2021 Adjust GmbH. All rights reserved.
//
#import <objc/runtime.h>
#import <AdjustSdk/AdjustSdk.h>
#import "AdjustUnityAppDelegate.h"
typedef BOOL (*openURL_t)(id, SEL, UIApplication *, NSURL *, NSDictionary *);
typedef BOOL (*continueUserActivity_t)(id, SEL, UIApplication *, NSUserActivity *, void (^)(NSArray *restorableObjects));
static openURL_t original_openURL = NULL;
static continueUserActivity_t original_continueUserActivity = NULL;
@implementation AdjustUnityAppDelegate
+ (void)swizzleAppDelegateCallbacks {
NSLog(@"[Adjust] Swizzling AppDelegate callbacks...");
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
original_openURL = (openURL_t)[self swizzleOriginalSelector:@selector(application:openURL:options:)
withSelector:@selector(adjust_application:openURL:options:)];
original_continueUserActivity = (continueUserActivity_t)[self swizzleOriginalSelector:@selector(application:continueUserActivity:restorationHandler:)
withSelector:@selector(adjust_application:continueUserActivity:restorationHandler:)];
});
}
+ (IMP)swizzleOriginalSelector:(SEL)originalSelector
withSelector:(SEL)swizzledSelector {
// The Unity base app controller class name.
extern const char* AppControllerClassName;
Class originalClass = NSClassFromString([NSString stringWithUTF8String:AppControllerClassName]);
Class swizzledClass = [self class];
IMP originalImp = NULL;
IMP swizzledImp = class_getMethodImplementation(swizzledClass, swizzledSelector);
// Replace original implementation by the custom one.
Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
if (originalMethod) {
originalImp = method_setImplementation(originalMethod, swizzledImp);
} else if (![originalClass instancesRespondToSelector:originalSelector]) {
// Add the method to the original class if it doesn't implement the selector.
Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
BOOL methodAdded = class_addMethod(originalClass, originalSelector, swizzledImp, method_getTypeEncoding(swizzledMethod));
if (!methodAdded) {
NSLog(@"[Adjust] Cannot swizzle selector '%@' of class '%@'.", NSStringFromSelector(originalSelector), originalClass);
return NULL;
}
}
NSLog(@"[Adjust] Selector '%@' of class '%@' is swizzled.", NSStringFromSelector(originalSelector), originalClass);
return originalImp;
}
- (BOOL)adjust_application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary *)options {
ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:url];
[Adjust processDeeplink:deeplink];
return original_openURL ? original_openURL(self, _cmd, application, url, options) : YES;
}
- (BOOL)adjust_application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
if ([[userActivity activityType] isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = [userActivity webpageURL];
ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:url];
[Adjust processDeeplink:deeplink];
}
return original_continueUserActivity ? original_continueUserActivity(self, _cmd, application, userActivity, restorationHandler) : YES;
}
@end

View File

@ -0,0 +1,98 @@
fileFormatVersion: 2
guid: ea1bc374f78b747f8a81fcc82cd77d96
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
Exclude tvOS: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: None
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 0
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,60 @@
//
// AdjustUnityDelegate.h
// Adjust SDK
//
// Created by Uglješa Erceg (@uerceg) on 5th December 2016.
// Copyright © 2012-Present Adjust GmbH. All rights reserved.
//
#import <AdjustSdk/AdjustSdk.h>
#import "AdjustUnity.h"
/**
* @brief The main interface to Adjust Unity delegate. Used to do callback methods swizzling where needed.
*/
@interface AdjustUnityDelegate : NSObject<AdjustDelegate>
/**
* @brief Boolean indicating whether deferred deep link should be launched by SDK or not.
*/
@property (nonatomic) BOOL shouldLaunchDeferredDeeplink;
@property (nonatomic) AdjustDelegateAttributionCallback attributionCallback;
@property (nonatomic) AdjustDelegateEventSuccessCallback eventSuccessCallback;
@property (nonatomic) AdjustDelegateEventFailureCallback eventFailureCallback;
@property (nonatomic) AdjustDelegateSessionSuccessCallback sessionSuccessCallback;
@property (nonatomic) AdjustDelegateSessionFailureCallback sessionFailureCallback;
@property (nonatomic) AdjustDelegateDeferredDeeplinkCallback deferredDeeplinkCallback;
@property (nonatomic) AdjustDelegateSkanUpdatedCallback skanUpdatedCallback;
/**
* @brief Get instance of the AdjustUnityDelegate with properly swizzled callback methods.
*
* @param swizzleAttributionCallback Indicator whether attribution callback should be swizzled or not.
* @param swizzleEventSuccessCallback Indicator whether event success callback should be swizzled or not.
* @param swizzleEventFailureCallback Indicator whether event failure callback should be swizzled or not.
* @param swizzleSessionSuccessCallback Indicator whether session success callback should be swizzled or not.
* @param swizzleSessionFailureCallback Indicator whether session failure callback should be swizzled or not.
* @param swizzleDeferredDeeplinkCallback Indicator whether deferred deep link callback should be swizzled or not.
* @param swizzleSkanUpdatedCallback Indicator whether SKAD conversion value update callback should be swizzled or not.
* @param shouldLaunchDeferredDeeplink Indicator whether SDK should launch deferred deep link by default or not.
* @param adjustUnityGameObjectName Name of the Unity game object that loads Adjust script.
*
* @return AdjustUnityDelegate object instance with properly swizzled callback methods.
*/
+ (id)getInstanceWithAttributionCallback:(AdjustDelegateAttributionCallback)attributionCallback
eventSuccessCallback:(AdjustDelegateEventSuccessCallback)eventSuccessCallback
eventFailureCallback:(AdjustDelegateEventFailureCallback)eventFailureCallback
sessionSuccessCallback:(AdjustDelegateSessionSuccessCallback)sessionSuccessCallback
sessionFailureCallback:(AdjustDelegateSessionFailureCallback)sessionFailureCallback
deferredDeeplinkCallback:(AdjustDelegateDeferredDeeplinkCallback)deferredDeeplinkCallback
skanUpdatedCallback:(AdjustDelegateSkanUpdatedCallback)skanUpdatedCallback
shouldLaunchDeferredDeeplink:(BOOL)shouldLaunchDeferredDeeplink;
/**
* @brief Teardown method used to reset static AdjustUnityDelegate instance.
* Used for testing purposes only.
*/
+ (void)teardown;
@end

View File

@ -0,0 +1,131 @@
fileFormatVersion: 2
guid: 5d2beef19c617f74fbca612cc97e3c60
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
Exclude tvOS: 1
- first:
'': Editor
second:
enabled: 0
settings:
CPU: AnyCPU
OS: AnyOS
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: None
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXIntel
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXIntel64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
iPhone: iOS
second:
enabled: 1
settings:
CompileFlags:
FrameworkDependencies:
- first:
tvOS: tvOS
second:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,345 @@
//
// AdjustUnityDelegate.mm
// Adjust SDK
//
// Created by Uglješa Erceg (@uerceg) on 5th December 2016.
// Copyright © 2012-2018 Adjust GmbH. All rights reserved.
//
#import <objc/runtime.h>
#import "AdjustUnityDelegate.h"
static dispatch_once_t onceToken;
static AdjustUnityDelegate *defaultInstance = nil;
@implementation AdjustUnityDelegate
#pragma mark - Object lifecycle methods
- (id)init {
self = [super init];
if (nil == self) {
return nil;
}
return self;
}
#pragma mark - Public methods
+ (id)getInstanceWithAttributionCallback:(AdjustDelegateAttributionCallback)attributionCallback
eventSuccessCallback:(AdjustDelegateEventSuccessCallback)eventSuccessCallback
eventFailureCallback:(AdjustDelegateEventFailureCallback)eventFailureCallback
sessionSuccessCallback:(AdjustDelegateSessionSuccessCallback)sessionSuccessCallback
sessionFailureCallback:(AdjustDelegateSessionFailureCallback)sessionFailureCallback
deferredDeeplinkCallback:(AdjustDelegateDeferredDeeplinkCallback)deferredDeeplinkCallback
skanUpdatedCallback:(AdjustDelegateSkanUpdatedCallback)skanUpdatedCallback
shouldLaunchDeferredDeeplink:(BOOL)shouldLaunchDeferredDeeplink {
dispatch_once(&onceToken, ^{
defaultInstance = [[AdjustUnityDelegate alloc] init];
// Do the swizzling where and if needed.
if (attributionCallback != nil) {
[defaultInstance swizzleOriginalSelector:@selector(adjustAttributionChanged:)
withSelector:@selector(adjustAttributionChangedWannabe:)];
}
if (eventSuccessCallback != nil) {
[defaultInstance swizzleOriginalSelector:@selector(adjustEventTrackingSucceeded:)
withSelector:@selector(adjustEventTrackingSucceededWannabe:)];
}
if (eventFailureCallback != nil) {
[defaultInstance swizzleOriginalSelector:@selector(adjustEventTrackingFailed:)
withSelector:@selector(adjustEventTrackingFailedWannabe:)];
}
if (sessionSuccessCallback != nil) {
[defaultInstance swizzleOriginalSelector:@selector(adjustSessionTrackingSucceeded:)
withSelector:@selector(adjustSessionTrackingSucceededWannabe:)];
}
if (sessionFailureCallback != nil) {
[defaultInstance swizzleOriginalSelector:@selector(adjustSessionTrackingFailed:)
withSelector:@selector(adjustSessionTrackingFailedWannabe:)];
}
if (deferredDeeplinkCallback != nil) {
[defaultInstance swizzleOriginalSelector:@selector(adjustDeferredDeeplinkReceived:)
withSelector:@selector(adjustDeferredDeeplinkReceivedWannabe:)];
}
if (skanUpdatedCallback != nil) {
[defaultInstance swizzleOriginalSelector:@selector(adjustSkanUpdatedWithConversionData:)
withSelector:@selector(adjustSkanUpdatedWithConversionDataWannabe:)];
}
[defaultInstance setAttributionCallback:attributionCallback];
[defaultInstance setEventSuccessCallback:eventSuccessCallback];
[defaultInstance setEventFailureCallback:eventFailureCallback];
[defaultInstance setSessionSuccessCallback:sessionSuccessCallback];
[defaultInstance setSessionFailureCallback:sessionFailureCallback];
[defaultInstance setDeferredDeeplinkCallback:deferredDeeplinkCallback];
[defaultInstance setSkanUpdatedCallback:skanUpdatedCallback];
[defaultInstance setShouldLaunchDeferredDeeplink:shouldLaunchDeferredDeeplink];
});
return defaultInstance;
}
+ (void)teardown {
defaultInstance = nil;
onceToken = 0;
}
#pragma mark - Private & helper methods
- (void)adjustAttributionChangedWannabe:(ADJAttribution *)attribution {
if (attribution == nil || _attributionCallback == nil) {
return;
}
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self addValueOrEmpty:attribution.trackerToken
forKey:@"trackerToken"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.trackerName
forKey:@"trackerName"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.network
forKey:@"network"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.campaign
forKey:@"campaign"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.creative
forKey:@"creative"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.adgroup
forKey:@"adgroup"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.clickLabel
forKey:@"clickLabel"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.costType
forKey:@"costType"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.costAmount
forKey:@"costAmount"
toDictionary:dictionary];
[self addValueOrEmpty:attribution.costCurrency
forKey:@"costCurrency"
toDictionary:dictionary];
if (attribution.jsonResponse != nil) {
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:attribution.jsonResponse
options:0
error:nil];
NSString *strJsonResponse = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[self addValueOrEmpty:strJsonResponse
forKey:@"jsonResponse"
toDictionary:dictionary];
}
NSData *dataAttribution = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
NSString *stringAttribution = [[NSString alloc] initWithBytes:[dataAttribution bytes]
length:[dataAttribution length]
encoding:NSUTF8StringEncoding];
const char* charArrayAttribution = [stringAttribution UTF8String];
_attributionCallback(charArrayAttribution);
}
- (void)adjustEventTrackingSucceededWannabe:(ADJEventSuccess *)eventSuccessResponseData {
if (nil == eventSuccessResponseData || _eventSuccessCallback == nil) {
return;
}
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self addValueOrEmpty:eventSuccessResponseData.message
forKey:@"message"
toDictionary:dictionary];
[self addValueOrEmpty:eventSuccessResponseData.timestamp
forKey:@"timestamp"
toDictionary:dictionary];
[self addValueOrEmpty:eventSuccessResponseData.adid
forKey:@"adid"
toDictionary:dictionary];
[self addValueOrEmpty:eventSuccessResponseData.eventToken
forKey:@"eventToken"
toDictionary:dictionary];
[self addValueOrEmpty:eventSuccessResponseData.callbackId
forKey:@"callbackId"
toDictionary:dictionary];
if (eventSuccessResponseData.jsonResponse != nil) {
[dictionary setObject:eventSuccessResponseData.jsonResponse
forKey:@"jsonResponse"];
}
NSData *dataEventSuccess = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
NSString *stringEventSuccess = [[NSString alloc] initWithBytes:[dataEventSuccess bytes]
length:[dataEventSuccess length]
encoding:NSUTF8StringEncoding];
const char* charArrayEventSuccess = [stringEventSuccess UTF8String];
_eventSuccessCallback(charArrayEventSuccess);
}
- (void)adjustEventTrackingFailedWannabe:(ADJEventFailure *)eventFailureResponseData {
if (nil == eventFailureResponseData || _eventFailureCallback == nil) {
return;
}
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self addValueOrEmpty:eventFailureResponseData.message
forKey:@"message"
toDictionary:dictionary];
[self addValueOrEmpty:eventFailureResponseData.timestamp
forKey:@"timestamp"
toDictionary:dictionary];
[self addValueOrEmpty:eventFailureResponseData.adid
forKey:@"adid"
toDictionary:dictionary];
[self addValueOrEmpty:eventFailureResponseData.eventToken
forKey:@"eventToken"
toDictionary:dictionary];
[self addValueOrEmpty:eventFailureResponseData.callbackId
forKey:@"callbackId"
toDictionary:dictionary];
[dictionary setObject:(eventFailureResponseData.willRetry ? @"true" : @"false")
forKey:@"willRetry"];
if (eventFailureResponseData.jsonResponse != nil) {
[dictionary setObject:eventFailureResponseData.jsonResponse
forKey:@"jsonResponse"];
}
NSData *dataEventFailure = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
NSString *stringEventFailure = [[NSString alloc] initWithBytes:[dataEventFailure bytes]
length:[dataEventFailure length]
encoding:NSUTF8StringEncoding];
const char* charArrayEventFailure = [stringEventFailure UTF8String];
_eventFailureCallback(charArrayEventFailure);
}
- (void)adjustSessionTrackingSucceededWannabe:(ADJSessionSuccess *)sessionSuccessResponseData {
if (nil == sessionSuccessResponseData || _sessionSuccessCallback == nil) {
return;
}
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self addValueOrEmpty:sessionSuccessResponseData.message
forKey:@"message"
toDictionary:dictionary];
[self addValueOrEmpty:sessionSuccessResponseData.timestamp
forKey:@"timestamp"
toDictionary:dictionary];
[self addValueOrEmpty:sessionSuccessResponseData.adid
forKey:@"adid"
toDictionary:dictionary];
if (sessionSuccessResponseData.jsonResponse != nil) {
[dictionary setObject:sessionSuccessResponseData.jsonResponse
forKey:@"jsonResponse"];
}
NSData *dataSessionSuccess = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
NSString *stringSessionSuccess = [[NSString alloc] initWithBytes:[dataSessionSuccess bytes]
length:[dataSessionSuccess length]
encoding:NSUTF8StringEncoding];
const char* charArraySessionSuccess = [stringSessionSuccess UTF8String];
_sessionSuccessCallback(charArraySessionSuccess);
}
- (void)adjustSessionTrackingFailedWannabe:(ADJSessionFailure *)sessionFailureResponseData {
if (nil == sessionFailureResponseData || _sessionFailureCallback == nil) {
return;
}
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self addValueOrEmpty:sessionFailureResponseData.message
forKey:@"message"
toDictionary:dictionary];
[self addValueOrEmpty:sessionFailureResponseData.timestamp
forKey:@"timestamp"
toDictionary:dictionary];
[self addValueOrEmpty:sessionFailureResponseData.adid
forKey:@"adid"
toDictionary:dictionary];
[dictionary setObject:(sessionFailureResponseData.willRetry ? @"true" : @"false")
forKey:@"willRetry"];
if (sessionFailureResponseData.jsonResponse != nil) {
[dictionary setObject:sessionFailureResponseData.jsonResponse
forKey:@"jsonResponse"];
}
NSData *dataSessionFailure = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
NSString *stringSessionFailure = [[NSString alloc] initWithBytes:[dataSessionFailure bytes]
length:[dataSessionFailure length]
encoding:NSUTF8StringEncoding];
const char* charArraySessionFailure = [stringSessionFailure UTF8String];
_sessionFailureCallback(charArraySessionFailure);
}
- (BOOL)adjustDeferredDeeplinkReceivedWannabe:(NSURL *)deeplink {
if (_deferredDeeplinkCallback != nil) {
NSString *stringDeeplink = [deeplink absoluteString];
const char* charDeeplink = [stringDeeplink UTF8String];
_deferredDeeplinkCallback(charDeeplink);
}
return _shouldLaunchDeferredDeeplink;
}
- (void)adjustSkanUpdatedWithConversionDataWannabe:(NSDictionary<NSString *,NSString *> *)data {
if (data == nil || _skanUpdatedCallback == nil) {
return;
}
NSData *dataSkanUpdatedData = [NSJSONSerialization dataWithJSONObject:data
options:0
error:nil];
NSString *strSkanUpdatedData = [[NSString alloc] initWithBytes:[dataSkanUpdatedData bytes]
length:[dataSkanUpdatedData length]
encoding:NSUTF8StringEncoding];
const char* charSkanUpdatedData = [strSkanUpdatedData UTF8String];
_skanUpdatedCallback(charSkanUpdatedData);
}
- (void)swizzleOriginalSelector:(SEL)originalSelector
withSelector:(SEL)swizzledSelector {
Class className = [self class];
Method originalMethod = class_getInstanceMethod(className, originalSelector);
Method swizzledMethod = class_getInstanceMethod(className, swizzledSelector);
BOOL didAddMethod = class_addMethod(className,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(className,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
- (void)addValueOrEmpty:(NSObject *)value
forKey:(NSString *)key
toDictionary:(NSMutableDictionary *)dictionary {
if (nil != value) {
if ([value isKindOfClass:[NSString class]]) {
[dictionary setObject:[NSString stringWithFormat:@"%@", value]
forKey:key];
} else if ([value isKindOfClass:[NSNumber class]]) {
[dictionary setObject:[NSString stringWithFormat:@"%@", [((NSNumber *)value) stringValue]]
forKey:key];
} else {
[dictionary setObject:@"" forKey:key];
}
} else {
[dictionary setObject:@"" forKey:key];
}
}
@end

View File

@ -0,0 +1,129 @@
fileFormatVersion: 2
guid: 81438eed05b2e4b489f13efc94d5476a
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
Exclude tvOS: 1
- first:
'': Editor
second:
enabled: 0
settings:
CPU: AnyCPU
OS: AnyOS
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: None
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXIntel
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXIntel64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
iPhone: iOS
second:
enabled: 1
settings:
CompileFlags:
FrameworkDependencies:
- first:
tvOS: tvOS
second:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0acdd227ad1b8d147ade044242671e15
folderAsset: yes
timeCreated: 1578652549
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,77 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &115478
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 415478}
- component: {fileID: 114179903453641630}
m_Layer: 0
m_Name: Adjust
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &415478
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 115478}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 115478}
m_IsPrefabParent: 1
--- !u!114 &114179903453641630
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 115478}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 525ece82a472e4dea837e1ef938fd15d, type: 3}
m_Name:
m_EditorClassIdentifier:
startManually: 1
appToken:
environment: 0
logLevel: 3
eventBuffering: 0
sendInBackground: 0
launchDeferredDeeplink: 1
needsCost: 0
coppaCompliant: 0
linkMe: 0
defaultTracker:
urlStrategy: 0
startDelay: 0
secretId: 0
info1: 0
info2: 0
info3: 0
info4: 0
preinstallTracking: 0
preinstallFilePath:
playStoreKidsApp: 0
adServicesInfoReading: 1
idfaInfoReading: 1
skAdNetworkHandling: 1

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a3267720e82aa41c1a05ab29824902b4
NativeFormatImporter:
mainObjectFileID: -1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e9688945324d3a44699534d71c3e55cb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,28 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ea4d495dc6d5ba64b90db7afda6a48a4, type: 3}
m_Name: AdjustSettings
m_EditorClassIdentifier:
_iOSFrameworkAdSupport: 1
_iOSFrameworkAdServices: 0
_iOSFrameworkAppTrackingTransparency: 0
_iOSFrameworkStoreKit: 0
_androidPermissionInternet: 1
_androidPermissionInstallReferrerService: 1
_androidPermissionAdId: 1
_androidPermissionAccessNetworkState: 0
_iOSUserTrackingUsageDescription:
_iOSUrlIdentifier:
_iOSUrlSchemes: []
_iOSUniversalLinksDomains: []
androidUriSchemes: []
_androidCustomActivityName:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 998d67a1c15bc8b4ea727ddd95230724
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0e5ecfef4e691483199f0cdae3eebff2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,839 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace AdjustSdk
{
public class Adjust : MonoBehaviour
{
private const string errorMsgEditor = "[Adjust]: SDK can not be used in Editor.";
private const string errorMsgStart = "[Adjust]: SDK not started. Start it manually using the 'start' method.";
private const string errorMsgPlatform = "[Adjust]: SDK can only be used in Android and iOS apps.";
// [Header("SDK SETTINGS:")]
// [Space(5)]
// [Tooltip("If selected, it is expected from you to initialize Adjust SDK from your app code. " +
// "Any SDK configuration settings from prefab will be ignored in that case.")]
[HideInInspector]
public bool startManually = true;
[HideInInspector]
public string appToken;
[HideInInspector]
public AdjustEnvironment environment = AdjustEnvironment.Sandbox;
[HideInInspector]
public AdjustLogLevel logLevel = AdjustLogLevel.Info;
[HideInInspector]
public bool coppaCompliance = false;
[HideInInspector]
public bool sendInBackground = false;
[HideInInspector]
public bool launchDeferredDeeplink = true;
[HideInInspector]
public bool costDataInAttribution = false;
[HideInInspector]
public bool linkMe = false;
[HideInInspector]
public string defaultTracker;
// [Header("ANDROID SPECIFIC FEATURES:")]
// [Space(5)]
[HideInInspector]
public bool preinstallTracking = false;
[HideInInspector]
public string preinstallFilePath;
// [Header("iOS SPECIFIC FEATURES:")]
// [Space(5)]
[HideInInspector]
public bool adServices = true;
[HideInInspector]
public bool idfaReading = true;
[HideInInspector]
public bool skanAttribution = true;
void Awake()
{
if (IsEditor())
{
return;
}
DontDestroyOnLoad(transform.gameObject);
// TODO: double-check the state of Unity on deep linking nowadays
#if UNITY_ANDROID && UNITY_2019_2_OR_NEWER
Application.deepLinkActivated += (deeplink) =>
{
Adjust.ProcessDeeplink(new AdjustDeeplink(deeplink));
};
if (!string.IsNullOrEmpty(Application.absoluteURL))
{
// cold start and Application.absoluteURL not null so process deep link
Adjust.ProcessDeeplink(new AdjustDeeplink(Application.absoluteURL));
}
#endif
if (!this.startManually)
{
AdjustConfig adjustConfig = new AdjustConfig(
this.appToken,
this.environment,
(this.logLevel == AdjustLogLevel.Suppress));
adjustConfig.LogLevel = this.logLevel;
adjustConfig.IsSendingInBackgroundEnabled = this.sendInBackground;
adjustConfig.IsDeferredDeeplinkOpeningEnabled = this.launchDeferredDeeplink;
adjustConfig.DefaultTracker = this.defaultTracker;
// TODO: URL strategy
adjustConfig.IsCoppaComplianceEnabled = this.coppaCompliance;
adjustConfig.IsCostDataInAttributionEnabled = this.costDataInAttribution;
adjustConfig.IsPreinstallTrackingEnabled = this.preinstallTracking;
adjustConfig.PreinstallFilePath = this.preinstallFilePath;
adjustConfig.IsAdServicesEnabled = this.adServices;
adjustConfig.IsIdfaReadingEnabled = this.idfaReading;
adjustConfig.IsLinkMeEnabled = this.linkMe;
adjustConfig.IsSkanAttributionEnabled = this.skanAttribution;
Adjust.InitSdk(adjustConfig);
}
}
public static void InitSdk(AdjustConfig adjustConfig)
{
if (IsEditor())
{
return;
}
if (adjustConfig == null)
{
Debug.Log("[Adjust]: Missing config to start.");
return;
}
#if UNITY_IOS
AdjustiOS.InitSdk(adjustConfig);
#elif UNITY_ANDROID
AdjustAndroid.InitSdk(adjustConfig);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void TrackEvent(AdjustEvent adjustEvent)
{
if (IsEditor())
{
return;
}
if (adjustEvent == null)
{
Debug.Log("[Adjust]: Missing event to track.");
return;
}
#if UNITY_IOS
AdjustiOS.TrackEvent(adjustEvent);
#elif UNITY_ANDROID
AdjustAndroid.TrackEvent(adjustEvent);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void Enable()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.Enable();
#elif UNITY_ANDROID
AdjustAndroid.Enable();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void Disable()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.Disable();
#elif UNITY_ANDROID
AdjustAndroid.Disable();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void IsEnabled(Action<bool> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.IsEnabled(callback);
#elif UNITY_ANDROID
AdjustAndroid.IsEnabled(callback);
#else
Debug.Log(errorMsgPlatform);
return;
#endif
}
public static void SwitchToOfflineMode()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.SwitchToOfflineMode();
#elif UNITY_ANDROID
AdjustAndroid.SwitchToOfflineMode();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void SwitchBackToOnlineMode()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.SwitchBackToOnlineMode();
#elif UNITY_ANDROID
AdjustAndroid.SwitchBackToOnlineMode();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void SetPushToken(string pushToken)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.SetPushToken(pushToken);
#elif UNITY_ANDROID
AdjustAndroid.SetPushToken(pushToken);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void GdprForgetMe()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.GdprForgetMe();
#elif UNITY_ANDROID
AdjustAndroid.GdprForgetMe();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void ProcessDeeplink(AdjustDeeplink deeplink)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.ProcessDeeplink(deeplink);
#elif UNITY_ANDROID
AdjustAndroid.ProcessDeeplink(deeplink);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void AddGlobalPartnerParameter(string key, string value)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.AddGlobalPartnerParameter(key, value);
#elif UNITY_ANDROID
AdjustAndroid.AddGlobalPartnerParameter(key, value);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void AddGlobalCallbackParameter(string key, string value)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.AddGlobalCallbackParameter(key, value);
#elif UNITY_ANDROID
AdjustAndroid.AddGlobalCallbackParameter(key, value);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void RemoveGlobalPartnerParameter(string key)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.RemoveGlobalPartnerParameter(key);
#elif UNITY_ANDROID
AdjustAndroid.RemoveGlobalPartnerParameter(key);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void RemoveGlobalCallbackParameter(string key)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.RemoveGlobalCallbackParameter(key);
#elif UNITY_ANDROID
AdjustAndroid.RemoveGlobalCallbackParameter(key);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void RemoveGlobalPartnerParameters()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.RemoveGlobalPartnerParameters();
#elif UNITY_ANDROID
AdjustAndroid.RemoveGlobalPartnerParameters();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void RemoveGlobalCallbackParameters()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.RemoveGlobalCallbackParameters();
#elif UNITY_ANDROID
AdjustAndroid.RemoveGlobalCallbackParameters();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void TrackAdRevenue(AdjustAdRevenue adRevenue)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.TrackAdRevenue(adRevenue);
#elif UNITY_ANDROID
AdjustAndroid.TrackAdRevenue(adRevenue);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void TrackAppStoreSubscription(AdjustAppStoreSubscription subscription)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.TrackAppStoreSubscription(subscription);
#elif UNITY_ANDROID
Debug.Log("[Adjust]: App Store subscription tracking is only supported for iOS platform.");
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void TrackPlayStoreSubscription(AdjustPlayStoreSubscription subscription)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
Debug.Log("[Adjust]: Play Store subscription tracking is only supported for Android platform.");
#elif UNITY_ANDROID
AdjustAndroid.TrackPlayStoreSubscription(subscription);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void TrackThirdPartySharing(AdjustThirdPartySharing thirdPartySharing)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.TrackThirdPartySharing(thirdPartySharing);
#elif UNITY_ANDROID
AdjustAndroid.TrackThirdPartySharing(thirdPartySharing);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void TrackMeasurementConsent(bool measurementConsent)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.TrackMeasurementConsent(measurementConsent);
#elif UNITY_ANDROID
AdjustAndroid.TrackMeasurementConsent(measurementConsent);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void RequestAppTrackingAuthorization(Action<int> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.RequestAppTrackingAuthorization(callback);
#elif UNITY_ANDROID
Debug.Log("[Adjust]: Requesting tracking authorization is only supported for iOS platform.");
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void UpdateSkanConversionValue(
int conversionValue,
string coarseValue,
bool lockWindow,
Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.UpdateSkanConversionValue(conversionValue, coarseValue, lockWindow, callback);
#elif UNITY_ANDROID
Debug.Log("[Adjust]: Updating SKAdNetwork conversion value is only supported for iOS platform.");
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static int GetAppTrackingAuthorizationStatus()
{
if (IsEditor())
{
return -1;
}
#if UNITY_IOS
return AdjustiOS.GetAppTrackingAuthorizationStatus();
#elif UNITY_ANDROID
Debug.Log("[Adjust]: Error! App tracking authorization status is only supported for iOS platform.");
return -1;
#else
Debug.Log(errorMsgPlatform);
return -1;
#endif
}
public static void GetAdid(Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.GetAdid(callback);
#elif UNITY_ANDROID
AdjustAndroid.GetAdid(callback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void GetAttribution(Action<AdjustAttribution> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.GetAttribution(callback);
#elif UNITY_ANDROID
AdjustAndroid.GetAttribution(callback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void GetIdfa(Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.GetIdfa(callback);
#elif UNITY_ANDROID
Debug.Log("[Adjust]: Error! IDFA is not available on Android platform.");
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void GetIdfv(Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.GetIdfv(callback);
#elif UNITY_ANDROID
Debug.Log("[Adjust]: Error! IDFV is not available on Android platform.");
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void GetGoogleAdId(Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
Debug.Log("[Adjust]: Error! Google Advertising ID is not available on iOS platform.");
#elif UNITY_ANDROID
AdjustAndroid.GetGoogleAdId(callback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void GetAmazonAdId(Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
Debug.Log("[Adjust]: Error! Amazon Fire Advertising ID is not available on iOS platform.");
#elif UNITY_ANDROID
AdjustAndroid.GetAmazonAdId(callback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void GetSdkVersion(Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.GetSdkVersion(callback);
#elif UNITY_ANDROID
AdjustAndroid.GetSdkVersion(callback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void GetLastDeeplink(Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.GetLastDeeplink(callback);
#elif UNITY_ANDROID
AdjustAndroid.GetLastDeeplink(callback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void VerifyAppStorePurchase(
AdjustAppStorePurchase purchase,
Action<AdjustPurchaseVerificationResult> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.VerifyAppStorePurchase(purchase, callback);
#elif UNITY_ANDROID
Debug.Log("[Adjust]: App Store purchase verification is only supported for iOS platform.");
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void VerifyPlayStorePurchase(
AdjustPlayStorePurchase purchase,
Action<AdjustPurchaseVerificationResult> verificationResultCallback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
Debug.Log("[Adjust]: Play Store purchase verification is only supported for Android platform.");
#elif UNITY_ANDROID
AdjustAndroid.VerifyPlayStorePurchase(purchase, verificationResultCallback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void ProcessAndResolveDeeplink(AdjustDeeplink deeplink, Action<string> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.ProcessAndResolveDeeplink(deeplink, callback);
#elif UNITY_ANDROID
AdjustAndroid.ProcessAndResolveDeeplink(deeplink, callback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void VerifyAndTrackAppStorePurchase(
AdjustEvent adjustEvent,
Action<AdjustPurchaseVerificationResult> callback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.VerifyAndTrackAppStorePurchase(adjustEvent, callback);
#elif UNITY_ANDROID
Debug.Log("[Adjust]: App Store purchase verification is only supported for iOS platform.");
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void VerifyAndTrackPlayStorePurchase(
AdjustEvent adjustEvent,
Action<AdjustPurchaseVerificationResult> verificationResultCallback)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
Debug.Log("[Adjust]: Play Store purchase verification is only supported for Android platform.");
#elif UNITY_ANDROID
AdjustAndroid.VerifyAndTrackPlayStorePurchase(adjustEvent, verificationResultCallback);
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void EndFirstSessionDelay()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.EndFirstSessionDelay();
#elif UNITY_ANDROID
AdjustAndroid.EndFirstSessionDelay();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void EnableCoppaComplianceInDelay()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.EnableCoppaComplianceInDelay();
#elif UNITY_ANDROID
AdjustAndroid.EnableCoppaComplianceInDelay();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void DisableCoppaComplianceInDelay()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.DisableCoppaComplianceInDelay();
#elif UNITY_ANDROID
AdjustAndroid.DisableCoppaComplianceInDelay();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void EnablePlayStoreKidsComplianceInDelay()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
Debug.Log("[Adjust]: Play Store kids feature is only supported for Android platform.");
#elif UNITY_ANDROID
AdjustAndroid.EnablePlayStoreKidsComplianceInDelay();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void DisablePlayStoreKidsComplianceInDelay()
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
Debug.Log("[Adjust]: Play Store kids feature is only supported for Android platform.");
#elif UNITY_ANDROID
AdjustAndroid.DisablePlayStoreKidsComplianceInDelay();
#else
Debug.Log(errorMsgPlatform);
#endif
}
public static void SetExternalDeviceIdInDelay(string externalDeviceId)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.SetExternalDeviceIdInDelay(externalDeviceId);
#elif UNITY_ANDROID
AdjustAndroid.SetExternalDeviceIdInDelay(externalDeviceId);
#else
Debug.Log(errorMsgPlatform);
#endif
}
private static bool IsEditor()
{
#if UNITY_EDITOR
Debug.Log(errorMsgEditor);
return true;
#else
return false;
#endif
}
public static void SetTestOptions(Dictionary<string, string> testOptions)
{
if (IsEditor())
{
return;
}
#if UNITY_IOS
AdjustiOS.SetTestOptions(testOptions);
#elif UNITY_ANDROID
AdjustAndroid.SetTestOptions(testOptions);
#else
Debug.Log("[Adjust]: Cannot run integration tests. None of the supported platforms selected.");
#endif
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 525ece82a472e4dea837e1ef938fd15d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,78 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AdjustSdk
{
public class AdjustAdRevenue
{
private List<string> innerCallbackParameters;
private List<string> innerPartnerParameters;
public string Source { get; private set; }
public double? Revenue { get; private set; }
public string Currency { get; private set; }
public int? AdImpressionsCount { get; set; }
public string AdRevenueNetwork { get; set; }
public string AdRevenueUnit { get; set; }
public string AdRevenuePlacement { get; set; }
public ReadOnlyCollection<string> CallbackParameters
{
get
{
if (innerCallbackParameters == null)
{
return null;
}
else
{
return innerCallbackParameters.AsReadOnly();
}
}
}
public ReadOnlyCollection<string> PartnerParameters
{
get
{
if (innerPartnerParameters == null)
{
return null;
}
else
{
return innerPartnerParameters.AsReadOnly();
}
}
}
public AdjustAdRevenue(string source)
{
this.Source = source;
}
public void SetRevenue(double revenue, string currency)
{
this.Revenue = revenue;
this.Currency = currency;
}
public void AddCallbackParameter(string key, string value)
{
if (this.innerCallbackParameters == null)
{
this.innerCallbackParameters = new List<string>();
}
this.innerCallbackParameters.Add(key);
this.innerCallbackParameters.Add(value);
}
public void AddPartnerParameter(string key, string value)
{
if (this.innerPartnerParameters == null)
{
this.innerPartnerParameters = new List<string>();
}
this.innerPartnerParameters.Add(key);
this.innerPartnerParameters.Add(value);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 776a9d4b715bc44c68724248a5a75cb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 04f57a99ef137445992d048a89c36788
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustAppStorePurchase
{
public string TransactionId { get; private set; }
public string ProductId { get; private set; }
public AdjustAppStorePurchase(string transactionId, string productId)
{
this.TransactionId = transactionId;
this.ProductId = productId;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 828a981c8c96741afa5d16ccb679e5af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,72 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AdjustSdk
{
public class AdjustAppStoreSubscription
{
private List<string> innerCallbackParameters;
private List<string> innerPartnerParameters;
public string Price { get; private set; }
public string Currency { get; private set; }
public string TransactionId { get; private set; }
public string TransactionDate { get; set; }
public string SalesRegion { get; set; }
public ReadOnlyCollection<string> CallbackParameters
{
get
{
if (innerCallbackParameters == null)
{
return null;
}
else
{
return innerCallbackParameters.AsReadOnly();
}
}
}
public ReadOnlyCollection<string> PartnerParameters
{
get
{
if (innerPartnerParameters == null)
{
return null;
}
else
{
return innerPartnerParameters.AsReadOnly();
}
}
}
public AdjustAppStoreSubscription(string price, string currency, string transactionId)
{
this.Price = price;
this.Currency = currency;
this.TransactionId = transactionId;
}
public void AddCallbackParameter(string key, string value)
{
if (this.innerCallbackParameters == null)
{
this.innerCallbackParameters = new List<string>();
}
this.innerCallbackParameters.Add(key);
this.innerCallbackParameters.Add(value);
}
public void AddPartnerParameter(string key, string value)
{
if (this.innerPartnerParameters == null)
{
this.innerPartnerParameters = new List<string>();
}
this.innerPartnerParameters.Add(key);
this.innerPartnerParameters.Add(value);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7e2d69221b1124370a4c016edce5a95a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustAttribution
{
public string TrackerToken { get; set; }
public string TrackerName { get; set; }
public string Network { get; set; }
public string Campaign { get; set; }
public string Adgroup { get; set; }
public string Creative { get; set; }
public string ClickLabel { get; set; }
public string CostType { get; set; }
public double? CostAmount { get; set; }
public string CostCurrency { get; set; }
public Dictionary<string, object> JsonResponse { get; set; }
// Android only
public string FbInstallReferrer { get; set; }
public AdjustAttribution() {}
public AdjustAttribution(string jsonString)
{
var jsonNode = JSON.Parse(jsonString);
if (jsonNode == null)
{
return;
}
this.TrackerName = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTrackerName);
this.TrackerToken = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTrackerToken);
this.Network = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyNetwork);
this.Campaign = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCampaign);
this.Adgroup = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdgroup);
this.Creative = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCreative);
this.ClickLabel = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyClickLabel);
this.CostType = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCostType);
try
{
this.CostAmount = double.Parse(
AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCostAmount),
System.Globalization.CultureInfo.InvariantCulture);
}
catch (Exception)
{
// attribution response doesn't contain cost amount attached
// value will default to null
}
this.CostCurrency = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCostCurrency);
this.FbInstallReferrer = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyFbInstallReferrer);
var jsonResponseValue = jsonNode[AdjustUtils.KeyJsonResponse];
if (jsonResponseValue == null)
{
return;
}
this.JsonResponse = AdjustUtils.GetAttributionJsonResponse(jsonResponseValue);
}
public AdjustAttribution(Dictionary<string, string> dicAttributionData)
{
if (dicAttributionData == null)
{
return;
}
this.TrackerName = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyTrackerName);
this.TrackerToken = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyTrackerToken);
this.Network = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyNetwork);
this.Campaign = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCampaign);
this.Adgroup = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyAdgroup);
this.Creative = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCreative);
this.ClickLabel = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyClickLabel);
this.CostType = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCostType);
try
{
this.CostAmount = double.Parse(
AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCostAmount),
System.Globalization.CultureInfo.InvariantCulture);
}
catch (Exception)
{
// attribution response doesn't contain cost amount attached
// value will default to null
}
this.CostCurrency = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCostCurrency);
this.FbInstallReferrer = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyFbInstallReferrer);
string jsonResponseString = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyJsonResponse);
var jsonResponseNode = JSON.Parse(jsonResponseString);
if (jsonResponseNode != null && jsonResponseNode.AsObject != null)
{
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, this.JsonResponse);
}
}
public void BuildJsonResponseFromString(string jsonResponseString)
{
var jsonNode = JSON.Parse(jsonResponseString);
if (jsonNode == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse);
}
public string GetJsonResponseAsString()
{
return AdjustUtils.GetJsonResponseCompact(JsonResponse);
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cc46748ad0e664f6d839a4f1a23d9f47
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustConfig
{
public string AppToken { get; private set; }
public string DefaultTracker { get; set; }
public string ExternalDeviceId { get; set; }
public bool? IsCoppaComplianceEnabled { get; set; }
public bool? IsSendingInBackgroundEnabled { get; set; }
public bool? IsCostDataInAttributionEnabled { get; set; }
public bool? IsDeviceIdsReadingOnceEnabled { get; set; }
public bool? IsDeferredDeeplinkOpeningEnabled { get; set; }
public bool? IsAppTrackingTransparencyUsageEnabled { get; set; }
public bool? IsFirstSessionDelayEnabled { get; set; }
public bool? AllowSuppressLogLevel { get; private set; }
public bool? IsDataResidency { get; private set; }
public bool? ShouldUseSubdomains { get; private set; }
public int? EventDeduplicationIdsMaxSize { get; set; }
public List<string> UrlStrategyDomains { get; private set; }
public AdjustLogLevel? LogLevel { get; set; }
public AdjustEnvironment Environment { get; private set; }
public AdjustStoreInfo StoreInfo { get; set; }
public Action<AdjustAttribution> AttributionChangedDelegate { get; set; }
public Action<AdjustEventSuccess> EventSuccessDelegate { get; set; }
public Action<AdjustEventFailure> EventFailureDelegate { get; set; }
public Action<AdjustSessionSuccess> SessionSuccessDelegate { get; set; }
public Action<AdjustSessionFailure> SessionFailureDelegate { get; set; }
public Action<string> DeferredDeeplinkDelegate { get; set; }
public Action<Dictionary<string, string>> SkanUpdatedDelegate { get; set; }
// iOS specific
public bool? IsAdServicesEnabled { get; set; }
public bool? IsIdfaReadingEnabled { get; set; }
public bool? IsIdfvReadingEnabled { get; set; }
public bool? IsSkanAttributionEnabled { get; set; }
public bool? IsLinkMeEnabled { get; set; }
public int? AttConsentWaitingInterval { get; set; }
// Android specific
public bool? IsPlayStoreKidsComplianceEnabled { get; set; }
public bool? IsPreinstallTrackingEnabled { get; set; }
public string PreinstallFilePath { get; set; }
public string FbAppId { get; set; }
public AdjustConfig(string appToken, AdjustEnvironment environment)
{
this.AppToken = appToken;
this.Environment = environment;
}
public AdjustConfig(string appToken, AdjustEnvironment environment, bool allowSuppressLogLevel)
{
this.AppToken = appToken;
this.Environment = environment;
this.AllowSuppressLogLevel = allowSuppressLogLevel;
}
public void SetUrlStrategy(
List<string> urlStrategyDomains,
bool shouldUseSubdomains,
bool isDataResidency)
{
this.UrlStrategyDomains = urlStrategyDomains;
this.ShouldUseSubdomains = shouldUseSubdomains;
this.IsDataResidency = isDataResidency;
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 02d4cad14fc094b17afde3b685897e5e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,15 @@
using System;
namespace AdjustSdk
{
public class AdjustDeeplink
{
public string Deeplink { get; private set; }
public string Referrer { get; set; }
public AdjustDeeplink(string deeplink)
{
this.Deeplink = deeplink;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40e25efef61754d66a47cd3e62a7f6bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,25 @@
namespace AdjustSdk
{
[System.Serializable]
public enum AdjustEnvironment
{
Sandbox,
Production
}
public static class AdjustEnvironmentExtension
{
public static string ToLowercaseString(this AdjustEnvironment adjustEnvironment)
{
switch (adjustEnvironment)
{
case AdjustEnvironment.Sandbox:
return "sandbox";
case AdjustEnvironment.Production:
return "production";
default:
return "unknown";
}
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 633f6fa279b2244fdb999db0441f9aac
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,81 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AdjustSdk
{
public class AdjustEvent
{
private List<string> innerCallbackParameters;
private List<string> innerPartnerParameters;
public string EventToken { get; private set; }
public double? Revenue { get; private set; }
public string Currency { get; private set; }
public string CallbackId { get; set; }
public string DeduplicationId { get; set; }
public string ProductId { get; set; }
public ReadOnlyCollection<string> CallbackParameters
{
get
{
if (innerCallbackParameters == null)
{
return null;
}
else
{
return innerCallbackParameters.AsReadOnly();
}
}
}
public ReadOnlyCollection<string> PartnerParameters
{
get
{
if (innerPartnerParameters == null)
{
return null;
}
else
{
return innerPartnerParameters.AsReadOnly();
}
}
}
// ios specific
public string TransactionId { get; set; }
// android specific
public string PurchaseToken;
public AdjustEvent(string eventToken)
{
this.EventToken = eventToken;
}
public void SetRevenue(double amount, string currency)
{
this.Revenue = amount;
this.Currency = currency;
}
public void AddCallbackParameter(string key, string value)
{
if (this.innerCallbackParameters == null)
{
this.innerCallbackParameters = new List<string>();
}
this.innerCallbackParameters.Add(key);
this.innerCallbackParameters.Add(value);
}
public void AddPartnerParameter(string key, string value)
{
if (this.innerPartnerParameters == null)
{
this.innerPartnerParameters = new List<string>();
}
this.innerPartnerParameters.Add(key);
this.innerPartnerParameters.Add(value);
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cd89f7713977f497a862f1a1b6f60933
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustEventFailure
{
public string Adid { get; set; }
public string Message { get; set; }
public string Timestamp { get; set; }
public string EventToken { get; set; }
public string CallbackId { get; set; }
public bool WillRetry { get; set; }
public Dictionary<string, object> JsonResponse { get; set; }
public AdjustEventFailure() {}
public AdjustEventFailure(Dictionary<string, string> eventFailureDataMap)
{
if (eventFailureDataMap == null)
{
return;
}
this.Adid = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyAdid);
this.Message = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyMessage);
this.Timestamp = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyTimestamp);
this.EventToken = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyEventToken);
this.CallbackId = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyCallbackId);
bool willRetry;
if (bool.TryParse(AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyWillRetry), out willRetry))
{
this.WillRetry = willRetry;
}
string jsonResponseString = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyJsonResponse);
var jsonResponseNode = JSON.Parse(jsonResponseString);
if (jsonResponseNode != null && jsonResponseNode.AsObject != null)
{
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse);
}
}
public AdjustEventFailure(string jsonString)
{
var jsonNode = JSON.Parse(jsonString);
if (jsonNode == null)
{
return;
}
this.Adid = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdid);
this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage);
this.Timestamp = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTimestamp);
this.EventToken = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyEventToken);
this.CallbackId = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCallbackId);
this.WillRetry = Convert.ToBoolean(AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyWillRetry));
var jsonResponseNode = jsonNode[AdjustUtils.KeyJsonResponse];
if (jsonResponseNode == null)
{
return;
}
if (jsonResponseNode.AsObject == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse);
}
public void BuildJsonResponseFromString(string jsonResponseString)
{
var jsonNode = JSON.Parse(jsonResponseString);
if (jsonNode == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse);
}
public string GetJsonResponseAsString()
{
return AdjustUtils.GetJsonResponseCompact(JsonResponse);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ea86cd4e1c6d0496397920902d0f0b5f
timeCreated: 1458128791
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustEventSuccess
{
public string Adid { get; set; }
public string Message { get; set; }
public string Timestamp { get; set; }
public string EventToken { get; set; }
public string CallbackId { get; set; }
public Dictionary<string, object> JsonResponse { get; set; }
public AdjustEventSuccess() {}
public AdjustEventSuccess(Dictionary<string, string> eventSuccessDataMap)
{
if (eventSuccessDataMap == null)
{
return;
}
this.Adid = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyAdid);
this.Message = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyMessage);
this.Timestamp = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyTimestamp);
this.EventToken = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyEventToken);
this.CallbackId = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyCallbackId);
string jsonResponseString = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyJsonResponse);
var jsonResponseNode = JSON.Parse(jsonResponseString);
if (jsonResponseNode != null && jsonResponseNode.AsObject != null)
{
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse);
}
}
public AdjustEventSuccess(string jsonString)
{
var jsonNode = JSON.Parse(jsonString);
if (jsonNode == null)
{
return;
}
this.Adid = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdid);
this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage);
this.Timestamp = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTimestamp);
this.EventToken = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyEventToken);
this.CallbackId = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCallbackId);
var jsonResponseNode = jsonNode[AdjustUtils.KeyJsonResponse];
if (jsonResponseNode == null)
{
return;
}
if (jsonResponseNode.AsObject == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse);
}
public void BuildJsonResponseFromString(string jsonResponseString)
{
var jsonNode = JSON.Parse(jsonResponseString);
if (jsonNode == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse);
}
public string GetJsonResponseAsString()
{
return AdjustUtils.GetJsonResponseCompact(JsonResponse);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1957a0e6e9aa14f0e8adefa2120f1e02
timeCreated: 1458128791
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,63 @@
namespace AdjustSdk
{
[System.Serializable]
public enum AdjustLogLevel
{
Verbose = 1,
Debug,
Info,
Warn,
Error,
Assert,
Suppress
}
public static class AdjustLogLevelExtension
{
public static string ToLowercaseString(this AdjustLogLevel AdjustLogLevel)
{
switch (AdjustLogLevel)
{
case AdjustLogLevel.Verbose:
return "verbose";
case AdjustLogLevel.Debug:
return "debug";
case AdjustLogLevel.Info:
return "info";
case AdjustLogLevel.Warn:
return "warn";
case AdjustLogLevel.Error:
return "error";
case AdjustLogLevel.Assert:
return "assert";
case AdjustLogLevel.Suppress:
return "suppress";
default:
return "unknown";
}
}
public static string ToUppercaseString(this AdjustLogLevel AdjustLogLevel)
{
switch (AdjustLogLevel)
{
case AdjustLogLevel.Verbose:
return "VERBOSE";
case AdjustLogLevel.Debug:
return "DEBUG";
case AdjustLogLevel.Info:
return "INFO";
case AdjustLogLevel.Warn:
return "WARN";
case AdjustLogLevel.Error:
return "ERROR";
case AdjustLogLevel.Assert:
return "ASSERT";
case AdjustLogLevel.Suppress:
return "SUPPRESS";
default:
return "UNKNOWN";
}
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 428ab44990df24973902248a9d2b43dd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustPlayStorePurchase
{
public string ProductId { get; private set; }
public string PurchaseToken { get; private set; }
public AdjustPlayStorePurchase(string productId, string purchaseToken)
{
this.ProductId = productId;
this.PurchaseToken = purchaseToken;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d875a71a5aeb1496d93afac749ab17f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,83 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AdjustSdk
{
public class AdjustPlayStoreSubscription
{
private List<string> innerCallbackParameters;
private List<string> innerPartnerParameters;
public string Price { get; private set; }
public string Currency { get; private set; }
public string ProductId { get; private set; }
public string OrderId { get; private set; }
public string Signature { get; private set; }
public string PurchaseToken { get; private set; }
public string PurchaseTime { get; set; }
public ReadOnlyCollection<string> CallbackParameters
{
get
{
if (innerCallbackParameters == null)
{
return null;
}
else
{
return innerCallbackParameters.AsReadOnly();
}
}
}
public ReadOnlyCollection<string> PartnerParameters
{
get
{
if (innerPartnerParameters == null)
{
return null;
}
else
{
return innerPartnerParameters.AsReadOnly();
}
}
}
public AdjustPlayStoreSubscription(
string price,
string currency,
string productId,
string orderId,
string signature,
string purchaseToken)
{
this.Price = price;
this.Currency = currency;
this.ProductId = productId;
this.OrderId = orderId;
this.Signature = signature;
this.PurchaseToken = purchaseToken;
}
public void AddCallbackParameter(string key, string value)
{
if (this.innerCallbackParameters == null)
{
this.innerCallbackParameters = new List<string>();
}
this.innerCallbackParameters.Add(key);
this.innerCallbackParameters.Add(value);
}
public void AddPartnerParameter(string key, string value)
{
if (this.innerPartnerParameters == null)
{
this.innerPartnerParameters = new List<string>();
}
this.innerPartnerParameters.Add(key);
this.innerPartnerParameters.Add(value);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 69e7a4074abb44758b3f011d8352a57a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,27 @@
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustPurchaseVerificationResult
{
public int Code { get; set; }
public string Message { get; set; }
public string VerificationStatus { get; set; }
public AdjustPurchaseVerificationResult() {}
public AdjustPurchaseVerificationResult(string jsonString)
{
var jsonNode = JSON.Parse(jsonString);
if (jsonNode == null)
{
return;
}
string strCode = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCode);
this.Code = int.Parse(strCode);
this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage);
this.VerificationStatus = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyVerificationStatus);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cbd451b59ec374fa7b72f226b1cef0b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,6 @@
{
"name": "AdjustSdk.Scripts",
"references": [],
"includePlatforms": [],
"excludePlatforms": []
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7d8924c6e6beb44e18f19e8c0b5068cd
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustSessionFailure
{
public string Adid { get; set; }
public string Message { get; set; }
public string Timestamp { get; set; }
public bool WillRetry { get; set; }
public Dictionary<string, object> JsonResponse { get; set; }
public AdjustSessionFailure() {}
public AdjustSessionFailure(Dictionary<string, string> sessionFailureDataMap)
{
if (sessionFailureDataMap == null)
{
return;
}
this.Adid = AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyAdid);
this.Message = AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyMessage);
this.Timestamp = AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyTimestamp);
bool willRetry;
if (bool.TryParse(AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyWillRetry), out willRetry))
{
this.WillRetry = willRetry;
}
string jsonResponseString = AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyJsonResponse);
var jsonResponseNode = JSON.Parse(jsonResponseString);
if (jsonResponseNode != null && jsonResponseNode.AsObject != null)
{
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse);
}
}
public AdjustSessionFailure(string jsonString)
{
var jsonNode = JSON.Parse(jsonString);
if (jsonNode == null)
{
return;
}
this.Adid = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdid);
this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage);
this.Timestamp = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTimestamp);
this.WillRetry = Convert.ToBoolean(AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyWillRetry));
var jsonResponseNode = jsonNode[AdjustUtils.KeyJsonResponse];
if (jsonResponseNode == null)
{
return;
}
if (jsonResponseNode.AsObject == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse);
}
public void BuildJsonResponseFromString(string jsonResponseString)
{
var jsonNode = JSON.Parse(jsonResponseString);
if (jsonNode == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse);
}
public string GetJsonResponseAsString()
{
return AdjustUtils.GetJsonResponseCompact(JsonResponse);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b4de268ab985448a594fb82264190742
timeCreated: 1458128791
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,77 @@
using System.Collections.Generic;
namespace AdjustSdk
{
public class AdjustSessionSuccess
{
public string Adid { get; set; }
public string Message { get; set; }
public string Timestamp { get; set; }
public Dictionary<string, object> JsonResponse { get; set; }
public AdjustSessionSuccess() {}
public AdjustSessionSuccess(Dictionary<string, string> sessionSuccessDataMap)
{
if (sessionSuccessDataMap == null)
{
return;
}
this.Adid = AdjustUtils.TryGetValue(sessionSuccessDataMap, AdjustUtils.KeyAdid);
this.Message = AdjustUtils.TryGetValue(sessionSuccessDataMap, AdjustUtils.KeyMessage);
this.Timestamp = AdjustUtils.TryGetValue(sessionSuccessDataMap, AdjustUtils.KeyTimestamp);
string jsonResponseString = AdjustUtils.TryGetValue(sessionSuccessDataMap, AdjustUtils.KeyJsonResponse);
var jsonResponseNode = JSON.Parse(jsonResponseString);
if (jsonResponseNode != null && jsonResponseNode.AsObject != null)
{
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse);
}
}
public AdjustSessionSuccess(string jsonString)
{
var jsonNode = JSON.Parse(jsonString);
if (jsonNode == null)
{
return;
}
this.Adid = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdid);
this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage);
this.Timestamp = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTimestamp);
var jsonResponseNode = jsonNode[AdjustUtils.KeyJsonResponse];
if (jsonResponseNode == null)
{
return;
}
if (jsonResponseNode.AsObject == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse);
}
public void BuildJsonResponseFromString(string jsonResponseString)
{
var jsonNode = JSON.Parse(jsonResponseString);
if (jsonNode == null)
{
return;
}
this.JsonResponse = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse);
}
public string GetJsonResponseAsString()
{
return AdjustUtils.GetJsonResponseCompact(JsonResponse);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c23847e7a1f464d7a8c7f9b35829af17
timeCreated: 1458128791
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,15 @@
using System;
namespace AdjustSdk
{
public class AdjustStoreInfo
{
public string StoreName { get; private set; }
public string StoreAppId { get; set; }
public AdjustStoreInfo(string storeName)
{
this.StoreName = storeName;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 09215b0ccf65143ae91e6fa6cdca34b9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,68 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AdjustSdk
{
public class AdjustThirdPartySharing
{
private List<string> innerGranularOptions;
private List<string> innerPartnerSharingSettings;
public bool? IsEnabled { get; private set; }
public ReadOnlyCollection<string> GranularOptions
{
get
{
if (innerGranularOptions == null)
{
return null;
}
else
{
return innerGranularOptions.AsReadOnly();
}
}
}
public ReadOnlyCollection<string> PartnerSharingSettings
{
get
{
if (innerPartnerSharingSettings == null)
{
return null;
}
else
{
return innerPartnerSharingSettings.AsReadOnly();
}
}
}
public AdjustThirdPartySharing(bool? isEnabled)
{
this.IsEnabled = isEnabled;
}
public void AddGranularOption(string partnerName, string key, string value)
{
if (this.innerGranularOptions == null)
{
this.innerGranularOptions = new List<string>();
}
this.innerGranularOptions.Add(partnerName);
this.innerGranularOptions.Add(key);
this.innerGranularOptions.Add(value);
}
public void AddPartnerSharingSetting(string partnerName, string key, bool value)
{
if (this.innerPartnerSharingSettings == null)
{
this.innerPartnerSharingSettings = new List<string>();
}
this.innerPartnerSharingSettings.Add(partnerName);
this.innerPartnerSharingSettings.Add(key);
this.innerPartnerSharingSettings.Add(value.ToString());
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dcb2591dfab904327904b8879af699ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using UnityEngine;
public class AdjustThreadDispatcher : MonoBehaviour
{
private static readonly Queue<Action> executionQueue = new Queue<Action>();
private static AdjustThreadDispatcher instance;
public static void RunOnMainThread(Action action)
{
if (action == null)
{
return;
}
lock (executionQueue)
{
executionQueue.Enqueue(action);
}
}
private void Update()
{
while (executionQueue.Count > 0)
{
Action action;
lock (executionQueue)
{
action = executionQueue.Dequeue();
}
if (action != null)
{
action.Invoke();
}
}
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Initialize()
{
if (instance == null)
{
GameObject obj = new GameObject("AdjustThreadDispatcher");
instance = obj.AddComponent<AdjustThreadDispatcher>();
DontDestroyOnLoad(obj);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 068759bba95d0411895637c9165b2f99
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,448 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
namespace AdjustSdk
{
public class AdjustUtils
{
public static string KeyAdid = "adid";
public static string KeyMessage = "message";
public static string KeyNetwork = "network";
public static string KeyAdgroup = "adgroup";
public static string KeyCampaign = "campaign";
public static string KeyCreative = "creative";
public static string KeyWillRetry = "willRetry";
public static string KeyTimestamp = "timestamp";
public static string KeyCallbackId = "callbackId";
public static string KeyEventToken = "eventToken";
public static string KeyClickLabel = "clickLabel";
public static string KeyTrackerName = "trackerName";
public static string KeyTrackerToken = "trackerToken";
public static string KeyJsonResponse = "jsonResponse";
public static string KeyCostType = "costType";
public static string KeyCostAmount = "costAmount";
public static string KeyCostCurrency = "costCurrency";
public static string KeyFbInstallReferrer = "fbInstallReferrer";
public static string KeySkanConversionValue = "fineValue";
public static string KeySkanCoarseValue = "coarseValue";
public static string KeySkanLockWindow = "lockWindow";
public static string KeyCode = "code";
public static string KeyVerificationStatus = "verificationStatus";
// For testing purposes.
public static string KeyTestOptionsBaseUrl = "baseUrl";
public static string KeyTestOptionsGdprUrl = "gdprUrl";
public static string KeyTestOptionsSubscriptionUrl = "subscriptionUrl";
public static string KeyTestOptionsPurchaseVerificationUrl = "purchaseVerificationUrl";
public static string KeyTestOptionsOverwriteUrl = "urlOverwrite";
public static string KeyTestOptionsExtraPath = "extraPath";
public static string KeyTestOptionsBasePath = "basePath";
public static string KeyTestOptionsGdprPath = "gdprPath";
public static string KeyTestOptionsDeleteState = "deleteState";
public static string KeyTestOptionsUseTestConnectionOptions = "useTestConnectionOptions";
public static string KeyTestOptionsTimerIntervalInMilliseconds = "timerIntervalInMilliseconds";
public static string KeyTestOptionsTimerStartInMilliseconds = "timerStartInMilliseconds";
public static string KeyTestOptionsSessionIntervalInMilliseconds = "sessionIntervalInMilliseconds";
public static string KeyTestOptionsSubsessionIntervalInMilliseconds = "subsessionIntervalInMilliseconds";
public static string KeyTestOptionsTeardown = "teardown";
public static string KeyTestOptionsNoBackoffWait = "noBackoffWait";
public static string KeyTestOptionsAdServicesFrameworkEnabled = "adServicesFrameworkEnabled";
public static string KeyTestOptionsAttStatus = "attStatus";
public static string KeyTestOptionsIdfa = "idfa";
public static string KeyTestOptionsIgnoreSystemLifecycleBootstrap = "ignoreSystemLifecycleBootstrap";
public static int ConvertLogLevel(AdjustLogLevel? logLevel)
{
if (logLevel == null)
{
return -1;
}
return (int)logLevel;
}
public static int ConvertBool(bool? value)
{
if (value == null)
{
return -1;
}
if (value.Value)
{
return 1;
}
else
{
return 0;
}
}
public static double ConvertDouble(double? value)
{
if (value == null)
{
return -1;
}
return (double)value;
}
public static int ConvertInt(int? value)
{
if (value == null)
{
return -1;
}
return (int)value;
}
public static long ConvertLong(long? value)
{
if (value == null)
{
return -1;
}
return (long)value;
}
public static string ConvertReadOnlyCollectionToJson(ReadOnlyCollection<string> list)
{
if (list == null)
{
return null;
}
List<string> processedList = new List<string>();
for (int i = 0; i < list.Count; i += 1)
{
string item = list[i];
if (item == null)
{
continue;
}
processedList.Add(item);
}
// create JSON array
var jsonArray = new JSONArray();
foreach (var listItem in processedList)
{
jsonArray.Add(new JSONData(listItem));
}
return jsonArray.ToString();
}
public static string ConvertReadOnlyCollectionOfPairsToJson(ReadOnlyCollection<string> list)
{
if (list == null)
{
return null;
}
// list of callback / partner parameters must contain even number of elements
if (list.Count % 2 != 0)
{
return null;
}
List<string> processedList = new List<string>();
for (int i = 0; i < list.Count; i += 2)
{
string key = list[i];
string value = list[i + 1];
if (key == null || value == null)
{
continue;
}
processedList.Add(key);
processedList.Add(value);
}
// create JSON array
var jsonArray = new JSONArray();
foreach (var listItem in processedList)
{
jsonArray.Add(new JSONData(listItem));
}
return jsonArray.ToString();
}
public static string ConvertReadOnlyCollectionOfTripletsToJson(ReadOnlyCollection<string> list)
{
if (list == null)
{
return null;
}
// list of third party sharing parameters must contain number of elements divisible by 3
if (list.Count % 3 != 0)
{
return null;
}
List<string> processedList = new List<string>();
for (int i = 0; i < list.Count; i += 3)
{
string partnerName = list[i];
string key = list[i + 1];
string value = list[i + 2];
if (partnerName == null || key == null || value == null)
{
continue;
}
processedList.Add(partnerName);
processedList.Add(key);
processedList.Add(value);
}
// create JSON array
var jsonArray = new JSONArray();
foreach (var listItem in processedList)
{
jsonArray.Add(new JSONData(listItem));
}
return jsonArray.ToString();
}
public static string GetJsonResponseCompact(Dictionary<string, object> dictionary)
{
string logJsonResponse = "";
if (dictionary == null)
{
return logJsonResponse;
}
else
{
int preLoopCounter = 0;
logJsonResponse += "{";
foreach (KeyValuePair<string, object> pair in dictionary)
{
string valueString = pair.Value as string;
if (valueString != null)
{
if (++preLoopCounter > 1)
{
logJsonResponse += ",";
}
// if the value is another JSON/complex-structure
if (valueString.StartsWith("{") && valueString.EndsWith("}"))
{
logJsonResponse += "\"" + pair.Key + "\"" + ":" + valueString;
}
else
{
logJsonResponse += "\"" + pair.Key + "\"" + ":" + "\"" + valueString + "\"";
}
continue;
}
Dictionary<string, object> valueDictionary = pair.Value as Dictionary<string, object>;
if (++preLoopCounter > 1)
{
logJsonResponse += ",";
}
logJsonResponse += "\"" + pair.Key + "\"" + ":";
logJsonResponse += GetJsonResponseCompact(valueDictionary);
}
logJsonResponse += "}";
}
return logJsonResponse;
}
public static string GetJsonString(JSONNode node, string key)
{
if (node == null)
{
return null;
}
// Access value object and cast it to JSONData.
var nodeValue = node[key] as JSONData;
if (nodeValue == null)
{
return null;
}
// https://github.com/adjust/unity_sdk/issues/137
if (nodeValue == "")
{
return null;
}
return nodeValue.Value;
}
public static void WriteJsonResponseDictionary(JSONClass jsonObject, Dictionary<string, object> output)
{
foreach (KeyValuePair<string, JSONNode> pair in jsonObject)
{
// Try to cast value as a complex object.
var subNode = pair.Value.AsObject;
var key = pair.Key;
// Value is not a complex object.
if (subNode == null)
{
var value = pair.Value.Value;
output.Add(key, value);
continue;
}
// Create new dictionary for complex type.
var newSubDictionary = new Dictionary<string, object>();
// Save it in the current dictionary.
output.Add(key, newSubDictionary);
// Recursive call to fill new dictionary.
WriteJsonResponseDictionary(subNode, newSubDictionary);
}
}
public static string TryGetValue(Dictionary<string, string> dictionary, string key)
{
string value;
if (dictionary.TryGetValue(key, out value))
{
// https://github.com/adjust/unity_sdk/issues/137
if (value == "")
{
return null;
}
return value;
}
return null;
}
public static Dictionary<string, string> GetSkanUpdateDataDictionary(string skanUpdateData)
{
Dictionary<string, string> skanUpdateDataDictionary = new Dictionary<string, string>();
var skanUpdateDataNode = JSON.Parse(skanUpdateData);
if (skanUpdateDataNode != null && skanUpdateDataNode.AsObject != null)
{
Dictionary<string, object> temp = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(skanUpdateDataNode.AsObject, temp);
foreach (KeyValuePair<string, object> entry in temp)
{
skanUpdateDataDictionary.Add(entry.Key, entry.Value.ToString());
}
}
return skanUpdateDataDictionary;
}
public static Dictionary<string, object> GetAttributionJsonResponse(string attributionJsonResponse)
{
Dictionary<string, object> attributionJsonResponseDictionary = new Dictionary<string, object>();
var attributionJsonResponseNode = JSON.Parse(attributionJsonResponse);
if (attributionJsonResponseNode != null && attributionJsonResponseNode.AsObject != null)
{
Dictionary<string, object> temp = new Dictionary<string, object>();
AdjustUtils.WriteJsonResponseDictionary(attributionJsonResponseNode.AsObject, temp);
foreach (KeyValuePair<string, object> entry in temp)
{
attributionJsonResponseDictionary.Add(entry.Key, entry.Value);
}
}
return attributionJsonResponseDictionary;
}
public static string GetValueOrEmptyToNull(string value)
{
return string.IsNullOrEmpty(value) ? null : value;
}
#if UNITY_ANDROID
public static AndroidJavaObject TestOptionsMap2AndroidJavaObject(Dictionary<string, string> testOptionsMap, AndroidJavaObject ajoCurrentActivity)
{
AndroidJavaObject ajoTestOptions = new AndroidJavaObject("com.adjust.sdk.AdjustTestOptions");
ajoTestOptions.Set<string>("baseUrl", testOptionsMap[KeyTestOptionsBaseUrl]);
ajoTestOptions.Set<string>("gdprUrl", testOptionsMap[KeyTestOptionsGdprUrl]);
ajoTestOptions.Set<string>("subscriptionUrl", testOptionsMap[KeyTestOptionsSubscriptionUrl]);
ajoTestOptions.Set<string>("purchaseVerificationUrl", testOptionsMap[KeyTestOptionsPurchaseVerificationUrl]);
if (testOptionsMap.ContainsKey(KeyTestOptionsExtraPath) && !string.IsNullOrEmpty(testOptionsMap[KeyTestOptionsExtraPath]))
{
ajoTestOptions.Set<string>("basePath", testOptionsMap[KeyTestOptionsExtraPath]);
ajoTestOptions.Set<string>("gdprPath", testOptionsMap[KeyTestOptionsExtraPath]);
ajoTestOptions.Set<string>("subscriptionPath", testOptionsMap[KeyTestOptionsExtraPath]);
ajoTestOptions.Set<string>("purchaseVerificationPath", testOptionsMap[KeyTestOptionsExtraPath]);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsDeleteState) && ajoCurrentActivity != null)
{
ajoTestOptions.Set<AndroidJavaObject>("context", ajoCurrentActivity);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsUseTestConnectionOptions))
{
bool useTestConnectionOptions = testOptionsMap[KeyTestOptionsUseTestConnectionOptions].ToLower() == "true";
AndroidJavaObject ajoUseTestConnectionOptions = new AndroidJavaObject("java.lang.Boolean", useTestConnectionOptions);
ajoTestOptions.Set<AndroidJavaObject>("useTestConnectionOptions", ajoUseTestConnectionOptions);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsTimerIntervalInMilliseconds))
{
var timerIntervalInMilliseconds = long.Parse(testOptionsMap[KeyTestOptionsTimerIntervalInMilliseconds]);
AndroidJavaObject ajoTimerIntervalInMilliseconds = new AndroidJavaObject("java.lang.Long", timerIntervalInMilliseconds);
ajoTestOptions.Set<AndroidJavaObject>("timerIntervalInMilliseconds", ajoTimerIntervalInMilliseconds);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsTimerStartInMilliseconds))
{
var timerStartInMilliseconds = long.Parse(testOptionsMap[KeyTestOptionsTimerStartInMilliseconds]);
AndroidJavaObject ajoTimerStartInMilliseconds = new AndroidJavaObject("java.lang.Long", timerStartInMilliseconds);
ajoTestOptions.Set<AndroidJavaObject>("timerStartInMilliseconds", ajoTimerStartInMilliseconds);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsSessionIntervalInMilliseconds))
{
var sessionIntervalInMilliseconds = long.Parse(testOptionsMap[KeyTestOptionsSessionIntervalInMilliseconds]);
AndroidJavaObject ajoSessionIntervalInMilliseconds = new AndroidJavaObject("java.lang.Long", sessionIntervalInMilliseconds);
ajoTestOptions.Set<AndroidJavaObject>("sessionIntervalInMilliseconds", ajoSessionIntervalInMilliseconds);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsSubsessionIntervalInMilliseconds))
{
var subsessionIntervalInMilliseconds = long.Parse(testOptionsMap[KeyTestOptionsSubsessionIntervalInMilliseconds]);
AndroidJavaObject ajoSubsessionIntervalInMilliseconds = new AndroidJavaObject("java.lang.Long", subsessionIntervalInMilliseconds);
ajoTestOptions.Set<AndroidJavaObject>("subsessionIntervalInMilliseconds", ajoSubsessionIntervalInMilliseconds);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsTeardown))
{
bool teardown = testOptionsMap[KeyTestOptionsTeardown].ToLower() == "true";
AndroidJavaObject ajoTeardown = new AndroidJavaObject("java.lang.Boolean", teardown);
ajoTestOptions.Set<AndroidJavaObject>("teardown", ajoTeardown);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsNoBackoffWait))
{
bool noBackoffWait = testOptionsMap[KeyTestOptionsNoBackoffWait].ToLower() == "true";
AndroidJavaObject ajoNoBackoffWait = new AndroidJavaObject("java.lang.Boolean", noBackoffWait);
ajoTestOptions.Set<AndroidJavaObject>("noBackoffWait", ajoNoBackoffWait);
}
if (testOptionsMap.ContainsKey(KeyTestOptionsIgnoreSystemLifecycleBootstrap))
{
// TODO: fix native logic not to have negation in naming throughout the chain of calls
bool doNotIgnoreSystemLifecycleBootstrap = testOptionsMap[KeyTestOptionsIgnoreSystemLifecycleBootstrap].ToLower() == "true";
AndroidJavaObject ajoDoNotIgnoreSystemLifecycleBootstrap = new AndroidJavaObject("java.lang.Boolean", doNotIgnoreSystemLifecycleBootstrap);
ajoTestOptions.Set<AndroidJavaObject>("ignoreSystemLifecycleBootstrap", ajoDoNotIgnoreSystemLifecycleBootstrap);
}
return ajoTestOptions;
}
#endif
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 98e51a1481cc24ddebf93f61f6c1eb9d
timeCreated: 1458230617
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1b9e944cddaba4b74b96cf2c01f5aee3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fd79158f62f184079b58f414302dd242
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.SceneManagement;
using UnityEditor;
namespace AdjustSdk
{
[CustomEditor(typeof(Adjust))]
public class AdjustCustomEditor : Editor
{
private Editor settingsEditor;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
var adjust = target as Adjust;
GUIStyle darkerCyanTextFieldStyles = new GUIStyle(EditorStyles.boldLabel);
darkerCyanTextFieldStyles.normal.textColor = new Color(0f/255f, 190f/255f, 190f/255f);
// Not gonna ask: http://answers.unity.com/answers/1244650/view.html
EditorGUILayout.Space();
var origFontStyle = EditorStyles.label.fontStyle;
EditorStyles.label.fontStyle = FontStyle.Bold;
adjust.startManually = EditorGUILayout.Toggle("START SDK MANUALLY", adjust.startManually, EditorStyles.toggle);
EditorStyles.label.fontStyle = origFontStyle;
using (new EditorGUI.DisabledScope(adjust.startManually))
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("MULTIPLATFORM SETTINGS:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
adjust.appToken = EditorGUILayout.TextField("App Token", adjust.appToken);
adjust.environment = (AdjustEnvironment)EditorGUILayout.EnumPopup("Environment", adjust.environment);
adjust.logLevel = (AdjustLogLevel)EditorGUILayout.EnumPopup("Log Level", adjust.logLevel);
// TODO: URL strategy missing
adjust.sendInBackground = EditorGUILayout.Toggle("Send In Background", adjust.sendInBackground);
adjust.launchDeferredDeeplink = EditorGUILayout.Toggle("Launch Deferred Deep Link", adjust.launchDeferredDeeplink);
adjust.costDataInAttribution = EditorGUILayout.Toggle("Cost Data In Attribution Callback", adjust.costDataInAttribution);
adjust.linkMe = EditorGUILayout.Toggle("LinkMe", adjust.linkMe);
adjust.defaultTracker = EditorGUILayout.TextField("Default Tracker", adjust.defaultTracker);
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
EditorGUILayout.LabelField("ANDROID SETTINGS:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
adjust.preinstallTracking = EditorGUILayout.Toggle("Preinstall Tracking", adjust.preinstallTracking);
adjust.preinstallFilePath = EditorGUILayout.TextField("Preinstall File Path", adjust.preinstallFilePath);
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
EditorGUILayout.LabelField("IOS SETTINGS:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
adjust.adServices = EditorGUILayout.Toggle("AdServices Info Reading", adjust.adServices);
adjust.idfaReading = EditorGUILayout.Toggle("IDFA Info Reading", adjust.idfaReading);
adjust.skanAttribution = EditorGUILayout.Toggle("SKAdNetwork Handling", adjust.skanAttribution);
EditorGUI.indentLevel -= 1;
}
if (settingsEditor == null)
{
settingsEditor = CreateEditor(AdjustSettings.Instance);
}
settingsEditor.OnInspectorGUI();
if (GUI.changed)
{
EditorUtility.SetDirty(adjust);
EditorSceneManager.MarkSceneDirty(adjust.gameObject.scene);
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 1772b9461c24c4df0ad55f51f81c7345
timeCreated: 1617868100
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,343 @@
using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
#if UNITY_IOS
using UnityEditor.iOS.Xcode;
#if UNITY_2019_3_OR_NEWER
using UnityEditor.iOS.Xcode.Extensions;
#endif
#endif
namespace AdjustSdk
{
public class AdjustEditor : AssetPostprocessor
{
private const int AdjustEditorPostProcesssBuildPriority = 90;
private const string TargetUnityIphonePodfileLine = "target 'Unity-iPhone' do";
private const string UseFrameworksPodfileLine = "use_frameworks!";
private const string UseFrameworksDynamicPodfileLine = "use_frameworks! :linkage => :dynamic";
private const string UseFrameworksStaticPodfileLine = "use_frameworks! :linkage => :static";
[PostProcessBuild(AdjustEditorPostProcesssBuildPriority)]
public static void OnPostprocessBuild(BuildTarget target, string projectPath)
{
RunPostBuildScript(target: target, projectPath: projectPath);
}
private static void RunPostBuildScript(BuildTarget target, string projectPath = "")
{
if (target == BuildTarget.iOS)
{
#if UNITY_IOS
Debug.Log("[Adjust]: Starting to perform post build tasks for iOS platform.");
string xcodeProjectPath = projectPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
PBXProject xcodeProject = new PBXProject();
xcodeProject.ReadFromFile(xcodeProjectPath);
#if UNITY_2019_3_OR_NEWER
string xcodeTarget = xcodeProject.GetUnityMainTargetGuid();
#else
string xcodeTarget = xcodeProject.TargetGuidByName("Unity-iPhone");
#endif
HandlePlistIosChanges(projectPath);
if (AdjustSettings.iOSUniversalLinksDomains.Length > 0)
{
AddUniversalLinkDomains(xcodeProject, xcodeProjectPath, xcodeTarget);
}
// If enabled by the user, Adjust SDK will try to add following frameworks to your project:
// - AdSupport.framework (needed for access to IDFA value)
// - AdServices.framework (needed in case you are running ASA campaigns)
// - StoreKit.framework (needed for communication with SKAdNetwork framework)
// - AppTrackingTransparency.framework (needed for information about user's consent to be tracked)
// In case you don't need any of these, feel free to remove them from your app.
if (AdjustSettings.iOSFrameworkAdSupport)
{
Debug.Log("[Adjust]: Adding AdSupport.framework to Xcode project.");
xcodeProject.AddFrameworkToProject(xcodeTarget, "AdSupport.framework", true);
Debug.Log("[Adjust]: AdSupport.framework added successfully.");
}
else
{
Debug.Log("[Adjust]: Skipping AdSupport.framework linking.");
}
if (AdjustSettings.iOSFrameworkAdServices)
{
Debug.Log("[Adjust]: Adding AdServices.framework to Xcode project.");
xcodeProject.AddFrameworkToProject(xcodeTarget, "AdServices.framework", true);
Debug.Log("[Adjust]: AdServices.framework added successfully.");
}
else
{
Debug.Log("[Adjust]: Skipping AdServices.framework linking.");
}
if (AdjustSettings.iOSFrameworkStoreKit)
{
Debug.Log("[Adjust]: Adding StoreKit.framework to Xcode project.");
xcodeProject.AddFrameworkToProject(xcodeTarget, "StoreKit.framework", true);
Debug.Log("[Adjust]: StoreKit.framework added successfully.");
}
else
{
Debug.Log("[Adjust]: Skipping StoreKit.framework linking.");
}
if (AdjustSettings.iOSFrameworkAppTrackingTransparency)
{
Debug.Log("[Adjust]: Adding AppTrackingTransparency.framework to Xcode project.");
xcodeProject.AddFrameworkToProject(xcodeTarget, "AppTrackingTransparency.framework", true);
Debug.Log("[Adjust]: AppTrackingTransparency.framework added successfully.");
}
else
{
Debug.Log("[Adjust]: Skipping AppTrackingTransparency.framework linking.");
}
// The Adjust SDK needs to have Obj-C exceptions enabled.
// GCC_ENABLE_OBJC_EXCEPTIONS=YES
string xcodeTargetUnityFramework = xcodeProject.TargetGuidByName("UnityFramework");
Debug.Log("[Adjust]: Enabling Obj-C exceptions by setting GCC_ENABLE_OBJC_EXCEPTIONS value to YES.");
xcodeProject.AddBuildProperty(xcodeTarget, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");
Debug.Log("[Adjust]: Obj-C exceptions enabled successfully.");
if (!string.IsNullOrEmpty(xcodeTargetUnityFramework))
{
Debug.Log("[Adjust]: Enabling Obj-C exceptions by setting GCC_ENABLE_OBJC_EXCEPTIONS value to YES.");
xcodeProject.AddBuildProperty(xcodeTargetUnityFramework, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");
Debug.Log("[Adjust]: Obj-C exceptions enabled successfully.");
}
// potential AdjustSigSdk.xcframework embedding
Debug.Log("[Adjust]: Checking whether AdjustSigSdk.xcframework needs to be embedded or not...");
EmbedAdjustSignatureIfNeeded(projectPath, xcodeProject, xcodeTarget);
// Save the changes to Xcode project file.
xcodeProject.WriteToFile(xcodeProjectPath);
#endif
}
}
#if UNITY_IOS
// dynamic xcframework embedding logic adjusted and taken from:
// https://github.com/AppLovin/AppLovin-MAX-Unity-Plugin/blob/master/DemoApp/Assets/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessiOS.cs
private static void EmbedAdjustSignatureIfNeeded(string buildPath, PBXProject project, string targetGuid)
{
var podsDirectory = Path.Combine(buildPath, "Pods");
if (!Directory.Exists(podsDirectory) || !ShouldEmbedDynamicLibraries(buildPath))
{
Debug.Log("[Adjust]: No need to embed AdjustSigSdk.xcframework.");
return;
}
var dynamicLibraryPathToEmbed = GetAdjustSignaturePathToEmbed(podsDirectory, buildPath);
if (dynamicLibraryPathToEmbed == null) {
return;
}
Debug.Log("[Adjust]: It needs to be embedded. Starting the embedding process...");
#if UNITY_2019_3_OR_NEWER
var fileGuid = project.AddFile(dynamicLibraryPathToEmbed, dynamicLibraryPathToEmbed);
project.AddFileToEmbedFrameworks(targetGuid, fileGuid);
#else
string runpathSearchPaths;
runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS");
runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " ";
// check if runtime search paths already contains the required search paths for dynamic libraries
if (runpathSearchPaths.Contains("@executable_path/Frameworks")) {
return;
}
runpathSearchPaths += "@executable_path/Frameworks";
project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths);
#endif
Debug.Log("[Adjust]: Embedding process completed.");
}
private static bool ShouldEmbedDynamicLibraries(string buildPath)
{
var podfilePath = Path.Combine(buildPath, "Podfile");
if (!File.Exists(podfilePath)) {
return false;
}
// if the Podfile doesn't have a `Unity-iPhone` target, we should embed the dynamic libraries
var lines = File.ReadAllLines(podfilePath);
var containsUnityIphoneTarget = lines.Any(line => line.Contains(TargetUnityIphonePodfileLine));
if (!containsUnityIphoneTarget) {
return true;
}
// if the Podfile does not have a `use_frameworks! :linkage => static` line, we should not embed the dynamic libraries
var useFrameworksStaticLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksStaticPodfileLine));
if (useFrameworksStaticLineIndex == -1) {
return false;
}
// if more than one of the `use_frameworks!` lines are present, CocoaPods will use the last one
var useFrameworksLineIndex = Array.FindIndex(lines, line => line.Trim() == UseFrameworksPodfileLine); // check for exact line to avoid matching `use_frameworks! :linkage => static/dynamic`
var useFrameworksDynamicLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksDynamicPodfileLine));
// check if `use_frameworks! :linkage => :static` is the last line of the three
// if it is, we should embed the dynamic libraries
return useFrameworksLineIndex < useFrameworksStaticLineIndex && useFrameworksDynamicLineIndex < useFrameworksStaticLineIndex;
}
private static string GetAdjustSignaturePathToEmbed(string podsDirectory, string buildPath)
{
var adjustSignatureFrameworkToEmbed = "AdjustSigSdk.xcframework";
// both .framework and .xcframework are directories, not files
var directories = Directory.GetDirectories(podsDirectory, adjustSignatureFrameworkToEmbed, SearchOption.AllDirectories);
if (directories.Length <= 0) {
return null;
}
var dynamicLibraryAbsolutePath = directories[0];
var relativePath = GetDynamicLibraryRelativePath(dynamicLibraryAbsolutePath);
return relativePath;
}
private static string GetDynamicLibraryRelativePath(string dynamicLibraryAbsolutePath)
{
var index = dynamicLibraryAbsolutePath.LastIndexOf("Pods", StringComparison.Ordinal);
return dynamicLibraryAbsolutePath.Substring(index);
}
private static void HandlePlistIosChanges(string projectPath)
{
const string UserTrackingUsageDescriptionKey = "NSUserTrackingUsageDescription";
// Check if needs to do any info plist change.
bool hasUserTrackingDescription =
!string.IsNullOrEmpty(AdjustSettings.iOSUserTrackingUsageDescription);
bool hasUrlSchemesDeepLinksEnabled = AdjustSettings.iOSUrlSchemes.Length > 0;
if (!hasUserTrackingDescription && !hasUrlSchemesDeepLinksEnabled)
{
return;
}
// Get and read info plist.
var plistPath = Path.Combine(projectPath, "Info.plist");
var plist = new PlistDocument();
plist.ReadFromFile(plistPath);
var plistRoot = plist.root;
// Do the info plist changes.
if (hasUserTrackingDescription)
{
if (plistRoot[UserTrackingUsageDescriptionKey] != null)
{
Debug.Log("[Adjust]: Overwritting User Tracking Usage Description.");
}
plistRoot.SetString(UserTrackingUsageDescriptionKey,
AdjustSettings.iOSUserTrackingUsageDescription);
}
if (hasUrlSchemesDeepLinksEnabled)
{
AddUrlSchemesIOS(plistRoot, AdjustSettings.iOSUrlIdentifier, AdjustSettings.iOSUrlSchemes);
}
// Write any info plist change.
File.WriteAllText(plistPath, plist.WriteToString());
}
private static void AddUrlSchemesIOS(PlistElementDict plistRoot, string urlIdentifier, string[] urlSchemes)
{
// Set Array for futher deeplink values.
var urlTypesArray = CreatePlistElementArray(plistRoot, "CFBundleURLTypes");
// Array will contain just one deeplink dictionary
var urlSchemesItems = CreatePlistElementDict(urlTypesArray);
urlSchemesItems.SetString("CFBundleURLName", urlIdentifier);
var urlSchemesArray = CreatePlistElementArray(urlSchemesItems, "CFBundleURLSchemes");
// Delete old deferred deeplinks URIs
Debug.Log("[Adjust]: Removing deeplinks that already exist in the array to avoid duplicates.");
foreach (var link in urlSchemes)
{
urlSchemesArray.values.RemoveAll(
element => element != null && element.AsString().Equals(link));
}
Debug.Log("[Adjust]: Adding new deep links.");
foreach (var link in urlSchemes.Distinct())
{
urlSchemesArray.AddString(link);
}
}
private static PlistElementArray CreatePlistElementArray(PlistElementDict root, string key)
{
if (!root.values.ContainsKey(key))
{
Debug.Log(string.Format("[Adjust]: {0} not found in Info.plist. Creating a new one.", key));
return root.CreateArray(key);
}
var result = root.values[key].AsArray();
return result != null ? result : root.CreateArray(key);
}
private static PlistElementDict CreatePlistElementDict(PlistElementArray rootArray)
{
if (rootArray.values.Count == 0)
{
Debug.Log("[Adjust]: Deeplinks array doesn't contain dictionary for deeplinks. Creating a new one.");
return rootArray.AddDict();
}
var urlSchemesItems = rootArray.values[0].AsDict();
Debug.Log("[Adjust]: Reading deeplinks array");
if (urlSchemesItems == null)
{
Debug.Log("[Adjust]: Deeplinks array doesn't contain dictionary for deeplinks. Creating a new one.");
urlSchemesItems = rootArray.AddDict();
}
return urlSchemesItems;
}
private static void AddUniversalLinkDomains(PBXProject project, string xCodeProjectPath, string xCodeTarget)
{
string entitlementsFileName = project.GetBuildPropertyForAnyConfig(xCodeTarget, "CODE_SIGN_ENTITLEMENTS");
if (entitlementsFileName == null)
{
entitlementsFileName = "Unity-iPhone.entitlements";
}
Debug.Log("[Adjust]: Adding associated domains to entitlements file.");
#if UNITY_2019_3_OR_NEWER
var projectCapabilityManager = new ProjectCapabilityManager(xCodeProjectPath, entitlementsFileName, null, project.GetUnityMainTargetGuid());
#else
var projectCapabilityManager = new ProjectCapabilityManager(xCodeProjectPath, entitlementsFileName, PBXProject.GetUnityTargetName());
#endif
var uniqueDomains = AdjustSettings.iOSUniversalLinksDomains.Distinct().ToArray();
const string applinksPrefix = "applinks:";
for (int i = 0; i < uniqueDomains.Length; i++)
{
if (!uniqueDomains[i].StartsWith(applinksPrefix))
{
uniqueDomains[i] = applinksPrefix + uniqueDomains[i];
}
}
projectCapabilityManager.AddAssociatedDomains(uniqueDomains);
projectCapabilityManager.WriteToFile();
Debug.Log("[Adjust]: Enabling Associated Domains capability with created entitlements file.");
project.AddCapability(xCodeTarget, PBXCapabilityType.AssociatedDomains, entitlementsFileName);
}
#endif
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fc5962e0096e9495bbad76934c842619
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,367 @@
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.Build;
using UnityEditor;
using System.Xml;
using System;
using System.Text.RegularExpressions;
using System.Linq;
namespace AdjustSdk
{
#if UNITY_2018_1_OR_NEWER
public class AdjustEditorPreprocessor : IPreprocessBuildWithReport
#else
public class AdjustEditorPreprocessor : IPreprocessBuild
#endif
{
public int callbackOrder
{
get
{
return 0;
}
}
#if UNITY_2018_1_OR_NEWER
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{
OnPreprocessBuild(report.summary.platform, string.Empty);
}
#endif
public void OnPreprocessBuild(BuildTarget target, string path)
{
if (target == BuildTarget.Android)
{
#if UNITY_ANDROID
RunPostProcessTasksAndroid();
#endif
}
}
#if UNITY_ANDROID
private static void RunPostProcessTasksAndroid()
{
var isAdjustManifestUsed = false;
var androidPluginsPath = Path.Combine(Application.dataPath, "Plugins/Android");
var adjustManifestPath = Path.Combine(Application.dataPath, "Adjust/Native/Android/AdjustAndroidManifest.xml");
var appManifestPath = Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml");
// Check if user has already created AndroidManifest.xml file in its location.
// If not, use already predefined AdjustAndroidManifest.xml as default one.
if (!File.Exists(appManifestPath))
{
if (!Directory.Exists(androidPluginsPath))
{
Directory.CreateDirectory(androidPluginsPath);
}
isAdjustManifestUsed = true;
File.Copy(adjustManifestPath, appManifestPath);
Debug.Log("[Adjust]: User defined AndroidManifest.xml file not found in Plugins/Android folder.");
Debug.Log("[Adjust]: Creating default app's AndroidManifest.xml from AdjustAndroidManifest.xml file.");
}
else
{
Debug.Log("[Adjust]: User defined AndroidManifest.xml file located in Plugins/Android folder.");
}
// Let's open the app's AndroidManifest.xml file.
var manifestFile = new XmlDocument();
manifestFile.Load(appManifestPath);
var manifestHasChanged = false;
// If Adjust manifest is used, we have already set up everything in it so that
// our native Android SDK can be used properly.
if (!isAdjustManifestUsed)
{
// However, if you already had your own AndroidManifest.xml, we'll now run
// some checks on it and tweak it a bit if needed to add some stuff which
// our native Android SDK needs so that it can run properly.
// Add needed permissions if they are missing.
manifestHasChanged |= AddPermissions(manifestFile);
// Add intent filter to main activity if it is missing.
manifestHasChanged |= AddBroadcastReceiver(manifestFile);
}
// Add intent filter to URL schemes for deeplinking
manifestHasChanged |= AddURISchemes(manifestFile);
if (manifestHasChanged)
{
// Save the changes.
manifestFile.Save(appManifestPath);
Debug.Log("[Adjust]: App's AndroidManifest.xml file check and potential modification completed.");
Debug.Log("[Adjust]: Please check if any error message was displayed during this process "
+ "and make sure to fix all issues in order to properly use the Adjust SDK in your app.");
}
else
{
Debug.Log("[Adjust]: App's AndroidManifest.xml file check completed.");
Debug.Log("[Adjust]: No modifications performed due to app's AndroidManifest.xml file compatibility.");
}
}
private static bool AddURISchemes(XmlDocument manifest)
{
if (AdjustSettings.AndroidUriSchemes.Length == 0)
{
return false;
}
Debug.Log("[Adjust]: Start addition of URI schemes");
// Check if user has defined a custom Android activity name.
string androidActivityName = "com.unity3d.player.UnityPlayerActivity";
if (AdjustSettings.AndroidCustomActivityName.Length != 0)
{
androidActivityName = AdjustSettings.AndroidCustomActivityName;
}
var intentRoot = manifest.DocumentElement.SelectSingleNode("/manifest/application/activity[@android:name='"
+ androidActivityName + "']", GetNamespaceManager(manifest));
var usedIntentFiltersChanged = false;
foreach (var uriScheme in AdjustSettings.AndroidUriSchemes)
{
Uri uri;
try
{
// The first element is android:scheme and the second one is android:host.
uri = new Uri(uriScheme);
// Uri class converts implicit file paths to explicit file paths with the file:// scheme.
if (!uriScheme.StartsWith(uri.Scheme))
{
throw new UriFormatException();
}
}
catch (UriFormatException)
{
Debug.LogError(string.Format("[Adjust]: Android deeplink URI scheme \"{0}\" is invalid and will be ignored.", uriScheme));
Debug.LogWarning(string.Format("[Adjust]: Make sure that your URI scheme entry ends with ://"));
continue;
}
if (!DoesIntentFilterAlreadyExist(manifest, uri))
{
Debug.Log("[Adjust]: Adding new URI with scheme: " + uri.Scheme + ", and host: " + uri.Host);
var newIntentFilter = GetNewIntentFilter(manifest);
var androidSchemeNode = manifest.CreateElement("data");
AddAndroidNamespaceAttribute(manifest, "scheme", uri.Scheme, androidSchemeNode);
AddAndroidNamespaceAttribute(manifest, "host", uri.Host, androidSchemeNode);
newIntentFilter.AppendChild(androidSchemeNode);
intentRoot.AppendChild(newIntentFilter);
Debug.Log(string.Format("[Adjust]: Android deeplink URI scheme \"{0}\" successfully added to your app's AndroidManifest.xml file.", uriScheme));
usedIntentFiltersChanged = true;
}
}
return usedIntentFiltersChanged;
}
private static XmlElement GetNewIntentFilter(XmlDocument manifest)
{
const string androidName = "name";
const string category = "category";
var intentFilter = manifest.CreateElement("intent-filter");
var actionElement = manifest.CreateElement("action");
AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.action.VIEW", actionElement);
intentFilter.AppendChild(actionElement);
var defaultCategory = manifest.CreateElement(category);
AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.DEFAULT", defaultCategory);
intentFilter.AppendChild(defaultCategory);
var browsableCategory = manifest.CreateElement(category);
AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.BROWSABLE", browsableCategory);
intentFilter.AppendChild(browsableCategory);
return intentFilter;
}
private static bool DoesIntentFilterAlreadyExist(XmlDocument manifest, Uri link)
{
var xpath = string.Format("/manifest/application/activity/intent-filter/data[@android:scheme='{0}' and @android:host='{1}']", link.Scheme, link.Host);
return manifest.DocumentElement.SelectSingleNode(xpath, GetNamespaceManager(manifest)) != null;
}
private static bool AddPermissions(XmlDocument manifest)
{
// The Adjust SDK needs two permissions to be added to you app's manifest file:
// <uses-permission android:name="android.permission.INTERNET" />
// <uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
// <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
// <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Debug.Log("[Adjust]: Checking if all permissions needed for the Adjust SDK are present in the app's AndroidManifest.xml file.");
var manifestHasChanged = false;
// If enabled by the user && android.permission.INTERNET permission is missing, add it.
if (AdjustSettings.androidPermissionInternet == true)
{
manifestHasChanged |= AddPermission(manifest, "android.permission.INTERNET");
}
// If enabled by the user && com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE permission is missing, add it.
if (AdjustSettings.androidPermissionInstallReferrerService == true)
{
manifestHasChanged |= AddPermission(manifest, "com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE");
}
// If enabled by the user && com.google.android.gms.permission.AD_ID permission is missing, add it.
if (AdjustSettings.androidPermissionAdId == true)
{
manifestHasChanged |= AddPermission(manifest, "com.google.android.gms.permission.AD_ID");
}
// If enabled by the user && android.permission.ACCESS_NETWORK_STATE permission is missing, add it.
if (AdjustSettings.androidPermissionAccessNetworkState == true)
{
manifestHasChanged |= AddPermission(manifest, "android.permission.ACCESS_NETWORK_STATE");
}
return manifestHasChanged;
}
private static bool AddPermission(XmlDocument manifest, string permissionValue)
{
if (DoesPermissionExist(manifest, permissionValue))
{
Debug.Log(string.Format("[Adjust]: Your app's AndroidManifest.xml file already contains {0} permission.", permissionValue));
return false;
}
var element = manifest.CreateElement("uses-permission");
AddAndroidNamespaceAttribute(manifest, "name", permissionValue, element);
manifest.DocumentElement.AppendChild(element);
Debug.Log(string.Format("[Adjust]: {0} permission successfully added to your app's AndroidManifest.xml file.", permissionValue));
return true;
}
private static bool DoesPermissionExist(XmlDocument manifest, string permissionValue)
{
var xpath = string.Format("/manifest/uses-permission[@android:name='{0}']", permissionValue);
return manifest.DocumentElement.SelectSingleNode(xpath, GetNamespaceManager(manifest)) != null;
}
private static bool AddBroadcastReceiver(XmlDocument manifest)
{
// We're looking for existence of broadcast receiver in the AndroidManifest.xml
// Check out the example below how that usually looks like:
// <manifest
// <!-- ... -->>
//
// <supports-screens
// <!-- ... -->/>
//
// <application
// <!-- ... -->>
// <receiver
// android:name="com.adjust.sdk.AdjustReferrerReceiver"
// android:permission="android.permission.INSTALL_PACKAGES"
// android:exported="true" >
//
// <intent-filter>
// <action android:name="com.android.vending.INSTALL_REFERRER" />
// </intent-filter>
// </receiver>
//
// <activity android:name="com.unity3d.player.UnityPlayerActivity"
// <!-- ... -->
// </activity>
// </application>
//
// <!-- ... -->>
//
// </manifest>
Debug.Log("[Adjust]: Checking if app's AndroidManifest.xml file contains receiver for INSTALL_REFERRER intent.");
// Find the application node
var applicationNodeXpath = "/manifest/application";
var applicationNode = manifest.DocumentElement.SelectSingleNode(applicationNodeXpath);
// If there's no application node, something is really wrong with your AndroidManifest.xml.
if (applicationNode == null)
{
Debug.LogError("[Adjust]: Your app's AndroidManifest.xml file does not contain \"<application>\" node.");
Debug.LogError("[Adjust]: Unable to add the Adjust broadcast receiver to AndroidManifest.xml.");
return false;
}
// Okay, there's an application node in the AndroidManifest.xml file.
// Let's now check if user has already defined a receiver which is listening to INSTALL_REFERRER intent.
// If that is already defined, don't force the Adjust broadcast receiver to the manifest file.
// If not, add the Adjust broadcast receiver to the manifest file.
var customBroadcastReceiversNodes = GetCustomRecieverNodes(manifest);
if (customBroadcastReceiversNodes.Count > 0)
{
if (DoesAdjustBroadcastReceiverExist(manifest))
{
Debug.Log("[Adjust]: It seems like you are already using Adjust broadcast receiver. Yay.");
}
else
{
Debug.Log("[Adjust]: It seems like you are using your own broadcast receiver.");
Debug.Log("[Adjust]: Please, add the calls to the Adjust broadcast receiver like described in here: https://github.com/adjust/android_sdk/blob/master/doc/english/referrer.md");
}
return false;
}
// Generate Adjust broadcast receiver entry and add it to the application node.
var receiverElement = manifest.CreateElement("receiver");
AddAndroidNamespaceAttribute(manifest, "name", "com.adjust.sdk.AdjustReferrerReceiver", receiverElement);
AddAndroidNamespaceAttribute(manifest, "permission", "android.permission.INSTALL_PACKAGES", receiverElement);
AddAndroidNamespaceAttribute(manifest, "exported", "true", receiverElement);
var intentFilterElement = manifest.CreateElement("intent-filter");
var actionElement = manifest.CreateElement("action");
AddAndroidNamespaceAttribute(manifest, "name", "com.android.vending.INSTALL_REFERRER", actionElement);
intentFilterElement.AppendChild(actionElement);
receiverElement.AppendChild(intentFilterElement);
applicationNode.AppendChild(receiverElement);
Debug.Log("[Adjust]: Adjust broadcast receiver successfully added to your app's AndroidManifest.xml file.");
return true;
}
private static bool DoesAdjustBroadcastReceiverExist(XmlDocument manifest)
{
var xpath = "/manifest/application/receiver[@android:name='com.adjust.sdk.AdjustReferrerReceiver']";
return manifest.SelectSingleNode(xpath, GetNamespaceManager(manifest)) != null;
}
private static List<XmlNode> GetCustomRecieverNodes(XmlDocument manifest)
{
var xpath = "/manifest/application/receiver[intent-filter/action[@android:name='com.android.vending.INSTALL_REFERRER']]";
return new List<XmlNode>(manifest.DocumentElement.SelectNodes(xpath, GetNamespaceManager(manifest)).OfType<XmlNode>());
}
private static void AddAndroidNamespaceAttribute(XmlDocument manifest, string key, string value, XmlElement node)
{
var androidSchemeAttribute = manifest.CreateAttribute("android", key, "http://schemas.android.com/apk/res/android");
androidSchemeAttribute.InnerText = value;
node.SetAttributeNode(androidSchemeAttribute);
}
private static XmlNamespaceManager GetNamespaceManager(XmlDocument manifest)
{
var namespaceManager = new XmlNamespaceManager(manifest.NameTable);
namespaceManager.AddNamespace("android", "http://schemas.android.com/apk/res/android");
return namespaceManager;
}
#endif
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: c88a79442bb9342b6956c7d59705f982
timeCreated: 1621599616
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
{
"name": "AdjustSdk.Editor",
"references": [
"AdjustSdk.Scripts"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: afc3483c5bcfe43c4a7a6b7f99b52a07
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,194 @@
// Inspired by: https://github.com/facebook/facebook-sdk-for-unity/blob/master/Facebook.Unity.Settings/FacebookSettings.cs
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace AdjustSdk
{
public class AdjustSettings : ScriptableObject
{
private static AdjustSettings instance;
public const string AdjustSettingsExportPath = "Adjust/Resources/AdjustSettings.asset";
[SerializeField]
private bool _iOSFrameworkAdSupport = true;
[SerializeField]
private bool _iOSFrameworkAdServices = false;
[SerializeField]
private bool _iOSFrameworkAppTrackingTransparency = false;
[SerializeField]
private bool _iOSFrameworkStoreKit = false;
[SerializeField]
private bool _androidPermissionInternet = true;
[SerializeField]
private bool _androidPermissionInstallReferrerService = true;
[SerializeField]
private bool _androidPermissionAdId = true;
[SerializeField]
private bool _androidPermissionAccessNetworkState = false;
[SerializeField]
private string _iOSUserTrackingUsageDescription;
[SerializeField]
private string _iOSUrlIdentifier;
[SerializeField]
private string[] _iOSUrlSchemes = new string[0];
[SerializeField]
private string[] _iOSUniversalLinksDomains = new string[0];
[SerializeField]
private string[] androidUriSchemes = new string[0];
[SerializeField]
private string _androidCustomActivityName;
public static AdjustSettings Instance
{
get
{
instance = NullableInstance;
if (instance == null)
{
// Create AdjustSettings.asset inside the folder in which AdjustSettings.cs reside.
instance = ScriptableObject.CreateInstance<AdjustSettings>();
var guids = AssetDatabase.FindAssets(string.Format("{0} t:script", "AdjustSettings"));
if (guids == null || guids.Length <= 0)
{
return instance;
}
var assetPath = AssetDatabase.GUIDToAssetPath(guids[0]).Replace("AdjustSettings.cs", "AdjustSettings.asset");
// AdjustSettings.asset will be stored inside of the Adjust/Resources directory
if (assetPath.StartsWith("Assets"))
{
// plugin located in Assets directory
string rootDir = assetPath.Replace("/Adjust/Scripts/Editor/AdjustSettings.asset", "");
string adjustResourcesPath = Path.Combine(rootDir, "Adjust/Resources");
if (!Directory.Exists(adjustResourcesPath))
{
Directory.CreateDirectory(adjustResourcesPath);
}
assetPath = Path.Combine(rootDir, AdjustSettingsExportPath);
}
else
{
// plugin located in Packages folder
string adjustResourcesPath = Path.Combine("Assets", "Adjust/Resources");
if (!Directory.Exists(adjustResourcesPath))
{
Directory.CreateDirectory(adjustResourcesPath);
}
assetPath = Path.Combine("Assets", AdjustSettingsExportPath);
}
AssetDatabase.CreateAsset(instance, assetPath);
}
return instance;
}
}
public static AdjustSettings NullableInstance
{
get
{
if (instance == null)
{
var guids = AssetDatabase.FindAssets(string.Format("{0} t:ScriptableObject", "AdjustSettings"));
if (guids == null || guids.Length <= 0)
{
return instance;
}
var assetPath = AssetDatabase.GUIDToAssetPath(guids[0]);
instance = (AdjustSettings)AssetDatabase.LoadAssetAtPath(assetPath, typeof(AdjustSettings));
}
return instance;
}
}
public static bool iOSFrameworkAdSupport
{
get { return Instance._iOSFrameworkAdSupport; }
set { Instance._iOSFrameworkAdSupport = value; }
}
public static bool iOSFrameworkAdServices
{
get { return Instance._iOSFrameworkAdServices; }
set { Instance._iOSFrameworkAdServices = value; }
}
public static bool iOSFrameworkAppTrackingTransparency
{
get { return Instance._iOSFrameworkAppTrackingTransparency; }
set { Instance._iOSFrameworkAppTrackingTransparency = value; }
}
public static bool iOSFrameworkStoreKit
{
get { return Instance._iOSFrameworkStoreKit; }
set { Instance._iOSFrameworkStoreKit = value; }
}
public static bool androidPermissionInternet
{
get { return Instance._androidPermissionInternet; }
set { Instance._androidPermissionInternet = value; }
}
public static bool androidPermissionInstallReferrerService
{
get { return Instance._androidPermissionInstallReferrerService; }
set { Instance._androidPermissionInstallReferrerService = value; }
}
public static bool androidPermissionAdId
{
get { return Instance._androidPermissionAdId; }
set { Instance._androidPermissionAdId = value; }
}
public static bool androidPermissionAccessNetworkState
{
get { return Instance._androidPermissionAccessNetworkState; }
set { Instance._androidPermissionAccessNetworkState = value; }
}
public static string iOSUserTrackingUsageDescription
{
get { return Instance._iOSUserTrackingUsageDescription; }
set { Instance._iOSUserTrackingUsageDescription = value; }
}
public static string iOSUrlIdentifier
{
get { return Instance._iOSUrlIdentifier; }
set { Instance._iOSUrlIdentifier = value; }
}
public static string[] iOSUrlSchemes
{
get { return Instance._iOSUrlSchemes; }
set { Instance._iOSUrlSchemes = value; }
}
public static string[] iOSUniversalLinksDomains
{
get { return Instance._iOSUniversalLinksDomains; }
set { Instance._iOSUniversalLinksDomains = value; }
}
public static string[] AndroidUriSchemes
{
get { return Instance.androidUriSchemes; }
set { Instance.androidUriSchemes = value; }
}
public static string AndroidCustomActivityName
{
get { return Instance._androidCustomActivityName; }
set { Instance._androidCustomActivityName = value; }
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: ea4d495dc6d5ba64b90db7afda6a48a4
timeCreated: 1601333126
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,137 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace AdjustSdk
{
[CustomEditor(typeof(AdjustSettings))]
public class AdjustSettingsEditor : Editor
{
SerializedProperty iOSFrameworkAdSupport;
SerializedProperty iOSFrameworkAdServices;
SerializedProperty iOSFrameworkAppTrackingTransparency;
SerializedProperty iOSFrameworkStoreKit;
SerializedProperty androidPermissionInternet;
SerializedProperty androidPermissionInstallReferrerService;
SerializedProperty androidPermissionAdId;
SerializedProperty androidPermissionAccessNetworkState;
SerializedProperty iOSUserTrackingUsageDescription;
SerializedProperty iOSUrlIdentifier;
SerializedProperty iOSUrlSchemes;
SerializedProperty iOSUniversalLinksDomains;
SerializedProperty androidUriSchemes;
SerializedProperty androidCustomActivityName;
void OnEnable()
{
iOSFrameworkAdSupport = serializedObject.FindProperty("_iOSFrameworkAdSupport");
iOSFrameworkAdServices = serializedObject.FindProperty("_iOSFrameworkAdServices");
iOSFrameworkAppTrackingTransparency = serializedObject.FindProperty("_iOSFrameworkAppTrackingTransparency");
iOSFrameworkStoreKit = serializedObject.FindProperty("_iOSFrameworkStoreKit");
androidPermissionInternet = serializedObject.FindProperty("_androidPermissionInternet");
androidPermissionInstallReferrerService = serializedObject.FindProperty("_androidPermissionInstallReferrerService");
androidPermissionAdId = serializedObject.FindProperty("_androidPermissionAdId");
androidPermissionAccessNetworkState = serializedObject.FindProperty("_androidPermissionAccessNetworkState");
iOSUserTrackingUsageDescription = serializedObject.FindProperty("_iOSUserTrackingUsageDescription");
iOSUrlIdentifier = serializedObject.FindProperty("_iOSUrlIdentifier");
iOSUrlSchemes = serializedObject.FindProperty("_iOSUrlSchemes");
iOSUniversalLinksDomains = serializedObject.FindProperty("_iOSUniversalLinksDomains");
androidUriSchemes = serializedObject.FindProperty("androidUriSchemes");
androidCustomActivityName = serializedObject.FindProperty("_androidCustomActivityName");
}
public override void OnInspectorGUI()
{
GUIStyle darkerCyanTextFieldStyles = new GUIStyle(EditorStyles.boldLabel);
darkerCyanTextFieldStyles.normal.textColor = new Color(0f/255f, 190f/255f, 190f/255f);
EditorGUILayout.Space();
EditorGUILayout.LabelField("LINK IOS FRAMEWORKS:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
EditorGUILayout.PropertyField(iOSFrameworkAdSupport,
new GUIContent("AdSupport.framework",
"iOS framework needed to access IDFA value"),
true);
EditorGUILayout.PropertyField(iOSFrameworkAdServices,
new GUIContent("AdServices.framework",
"iOS framework needed to support AdServices based Apple Search Ads attribution"),
true);
EditorGUILayout.PropertyField(iOSFrameworkAppTrackingTransparency,
new GUIContent("AppTrackingTransparency.framework",
"iOS framework needed to display tracking consent dialog"),
true);
EditorGUILayout.PropertyField(iOSFrameworkStoreKit,
new GUIContent("StoreKit.framework",
"iOS framework needed to use SKAdNetwork capabilities"),
true);
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
EditorGUILayout.LabelField("ADD ANDROID PERMISSIONS:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
EditorGUILayout.PropertyField(androidPermissionInternet,
new GUIContent("android.permission.INTERNET",
"Android permission needed to send data to Adjust backend"),
true);
EditorGUILayout.PropertyField(androidPermissionInstallReferrerService,
new GUIContent("com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE",
"Android permission needed to read install referrer"),
true);
EditorGUILayout.PropertyField(androidPermissionAdId,
new GUIContent("com.google.android.gms.permission.AD_ID",
"Android permission needed to read Google Advertising ID if you target API 33 or later"),
true);
EditorGUILayout.PropertyField(androidPermissionAccessNetworkState,
new GUIContent("android.permission.ACCESS_NETWORK_STATE",
"Android permission needed to determine type of network device is connected to"),
true);
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
EditorGUILayout.LabelField("IOS PRIVACY:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
EditorGUILayout.PropertyField(iOSUserTrackingUsageDescription,
new GUIContent("User Tracking Description",
"String you would like to display to your users describing the reason " +
"behind asking for tracking permission."),
true);
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
EditorGUILayout.LabelField("ANDROID ACTIVITY NAME:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
EditorGUILayout.PropertyField(androidCustomActivityName,
new GUIContent("Custom Android Activity Name",
"In case you are using custom activity instead of the default Unity activity " +
"(com.unity3d.player.UnityPlayerActivity), please specify it's full name."),
true);
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
EditorGUILayout.LabelField("DEEP LINKING:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
EditorGUILayout.PropertyField(iOSUrlIdentifier,
new GUIContent("iOS URL Identifier",
"Value of CFBundleURLName property of the root CFBundleURLTypes element. " +
"If not needed otherwise, value should be your bundle ID."),
true);
EditorGUILayout.PropertyField(iOSUrlSchemes,
new GUIContent("iOS URL Schemes",
"URL schemes handled by your app. " +
"Make sure to enter just the scheme name without :// part at the end."),
true);
EditorGUILayout.PropertyField(iOSUniversalLinksDomains,
new GUIContent("iOS Universal Links Domains",
"Associated domains handled by your app. State just the domain part without applinks: part in front."),
true);
EditorGUILayout.PropertyField(androidUriSchemes,
new GUIContent("Android URI Schemes",
"URI schemes handled by your app. " +
"Make sure to enter just the scheme name with :// part at the end."),
true);
EditorGUILayout.HelpBox(
"Please note that Adjust SDK doesn't remove existing URI Schemes, " +
"so if you need to clean previously added entries, " +
"you need to do it manually from \"Assets/Plugins/Android/AndroidManifest.xml\"",
MessageType.Info,
true);
EditorGUI.indentLevel -= 1;
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e957ffb3938e94bcaab247e46bd9804c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 638019d211e7141b7a78db997a91d582
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9c780c17852614618be5ffd9cc43a75f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

Some files were not shown because too many files have changed in this diff Show More