First Version of AppsFlyerSDK Package

This commit is contained in:
wsycarlos 2025-12-06 16:42:27 +08:00
commit 596405b567
117 changed files with 10501 additions and 0 deletions

106
.gitignore vendored Normal file
View File

@ -0,0 +1,106 @@
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
#
.utmp/
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/
*.log
# By default unity supports Blender asset imports, *.blend1 blender files do not need to be commited to version control.
*.blend1
*.blend1.meta
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/
# Recordings can get excessive in size
/[Rr]ecordings/
# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*
# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*
# Jetbrains Rider personal-layer settings
*.DotSettings.user
# Visual Studio cache directory
.vs/
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Mono auto generated files
mono_crash.*
# Builds
*.apk
*.aab
*.unitypackage
*.unitypackage.meta
# Crashlytics generated file
crashlytics-build.properties
# TestRunner generated files
InitTestScene*.unity*
# Addressables default ignores, before user customizations
/ServerData
/[Aa]ssets/StreamingAssets/aa*
/[Aa]ssets/AddressableAssetsData/link.xml*
/[Aa]ssets/Addressables_Temp*
# By default, Addressables content builds will generate addressables_content_state.bin
# files in platform-specific subfolders, for example:
# /Assets/AddressableAssetsData/OSX/addressables_content_state.bin
/[Aa]ssets/AddressableAssetsData/*/*.bin*
# Visual Scripting auto-generated files
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db.meta
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers.meta
# Auto-generated scenes by play mode tests
/[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity*
.vsconfig
Logs/
[Aa]ssets/
[Pp]ublish/
.vscode/settings.json
*.dat

View File

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

View File

@ -0,0 +1,17 @@
{
"name": "AppsFlyer.Editor",
"references": [
"AppsFlyer"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

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

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dependencies>
<androidPackages>
<androidPackage spec="com.appsflyer:af-android-sdk:6.17.3"></androidPackage>
<androidPackage spec="com.appsflyer:unity-wrapper:6.17.72"></androidPackage>
<androidPackage spec="com.android.installreferrer:installreferrer:2.1"></androidPackage>
<androidPackage spec="com.appsflyer:purchase-connector:2.1.1"></androidPackage>
</androidPackages>
<iosPods>
<iosPod name="AppsFlyerFramework" version="6.17.7" minTargetSdk="12.0"></iosPod>
<iosPod name="PurchaseConnector" version="6.17.7" minTargetSdk="12.0"></iosPod>
</iosPods>
</dependencies>

View File

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

View File

@ -0,0 +1,84 @@
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(AppsFlyerObjectScript))]
[CanEditMultipleObjects]
public class AppsFlyerObjectEditor : Editor
{
SerializedProperty devKey;
SerializedProperty appID;
SerializedProperty UWPAppID;
SerializedProperty macOSAppID;
SerializedProperty isDebug;
SerializedProperty getConversionData;
void OnEnable()
{
devKey = serializedObject.FindProperty("devKey");
appID = serializedObject.FindProperty("appID");
UWPAppID = serializedObject.FindProperty("UWPAppID");
macOSAppID = serializedObject.FindProperty("macOSAppID");
isDebug = serializedObject.FindProperty("isDebug");
getConversionData = serializedObject.FindProperty("getConversionData");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
GUILayout.Box((Texture)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(AssetDatabase.FindAssets("appsflyer_logo")[0]), typeof(Texture)), new GUILayoutOption[] { GUILayout.Width(600) });
EditorGUILayout.Separator();
EditorGUILayout.HelpBox("Set your devKey and appID to init the AppsFlyer SDK and start tracking. You must modify these fields and provide:\ndevKey - Your application devKey provided by AppsFlyer.\nappId - For iOS only. Your iTunes Application ID.\nUWP app id - For UWP only. Your application app id \nMac OS app id - For MacOS app only.", MessageType.Info);
EditorGUILayout.PropertyField(devKey);
EditorGUILayout.PropertyField(appID);
EditorGUILayout.PropertyField(UWPAppID);
EditorGUILayout.PropertyField(macOSAppID);
EditorGUILayout.Separator();
EditorGUILayout.HelpBox("Enable get conversion data to allow your app to recive deeplinking callbacks", MessageType.None);
EditorGUILayout.PropertyField(getConversionData);
EditorGUILayout.Separator();
EditorGUILayout.HelpBox("Debugging should be restricted to development phase only.\n Do not distribute the app to app stores with debugging enabled", MessageType.Warning);
EditorGUILayout.PropertyField(isDebug);
EditorGUILayout.Separator();
EditorGUILayout.HelpBox("For more information on setting up AppsFlyer check out our relevant docs.", MessageType.None);
if (GUILayout.Button("AppsFlyer Unity Docs", new GUILayoutOption[] { GUILayout.Width(200) }))
{
Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/213766183-Unity-SDK-integration-for-developers");
}
if (GUILayout.Button("AppsFlyer Android Docs", new GUILayoutOption[] { GUILayout.Width(200) }))
{
Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/207032126-Android-SDK-integration-for-developers");
}
if (GUILayout.Button("AppsFlyer iOS Docs", new GUILayoutOption[] { GUILayout.Width(200) }))
{
Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/207032066-AppsFlyer-SDK-Integration-iOS");
}
if (GUILayout.Button("AppsFlyer Deeplinking Docs", new GUILayoutOption[] { GUILayout.Width(200) }))
{
Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/208874366-OneLink-deep-linking-guide#Setups");
}
if (GUILayout.Button("AppsFlyer Windows Docs", new GUILayoutOption[] { GUILayout.Width(200) }))
{
Application.OpenURL("https://support.appsflyer.com/hc/en-us/articles/207032026-Windows-and-Xbox-SDK-integration-for-developers");
}
serializedObject.ApplyModifiedProperties();
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -0,0 +1,92 @@
fileFormatVersion: 2
guid: bc7fa5a6b64b944a4b2900fd877acb8b
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

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

View File

@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 682114f7790724ab3b9410e89bbc076c
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux64: 1
Exclude OSXUniversal: 0
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 1
- first:
Android: Android
second:
enabled: 0
settings:
AndroidSharedLibraryType: Executable
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: OSX
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: x86_64
- first:
iPhone: iOS
second:
enabled: 0
settings:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>20G417</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>AppsFlyerBundle</string>
<key>CFBundleIdentifier</key>
<string>com.appsflyer.support.two.AppsFlyerBundle</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>AppsFlyerBundle</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>13A1030d</string>
<key>DTPlatformName</key>
<string>macosx</string>
<key>DTPlatformVersion</key>
<string>12.0</string>
<key>DTSDKBuild</key>
<string>21A344</string>
<key>DTSDKName</key>
<string>macosx12.0</string>
<key>DTXcode</key>
<string>1310</string>
<key>DTXcodeBuild</key>
<string>13A1030d</string>
<key>LSMinimumSystemVersion</key>
<string>11.6</string>
<key>NSHumanReadableCopyright</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict/>
<key>files2</key>
<dict/>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View File

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

View File

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

View File

@ -0,0 +1,92 @@
fileFormatVersion: 2
guid: 5186898c6f4665f438e46763d4cff3ae
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 0
Exclude Win64: 0
Exclude iOS: 1
- first:
Android: Android
second:
enabled: 0
settings:
AndroidSharedLibraryType: Executable
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: Windows
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
XboxOne: XboxOne
second:
enabled: 1
settings: {}
- first:
iPhone: iOS
second:
enabled: 0
settings:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,145 @@
//#define AFSDK_WIN_DEBUG
//#define UNITY_WSA_10_0
//#define ENABLE_WINMD_SUPPORT
#if UNITY_WSA_10_0
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.ComponentModel;
using UnityEngine;
using System.Threading.Tasks;
#if ENABLE_WINMD_SUPPORT
using AppsFlyerLib;
#endif
namespace AppsFlyerSDK
{
public class AppsFlyerWindows
{
#if ENABLE_WINMD_SUPPORT
static private MonoBehaviour _gameObject = null;
#endif
public static void InitSDK(string devKey, string appId, MonoBehaviour gameObject)
{
#if ENABLE_WINMD_SUPPORT
#if AFSDK_WIN_DEBUG
// Remove callstack
Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
#endif
Log("[InitSDK]: devKey: {0}, appId: {1}, gameObject: {2}", devKey, appId, gameObject == null ? "null" : gameObject.ToString());
AppsFlyerTracker tracker = AppsFlyerTracker.GetAppsFlyerTracker();
tracker.devKey = devKey;
tracker.appId = appId;
// Interface
_gameObject = gameObject;
#endif
}
public static string GetAppsFlyerId()
{
#if ENABLE_WINMD_SUPPORT
Log("[GetAppsFlyerId]");
return AppsFlyerTracker.GetAppsFlyerTracker().GetAppsFlyerUID();
#else
return "";
#endif
}
public static void SetCustomerUserId(string customerUserId)
{
#if ENABLE_WINMD_SUPPORT
Log("[SetCustomerUserId] customerUserId: {0}", customerUserId);
if (customerUserId.Contains("test_device:"))
{
string testDeviceId = customerUserId.Substring(12);
AppsFlyerTracker.GetAppsFlyerTracker().testDeviceId = testDeviceId;
}
AppsFlyerTracker.GetAppsFlyerTracker().customerUserId = customerUserId;
#endif
}
public static void Start()
{
#if ENABLE_WINMD_SUPPORT
Log("[Start]");
AppsFlyerTracker.GetAppsFlyerTracker().TrackAppLaunchAsync(Callback);
#endif
}
#if ENABLE_WINMD_SUPPORT
public static void Callback(AppsFlyerLib.ServerStatusCode code)
{
Log("[Callback]: {0}", code.ToString());
AppsFlyerRequestEventArgs eventArgs = new AppsFlyerRequestEventArgs((int)code, code.ToString());
if (_gameObject != null) {
var method = _gameObject.GetType().GetMethod("AppsFlyerOnRequestResponse");
if (method != null) {
method.Invoke(_gameObject, new object[] { AppsFlyerTracker.GetAppsFlyerTracker(), eventArgs });
}
}
}
#endif
public static void LogEvent(string eventName, Dictionary<string, string> eventValues)
{
#if ENABLE_WINMD_SUPPORT
if (eventValues == null)
{
eventValues = new Dictionary<string, string>();
}
IDictionary<string, object> result = new Dictionary<string, object>();
foreach (KeyValuePair<string, string> kvp in eventValues)
{
result.Add(kvp.Key.ToString(), kvp.Value);
}
Log("[LogEvent]: eventName: {0} result: {1}", eventName, result.ToString());
AppsFlyerTracker tracker = AppsFlyerTracker.GetAppsFlyerTracker();
tracker.TrackEvent(eventName, result);
#endif
}
public static void GetConversionData(string _reserved)
{
#if ENABLE_WINMD_SUPPORT
Task.Run(async () =>
{
AppsFlyerLib.AppsFlyerTracker tracker = AppsFlyerLib.AppsFlyerTracker.GetAppsFlyerTracker();
string conversionData = await tracker.GetConversionDataAsync();
IAppsFlyerConversionData conversionDataHandler = _gameObject as IAppsFlyerConversionData;
if (conversionDataHandler != null)
{
Log("[GetConversionData] Will call `onConversionDataSuccess` with: {0}", conversionData);
conversionDataHandler.onConversionDataSuccess(conversionData);
} else {
Log("[GetConversionData] Object with `IAppsFlyerConversionData` interface not found! Check `InitSDK` implementation");
}
// _gameObject.GetType().GetMethod("onConversionDataSuccess").Invoke(_gameObject, new[] { conversionData });
});
#endif
}
private static void Log(string format, params string[] args)
{
#if AFSDK_WIN_DEBUG
#if ENABLE_WINMD_SUPPORT
Debug.Log("AF_UNITY_WSA_10_0" + String.Format(format, args));
#endif
#endif
}
}
}
#endif

View File

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

View File

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

View File

@ -0,0 +1,79 @@
import Foundation
import StoreKit
#if canImport(PurchaseConnector)
import PurchaseConnector
@available(iOS 15.0, *)
@objc
public class AFUnityStoreKit2Bridge: NSObject {
@objc
public static func fetchAFSDKTransactionSK2(withTransactionId transactionId: String, completion: @escaping (AFSDKTransactionSK2?) -> Void) {
guard let transactionIdUInt64 = UInt64(transactionId) else {
print("Invalid transaction ID format.")
completion(nil)
return
}
Task {
for await result in StoreKit.Transaction.all {
if case .verified(let transaction) = result, transaction.id == transactionIdUInt64 {
let afTransaction = AFSDKTransactionSK2(transaction: transaction)
DispatchQueue.main.async {
completion(afTransaction)
}
return
}
}
DispatchQueue.main.async {
completion(nil)
}
}
}
@objc
public static func extractSK2ProductInfo(_ products: [AFSDKProductSK2]) -> NSArray {
var result: [[String: Any]] = []
for product in products {
if let swiftProduct = Mirror(reflecting: product).children.first(where: { $0.label == "product" })?.value {
let productId = (swiftProduct as? NSObject)?.value(forKey: "id") as? String ?? ""
let title = (swiftProduct as? NSObject)?.value(forKey: "displayName") as? String ?? ""
let desc = (swiftProduct as? NSObject)?.value(forKey: "description") as? String ?? ""
let price = (swiftProduct as? NSObject)?.value(forKey: "price") as? NSDecimalNumber ?? 0
result.append([
"productIdentifier": productId,
"localizedTitle": title,
"localizedDescription": desc,
"price": price
])
}
}
return result as NSArray
}
@objc
public static func extractSK2TransactionInfo(_ transactions: [AFSDKTransactionSK2]) -> NSArray {
var result: [[String: Any]] = []
for txn in transactions {
guard let mirrorChild = Mirror(reflecting: txn).children.first(where: { $0.label == "transaction" }),
let swiftTxn = mirrorChild.value as? StoreKit.Transaction else {
continue
}
let transactionId = "\(swiftTxn.id)"
let date = NSNumber(value: swiftTxn.purchaseDate.timeIntervalSince1970)
result.append([
"transactionIdentifier": transactionId,
"transactionState": "verified", // or skip this line
"transactionDate": date
])
}
return result as NSArray
}
}
#endif

View File

@ -0,0 +1,42 @@
fileFormatVersion: 2
guid: 5652805602a6b4273a6e527b00aea272
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
VisionOS: VisionOS
second:
enabled: 1
settings: {}
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
//
// AFUnityUtils.h
//
// Created by Andrii H. and Dmitry O. on 16 Oct 2023
//
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
#import <AppsFlyerLib/AppsFlyerLib.h>
#else
#import "AppsFlyerLib.h"
#endif
static NSString* stringFromChar(const char *str);
static NSDictionary* dictionaryFromJson(const char *jsonString);
static const char* stringFromdictionary(NSDictionary* dictionary);
static NSArray<NSString*> *NSArrayFromCArray(int length, const char **arr);
static char* getCString(const char* string);
static AppsFlyerLinkGenerator* generatorFromDictionary(NSDictionary* dictionary, AppsFlyerLinkGenerator* generator);
static EmailCryptType emailCryptTypeFromInt(int emailCryptTypeInt);
static AppsFlyerAdRevenueMediationNetworkType mediationNetworkTypeFromInt(int mediationNetwork);
static NSNumber *intFromNullableBool(const char *cStr);
static NSString* stringFromDeepLinkResultStatus(AFSDKDeepLinkResultStatus deepLinkResult);
static NSString* stringFromDeepLinkResultError(AppsFlyerDeepLinkResult *result);

View File

@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 4b0609ff467554f2088aee1c52bf54a2
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
- first:
Android: Android
second:
enabled: 0
settings:
AndroidSharedLibraryType: Executable
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- 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:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,211 @@
//
// AFUnityUtils.mm
// Unity-iPhone
//
// Created by Jonathan Wesfield on 24/07/2019.
//
#import "AFUnityUtils.h"
static NSString* stringFromChar(const char *str) {
return str ? [NSString stringWithUTF8String:str] : nil;
}
static NSDictionary* dictionaryFromJson(const char *jsonString) {
if(jsonString){
NSData *jsonData = [[NSData alloc] initWithBytes:jsonString length:strlen(jsonString)];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
return dictionary;
}
return nil;
}
static const char* stringFromdictionary(NSDictionary* dictionary) {
if(dictionary){
NSError * err;
NSData * jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&err];
NSString * myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return [myString UTF8String];
}
return nil;
}
static NSDictionary* dictionaryFromNSError(NSError* error) {
if(error){
NSInteger code = [error code];
NSString *localizedDescription = [error localizedDescription];
NSDictionary *errorDictionary = @{
@"code" : @(code) ?: @(-1),
@"localizedDescription" : localizedDescription,
};
return errorDictionary;
}
return nil;
}
static NSArray<NSString*> *NSArrayFromCArray(int length, const char **arr) {
NSMutableArray<NSString *> *res = [[NSMutableArray alloc] init];
for(int i = 0; i < length; i++) {
if (arr[i]) {
[res addObject:[NSString stringWithUTF8String:arr[i]]];
}
}
return res;
}
static char* getCString(const char* string){
if (string == NULL){
return NULL;
}
char* res = (char*)malloc(strlen(string) + 1);
strcpy(res, string);
return res;
}
static AppsFlyerLinkGenerator* generatorFromDictionary(NSDictionary* dictionary, AppsFlyerLinkGenerator* generator) {
NSArray* generatorKeys = @[@"channel", @"customerID", @"campaign", @"referrerName", @"referrerImageUrl", @"deeplinkPath", @"baseDeeplink", @"brandDomain"];
NSMutableDictionary* mutableDictionary = [dictionary mutableCopy];
[generator setChannel:[dictionary objectForKey: @"channel"]];
[generator setReferrerCustomerId:[dictionary objectForKey: @"customerID"]];
[generator setCampaign:[dictionary objectForKey: @"campaign"]];
[generator setReferrerName:[dictionary objectForKey: @"referrerName"]];
[generator setReferrerImageURL:[dictionary objectForKey: @"referrerImageUrl"]];
[generator setDeeplinkPath:[dictionary objectForKey: @"deeplinkPath"]];
[generator setBaseDeeplink:[dictionary objectForKey: @"baseDeeplink"]];
[generator setBrandDomain:[dictionary objectForKey: @"brandDomain"]];
[mutableDictionary removeObjectsForKeys:generatorKeys];
[generator addParameters:mutableDictionary];
return generator;
}
static EmailCryptType emailCryptTypeFromInt(int emailCryptTypeInt){
EmailCryptType emailCryptType;
switch (emailCryptTypeInt){
case 1:
emailCryptType = EmailCryptTypeSHA256;
break;
default:
emailCryptType = EmailCryptTypeNone;
break;
}
return emailCryptType;
}
static NSNumber *intFromNullableBool(const char *cStr) {
if (!cStr) return nil;
NSString *str = [NSString stringWithUTF8String:cStr];
if ([str caseInsensitiveCompare:@"true"] == NSOrderedSame) {
return @YES;
} else if ([str caseInsensitiveCompare:@"false"] == NSOrderedSame) {
return @NO;
}
return nil;
}
static AppsFlyerAdRevenueMediationNetworkType mediationNetworkTypeFromInt(int mediationNetworkInt){
AppsFlyerAdRevenueMediationNetworkType mediationNetworkType;
switch (mediationNetworkInt){
case 1:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeGoogleAdMob;
break;
case 2:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeIronSource;
break;
case 3:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeApplovinMax;
break;
case 4:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeFyber;
break;
case 5:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeAppodeal;
break;
case 6:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeAdmost;
break;
case 7:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeTopon;
break;
case 8:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeTradplus;
break;
case 9:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeYandex;
break;
case 10:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeChartBoost;
break;
case 11:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeUnity;
break;
case 12:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeToponPte;
break;
case 13:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeCustom;
break;
case 14:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeDirectMonetization;
break;
default:
mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeCustom;
break;
}
return mediationNetworkType;
}
static NSString* stringFromDeepLinkResultStatus(AFSDKDeepLinkResultStatus deepLinkResult){
NSString* result;
switch (deepLinkResult){
case AFSDKDeepLinkResultStatusFound:
result = @"FOUND";
break;
case AFSDKDeepLinkResultStatusFailure:
result = @"ERROR";
break;
case AFSDKDeepLinkResultStatusNotFound:
result = @"NOT_FOUND";
break;
default:
result = @"ERROR";
break;
}
return result;
}
static NSString* stringFromDeepLinkResultError(AppsFlyerDeepLinkResult *result){
NSString* res;
if (result && result.error){
if ([[result.error userInfo][NSUnderlyingErrorKey] code] == -1001) {
res = @"TIMEOUT";
} else if ([[result.error userInfo][NSUnderlyingErrorKey] code] == -1009) {
res = @"NETWORK";
}
}
res = @"UNKNOWN";
return res;
}

View File

@ -0,0 +1,37 @@
fileFormatVersion: 2
guid: 18a03931864e84d86bedcc99c440e060
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,164 @@
//
// AppsFlyer+AppController.m
// Unity-iPhone
//
// Created by Jonathan Wesfield on 24/07/2019.
//
#import <objc/runtime.h>
#import "UnityAppController.h"
#import "AppsFlyeriOSWrapper.h"
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
#import <AppsFlyerLib/AppsFlyerLib.h>
#else
#import "AppsFlyerLib.h"
#endif
@implementation UnityAppController (AppsFlyerSwizzledAppController)
static BOOL didEnteredBackGround __unused;
static IMP __original_applicationDidBecomeActive_Imp __unused;
static IMP __original_applicationDidEnterBackground_Imp __unused;
static IMP __original_didReceiveRemoteNotification_Imp __unused;
static IMP __original_continueUserActivity_Imp __unused;
static IMP __original_openUrl_Imp __unused;
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
#if !AFSDK_SHOULD_SWIZZLE
id swizzleFlag = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppsFlyerShouldSwizzle"];
BOOL shouldSwizzle = swizzleFlag ? [swizzleFlag boolValue] : NO;
if(shouldSwizzle){
Method method1 = class_getInstanceMethod([self class], @selector(applicationDidBecomeActive:));
__original_applicationDidBecomeActive_Imp = method_setImplementation(method1, (IMP)__swizzled_applicationDidBecomeActive);
Method method2 = class_getInstanceMethod([self class], @selector(applicationDidEnterBackground:));
__original_applicationDidEnterBackground_Imp = method_setImplementation(method2, (IMP)__swizzled_applicationDidEnterBackground);
Method method3 = class_getInstanceMethod([self class], @selector(didReceiveRemoteNotification:));
__original_didReceiveRemoteNotification_Imp = method_setImplementation(method3, (IMP)__swizzled_didReceiveRemoteNotification);
Method method4 = class_getInstanceMethod([self class], @selector(application:openURL:options:));
__original_openUrl_Imp = method_setImplementation(method4, (IMP)__swizzled_openURL);
if (_AppsFlyerdelegate == nil) {
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
}
[self swizzleContinueUserActivity:[self class]];
}
#elif AFSDK_SHOULD_SWIZZLE
Method method1 = class_getInstanceMethod([self class], @selector(applicationDidBecomeActive:));
__original_applicationDidBecomeActive_Imp = method_setImplementation(method1, (IMP)__swizzled_applicationDidBecomeActive);
Method method2 = class_getInstanceMethod([self class], @selector(applicationDidEnterBackground:));
__original_applicationDidEnterBackground_Imp = method_setImplementation(method2, (IMP)__swizzled_applicationDidEnterBackground);
Method method3 = class_getInstanceMethod([self class], @selector(didReceiveRemoteNotification:));
__original_didReceiveRemoteNotification_Imp = method_setImplementation(method3, (IMP)__swizzled_didReceiveRemoteNotification);
Method method4 = class_getInstanceMethod([self class], @selector(application:openURL:options:));
__original_openUrl_Imp = method_setImplementation(method4, (IMP)__swizzled_openURL);
if (_AppsFlyerdelegate == nil) {
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
}
[self swizzleContinueUserActivity:[self class]];
#endif
});
}
+(void)swizzleContinueUserActivity:(Class)class {
SEL originalSelector = @selector(application:continueUserActivity:restorationHandler:);
Method defaultMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, @selector(__swizzled_continueUserActivity));
BOOL isMethodExists = !class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (isMethodExists) {
__original_continueUserActivity_Imp = method_setImplementation(defaultMethod, (IMP)__swizzled_continueUserActivity);
} else {
class_replaceMethod(class, originalSelector, (IMP)__swizzled_continueUserActivity, method_getTypeEncoding(swizzledMethod));
}
}
BOOL __swizzled_continueUserActivity(id self, SEL _cmd, UIApplication* application, NSUserActivity* userActivity, void (^restorationHandler)(NSArray*)) {
NSLog(@"swizzled continueUserActivity");
[[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
if(__original_continueUserActivity_Imp){
return ((BOOL(*)(id, SEL, UIApplication*, NSUserActivity*, void (^)(NSArray*)))__original_continueUserActivity_Imp)(self, _cmd, application, userActivity, NULL);
}
return YES;
}
void __swizzled_applicationDidBecomeActive(id self, SEL _cmd, UIApplication* launchOptions) {
NSLog(@"swizzled applicationDidBecomeActive");
[[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
if(didEnteredBackGround && AppsFlyeriOSWarpper.didCallStart == YES){
[[AppsFlyerLib shared] start];
}
if(__original_applicationDidBecomeActive_Imp){
((void(*)(id,SEL, UIApplication*))__original_applicationDidBecomeActive_Imp)(self, _cmd, launchOptions);
}
}
void __swizzled_applicationDidEnterBackground(id self, SEL _cmd, UIApplication* application) {
NSLog(@"swizzled applicationDidEnterBackground");
didEnteredBackGround = YES;
if(__original_applicationDidEnterBackground_Imp){
((void(*)(id,SEL, UIApplication*))__original_applicationDidEnterBackground_Imp)(self, _cmd, application);
}
}
BOOL __swizzled_didReceiveRemoteNotification(id self, SEL _cmd, UIApplication* application, NSDictionary* userInfo,void (^UIBackgroundFetchResult)(void) ) {
NSLog(@"swizzled didReceiveRemoteNotification");
[[AppsFlyerLib shared] handlePushNotification:userInfo];
if(__original_didReceiveRemoteNotification_Imp){
return ((BOOL(*)(id, SEL, UIApplication*, NSDictionary*, int(UIBackgroundFetchResult)))__original_didReceiveRemoteNotification_Imp)(self, _cmd, application, userInfo, nil);
}
return YES;
}
BOOL __swizzled_openURL(id self, SEL _cmd, UIApplication* application, NSURL* url, NSDictionary * options) {
NSLog(@"swizzled openURL");
[[AppsFlyerAttribution shared] handleOpenUrl:url options:options];
if(__original_openUrl_Imp){
return ((BOOL(*)(id, SEL, UIApplication*, NSURL*, NSDictionary*))__original_openUrl_Imp)(self, _cmd, application, url, options);
}
return NO;
}
@end

View File

@ -0,0 +1,37 @@
fileFormatVersion: 2
guid: 6ae9e1f7daef2427588fab2fbf8d35d5
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,131 @@
//
// AppsFlyerAppController.mm
// Unity-iPhone
//
// Created by Jonathan Wesfield on 30/07/2019.
//
#import <Foundation/Foundation.h>
#import "UnityAppController.h"
#import "AppDelegateListener.h"
#import "AppsFlyeriOSWrapper.h"
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
#import <AppsFlyerLib/AppsFlyerLib.h>
#else
#import "AppsFlyerLib.h"
#endif
#import <objc/message.h>
/**
Note if you would like to use method swizzeling see AppsFlyer+AppController.m
If you are using swizzeling then comment out the method that is being swizzeled in AppsFlyerAppController.mm
Only use swizzeling if there are conflicts with other plugins that needs to be resolved.
*/
@interface AppsFlyerAppController : UnityAppController <AppDelegateListener>
{
BOOL didEnteredBackGround;
}
@end
@implementation AppsFlyerAppController
- (instancetype)init
{
self = [super init];
if (self) {
id swizzleFlag = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppsFlyerShouldSwizzle"];
BOOL shouldSwizzle = swizzleFlag ? [swizzleFlag boolValue] : NO;
if(!shouldSwizzle){
UnityRegisterAppDelegateListener(self);
}
}
return self;
}
- (void)didFinishLaunching:(NSNotification*)notification {
NSLog(@"got didFinishLaunching = %@",notification.userInfo);
if (_AppsFlyerdelegate == nil) {
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
}
[[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
if (notification.userInfo[@"url"]) {
[self onOpenURL:notification];
}
}
-(void)didBecomeActive:(NSNotification*)notification {
NSLog(@"got didBecomeActive(out) = %@", notification.userInfo);
if (didEnteredBackGround == YES && AppsFlyeriOSWarpper.didCallStart == YES) {
[[AppsFlyerLib shared] start];
didEnteredBackGround = NO;
}
}
- (void)didEnterBackground:(NSNotification*)notification {
NSLog(@"got didEnterBackground = %@", notification.userInfo);
didEnteredBackGround = YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler {
[[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
return YES;
}
- (void)onOpenURL:(NSNotification*)notification {
NSLog(@"got onOpenURL = %@", notification.userInfo);
NSURL *url = notification.userInfo[@"url"];
NSString *sourceApplication = notification.userInfo[@"sourceApplication"];
if (sourceApplication == nil) {
sourceApplication = @"";
}
if (url != nil) {
[[AppsFlyerAttribution shared] handleOpenUrl:url sourceApplication:sourceApplication annotation:nil];
}
}
- (void)didReceiveRemoteNotification:(NSNotification*)notification {
NSLog(@"got didReceiveRemoteNotification = %@", notification.userInfo);
[[AppsFlyerLib shared] handlePushNotification:notification.userInfo];
}
@end
#if !(AFSDK_SHOULD_SWIZZLE)
IMPL_APP_CONTROLLER_SUBCLASS(AppsFlyerAppController)
#endif
/**
Note if you would not like to use IMPL_APP_CONTROLLER_SUBCLASS you can replace it with the code below.
<code>
+(void)load
{
[AppsFlyerAppController plugin];
}
// Singleton accessor.
+ (AppsFlyerAppController *)plugin
{
static AppsFlyerAppController *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[AppsFlyerAppController alloc] init];
});
return sharedInstance;
}
</code>
**/

View File

@ -0,0 +1,37 @@
fileFormatVersion: 2
guid: 2d1497a1493b24fecaa58bd3a7b707f9
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,34 @@
//
// AppsFlyerAttribution.h
// UnityFramework
//
// Created by Margot Guetta on 11/04/2021.
//
#ifndef AppsFlyerAttribution_h
#define AppsFlyerAttribution_h
#endif /* AppsFlyerAttribution_h */
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
#import <AppsFlyerLib/AppsFlyerLib.h>
#else
#import "AppsFlyerLib.h"
#endif
@interface AppsFlyerAttribution : NSObject
@property NSUserActivity*_Nullable userActivity;
@property (nonatomic, copy) void (^ _Nullable restorationHandler)(NSArray *_Nullable );
@property NSURL * _Nullable url;
@property NSDictionary * _Nullable options;
@property NSString* _Nullable sourceApplication;
@property id _Nullable annotation;
@property BOOL isBridgeReady;
+ (AppsFlyerAttribution *_Nullable)shared;
- (void) continueUserActivity: (NSUserActivity*_Nullable) userActivity restorationHandler: (void (^_Nullable)(NSArray * _Nullable))restorationHandler;
- (void) handleOpenUrl:(NSURL*_Nullable)url options:(NSDictionary*_Nullable) options;
- (void) handleOpenUrl: (NSURL *_Nonnull)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation;
@end
static NSString * _Nullable const AF_BRIDGE_SET = @"bridge is set";

View File

@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 8544dc3b3c7bb40d397b2de568df1058
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
- first:
Android: Android
second:
enabled: 0
settings:
AndroidSharedLibraryType: Executable
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- 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:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,86 @@
//
// NSObject+AppsFlyerAttribution.m
// UnityFramework
//
// Created by Margot Guetta on 11/04/2021.
//
#import <Foundation/Foundation.h>
#import "AppsFlyerAttribution.h"
@implementation AppsFlyerAttribution
+ (id)shared {
static AppsFlyerAttribution *shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[self alloc] init];
});
return shared;
}
- (id)init {
if (self = [super init]) {
self.options = nil;
self.restorationHandler = nil;
self.url = nil;
self.userActivity = nil;
self.annotation = nil;
self.sourceApplication = nil;
self.isBridgeReady = NO;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(receiveBridgeReadyNotification:)
name:AF_BRIDGE_SET
object:nil];
}
return self;
}
- (void) continueUserActivity: (NSUserActivity*_Nullable) userActivity restorationHandler: (void (^_Nullable)(NSArray * _Nullable))restorationHandler{
if(self.isBridgeReady == YES){
[[AppsFlyerLib shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
}else{
[AppsFlyerAttribution shared].userActivity = userActivity;
[AppsFlyerAttribution shared].restorationHandler = restorationHandler;
}
}
- (void) handleOpenUrl:(NSURL *)url options:(NSDictionary *)options{
if(self.isBridgeReady == YES){
[[AppsFlyerLib shared] handleOpenUrl:url options:options];
}else{
[AppsFlyerAttribution shared].url = url;
[AppsFlyerAttribution shared].options = options;
}
}
- (void) handleOpenUrl:(NSURL *)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation{
if(self.isBridgeReady == YES){
[[AppsFlyerLib shared] handleOpenURL:url sourceApplication:sourceApplication withAnnotation:annotation];
}else{
[AppsFlyerAttribution shared].url = url;
[AppsFlyerAttribution shared].sourceApplication = sourceApplication;
[AppsFlyerAttribution shared].annotation = annotation;
}
}
- (void) receiveBridgeReadyNotification:(NSNotification *) notification
{
NSLog (@"AppsFlyer Debug: handle deep link");
if(self.url && self.sourceApplication){
[[AppsFlyerLib shared] handleOpenURL:self.url sourceApplication:self.sourceApplication withAnnotation:self.annotation];
self.url = nil;
self.sourceApplication = nil;
self.annotation = nil;
}else if(self.options && self.url){
[[AppsFlyerLib shared] handleOpenUrl:self.url options:self.options];
self.options = nil;
self.url = nil;
}else if(self.userActivity){
[[AppsFlyerLib shared] continueUserActivity:self.userActivity restorationHandler:nil];
self.userActivity = nil;
self.restorationHandler = nil;
}
}
@end

View File

@ -0,0 +1,37 @@
fileFormatVersion: 2
guid: 1060e47d7b9e2453ba575f0b455b2bf8
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,71 @@
//
// AppsFlyeriOSWarpper.h
// Unity-iPhone
//
// Created by Jonathan Wesfield on 24/07/2019.
//
#import "AFUnityUtils.mm"
#import "UnityAppController.h"
#import "AppsFlyerAttribution.h"
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
#import <AppsFlyerLib/AppsFlyerLib.h>
#else
#import "AppsFlyerLib.h"
#endif
#if __has_include(<PurchaseConnector/PurchaseConnector.h>)
#import <PurchaseConnector/PurchaseConnector.h>
#else
#import "PurchaseConnector.h"
#endif
#import <PurchaseConnector/PurchaseConnector-Swift.h>
// Add StoreKit 2 support
#if __has_include(<StoreKit/StoreKit.h>)
#import <StoreKit/StoreKit.h>
#endif
@interface AppsFlyeriOSWarpper : NSObject <AppsFlyerLibDelegate, AppsFlyerDeepLinkDelegate, AppsFlyerPurchaseRevenueDelegate, AppsFlyerPurchaseRevenueDataSource, AppsFlyerPurchaseRevenueDataSourceStoreKit2>
+ (BOOL) didCallStart;
+ (void) setDidCallStart:(BOOL)val;
// Add StoreKit 2 methods
- (void)setStoreKitVersion:(int)storeKitVersion;
- (void)logConsumableTransaction:(id)transaction;
@end
static AppsFlyeriOSWarpper *_AppsFlyerdelegate;
static const int kPushNotificationSize = 32;
static NSString* ConversionDataCallbackObject = @"AppsFlyerObject";
static const char* VALIDATE_CALLBACK = "didFinishValidateReceipt";
static const char* VALIDATE_ERROR_CALLBACK = "didFinishValidateReceiptWithError";
static const char* GCD_CALLBACK = "onConversionDataSuccess";
static const char* GCD_ERROR_CALLBACK = "onConversionDataFail";
static const char* OAOA_CALLBACK = "onAppOpenAttribution";
static const char* OAOA_ERROR_CALLBACK = "onAppOpenAttributionFailure";
static const char* GENERATE_LINK_CALLBACK = "onInviteLinkGenerated";
static const char* OPEN_STORE_LINK_CALLBACK = "onOpenStoreLinkGenerated";
static const char* START_REQUEST_CALLBACK = "requestResponseReceived";
static const char* IN_APP_RESPONSE_CALLBACK = "inAppResponseReceived";
static const char* ON_DEEPLINKING = "onDeepLinking";
static const char* VALIDATE_AND_LOG_V2_CALLBACK = "onValidateAndLogComplete";
static const char* VALIDATE_AND_LOG_V2_ERROR_CALLBACK = "onValidateAndLogFailure";
static NSString* validateObjectName = @"";
static NSString* openStoreObjectName = @"";
static NSString* generateInviteObjectName = @"";
static NSString* validateAndLogObjectName = @"";
static NSString* startRequestObjectName = @"";
static NSString* inAppRequestObjectName = @"";
static NSString* onDeeplinkingObjectName = @"";
static const char* PURCHASE_REVENUE_VALIDATION_CALLBACK = "didReceivePurchaseRevenueValidationInfo";
static const char* PURCHASE_REVENUE_ERROR_CALLBACK = "didReceivePurchaseRevenueError";
static NSString* onPurchaseValidationObjectName = @"";

View File

@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 147104b04b5794eaa92b4195cc328e13
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
- first:
Android: Android
second:
enabled: 0
settings:
AndroidSharedLibraryType: Executable
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- 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:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,620 @@
//
// AppsFlyeriOSWarpper.mm
// Unity-iPhone
//
// Created by Jonathan Wesfield on 24/07/2019.
//
#import "AppsFlyeriOSWrapper.h"
#import <objc/runtime.h>
#import <StoreKit/StoreKit.h>
#import "UnityFramework/UnityFramework-Swift.h"
#if __has_include(<PurchaseConnector/PurchaseConnector-Swift.h>)
#import <PurchaseConnector/PurchaseConnector-Swift.h>
#elif __has_include("PurchaseConnector-Swift.h")
#import "PurchaseConnector-Swift.h"
#endif
#if __has_include(<UnityFramework/UnityFramework-Swift.h>)
#import <UnityFramework/UnityFramework-Swift.h>
#elif __has_include("UnityFramework-Swift.h")
#import "UnityFramework-Swift.h"
#endif
static void unityCallBack(NSString* objectName, const char* method, const char* msg) {
if(objectName){
UnitySendMessage([objectName UTF8String], method, msg);
}
}
extern "C" {
const void _startSDK(bool shouldCallback, const char* objectName) {
[[AppsFlyerLib shared] setPluginInfoWith: AFSDKPluginUnity
pluginVersion:@"6.17.72"
additionalParams:nil];
startRequestObjectName = stringFromChar(objectName);
AppsFlyeriOSWarpper.didCallStart = YES;
[AppsFlyerAttribution shared].isBridgeReady = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:AF_BRIDGE_SET object: [AppsFlyerAttribution shared]];
[[AppsFlyerLib shared] startWithCompletionHandler:^(NSDictionary<NSString *,id> *dictionary, NSError *error) {
if(shouldCallback){
if (error) {
NSDictionary *callbackDictionary = @{@"statusCode":[NSNumber numberWithLong:[error code]]};
unityCallBack(startRequestObjectName, START_REQUEST_CALLBACK, stringFromdictionary(callbackDictionary));
return;
}
if (dictionary) {
unityCallBack(startRequestObjectName, START_REQUEST_CALLBACK, stringFromdictionary(dictionary));
return;
}
}
}];
}
const void _setCustomerUserID (const char* customerUserID) {
[[AppsFlyerLib shared] setCustomerUserID:stringFromChar(customerUserID)];
}
const void _setAdditionalData (const char* customData) {
[[AppsFlyerLib shared] setAdditionalData:dictionaryFromJson(customData)];
}
const void _setAppsFlyerDevKey (const char* appsFlyerDevKey) {
[AppsFlyerLib shared].appsFlyerDevKey = stringFromChar(appsFlyerDevKey);
}
const void _setAppleAppID (const char* appleAppID) {
[AppsFlyerLib shared].appleAppID = stringFromChar(appleAppID);
}
const void _setCurrencyCode (const char* currencyCode) {
[[AppsFlyerLib shared] setCurrencyCode:stringFromChar(currencyCode)];
}
const void _setDisableCollectAppleAdSupport (bool disableAdvertisingIdentifier) {
[AppsFlyerLib shared].disableAdvertisingIdentifier = disableAdvertisingIdentifier;
}
const void _setIsDebug (bool isDebug) {
[AppsFlyerLib shared].isDebug = isDebug;
}
const void _setShouldCollectDeviceName (bool shouldCollectDeviceName) {
[AppsFlyerLib shared].shouldCollectDeviceName = shouldCollectDeviceName;
}
const void _setAppInviteOneLinkID (const char* appInviteOneLinkID) {
[[AppsFlyerLib shared] setAppInviteOneLink:stringFromChar(appInviteOneLinkID)];
}
const void _setDeepLinkTimeout (long deepLinkTimeout) {
[AppsFlyerLib shared].deepLinkTimeout = deepLinkTimeout;
}
const void _anonymizeUser (bool anonymizeUser) {
[AppsFlyerLib shared].anonymizeUser = anonymizeUser;
}
const void _enableTCFDataCollection (bool shouldCollectTcfData) {
[[AppsFlyerLib shared] enableTCFDataCollection:shouldCollectTcfData];
}
const void _setConsentData(const char* isUserSubjectToGDPR, const char* hasConsentForDataUsage, const char* hasConsentForAdsPersonalization, const char* hasConsentForAdStorage) {
NSNumber *gdpr = intFromNullableBool(isUserSubjectToGDPR);
NSNumber *dataUsage = intFromNullableBool(hasConsentForDataUsage);
NSNumber *adsPersonalization = intFromNullableBool(hasConsentForAdsPersonalization);
NSNumber *adStorage = intFromNullableBool(hasConsentForAdStorage);
AppsFlyerConsent *consentData = [[AppsFlyerConsent alloc] initWithIsUserSubjectToGDPR:gdpr
hasConsentForDataUsage:dataUsage
hasConsentForAdsPersonalization:adsPersonalization
hasConsentForAdStorage:adStorage];
[[AppsFlyerLib shared] setConsentData:consentData];
}
const void _logAdRevenue(const char* monetizationNetwork, int mediationNetworkInt, const char* currencyIso4217Code, double eventRevenue, const char* additionalParameters) {
AppsFlyerAdRevenueMediationNetworkType mediationNetwork = mediationNetworkTypeFromInt(mediationNetworkInt);
NSNumber *number = [NSNumber numberWithDouble:eventRevenue];
AFAdRevenueData *adRevenue = [[AFAdRevenueData alloc] initWithMonetizationNetwork:stringFromChar(monetizationNetwork) mediationNetwork:mediationNetwork currencyIso4217Code:stringFromChar(currencyIso4217Code) eventRevenue:number];
[[AppsFlyerLib shared] logAdRevenue: adRevenue additionalParameters:dictionaryFromJson(additionalParameters)];
}
const void _setDisableCollectIAd (bool disableCollectASA) {
[AppsFlyerLib shared].disableCollectASA = disableCollectASA;
}
const void _setUseReceiptValidationSandbox (bool useReceiptValidationSandbox) {
[AppsFlyerLib shared].useReceiptValidationSandbox = useReceiptValidationSandbox;
}
const void _setUseUninstallSandbox (bool useUninstallSandbox) {
[AppsFlyerLib shared].useUninstallSandbox = useUninstallSandbox;
}
const void _setResolveDeepLinkURLs (int length, const char **resolveDeepLinkURLs) {
if(length > 0 && resolveDeepLinkURLs) {
[[AppsFlyerLib shared] setResolveDeepLinkURLs:NSArrayFromCArray(length, resolveDeepLinkURLs)];
}
}
const void _setOneLinkCustomDomains (int length, const char **oneLinkCustomDomains) {
if(length > 0 && oneLinkCustomDomains) {
[[AppsFlyerLib shared] setOneLinkCustomDomains:NSArrayFromCArray(length, oneLinkCustomDomains)];
}
}
const void _afSendEvent (const char* eventName, const char* eventValues, bool shouldCallback, const char* objectName) {
inAppRequestObjectName = stringFromChar(objectName);
[[AppsFlyerLib shared] logEventWithEventName:stringFromChar(eventName) eventValues:dictionaryFromJson(eventValues) completionHandler:^(NSDictionary<NSString *,id> *dictionary, NSError *error) {
if(shouldCallback){
if (error) {
NSDictionary *callbackDictionary = @{@"statusCode":[NSNumber numberWithLong:[error code]]};
unityCallBack(inAppRequestObjectName, IN_APP_RESPONSE_CALLBACK, stringFromdictionary(callbackDictionary));
return;
}
if (dictionary) {
unityCallBack(inAppRequestObjectName, IN_APP_RESPONSE_CALLBACK, stringFromdictionary(dictionary));
return;
}
}
}];
}
const void _recordLocation (double longitude, double latitude) {
[[AppsFlyerLib shared] logLocation:longitude latitude:latitude];
}
const char* _getAppsFlyerId () {
return getCString([[[AppsFlyerLib shared] getAppsFlyerUID] UTF8String]);
}
const void _registerUninstall (unsigned char* deviceToken) {
if(deviceToken){
NSData* tokenData = [NSData dataWithBytes:(const void *)deviceToken length:sizeof(unsigned char)*kPushNotificationSize];
[[AppsFlyerLib shared] registerUninstall:tokenData];
}
}
const void _handlePushNotification (const char* pushPayload) {
[[AppsFlyerLib shared] handlePushNotification:dictionaryFromJson(pushPayload)];
}
const char* _getSDKVersion () {
return getCString([[[AppsFlyerLib shared] getSDKVersion] UTF8String]);
}
const void _setHost (const char* host, const char* hostPrefix) {
[[AppsFlyerLib shared] setHost:stringFromChar(host) withHostPrefix:stringFromChar(hostPrefix)];
}
const void _setMinTimeBetweenSessions (int minTimeBetweenSessions) {
[AppsFlyerLib shared].minTimeBetweenSessions = minTimeBetweenSessions;
}
const void _stopSDK (bool isStopped) {
[AppsFlyerLib shared].isStopped = isStopped;
}
const BOOL _isSDKStopped () {
return [AppsFlyerLib shared].isStopped;
}
const void _handleOpenUrl(const char *url, const char *sourceApplication, const char *annotation) {
[[AppsFlyerLib shared] handleOpenURL:[NSURL URLWithString:stringFromChar(url)] sourceApplication:stringFromChar(sourceApplication) withAnnotation:stringFromChar(annotation)]; }
const void _recordCrossPromoteImpression (const char* appID, const char* campaign, const char* parameters) {
[AppsFlyerCrossPromotionHelper logCrossPromoteImpression:stringFromChar(appID) campaign:stringFromChar(campaign) parameters:dictionaryFromJson(parameters)]; }
const void _attributeAndOpenStore (const char* appID, const char* campaign, const char* parameters, const char* objectName) {
openStoreObjectName = stringFromChar(objectName);
[AppsFlyerCrossPromotionHelper
logAndOpenStore:stringFromChar(appID)
campaign:stringFromChar(campaign)
parameters:dictionaryFromJson(parameters)
openStore:^(NSURLSession * _Nonnull urlSession, NSURL * _Nonnull clickURL) {
unityCallBack(openStoreObjectName, OPEN_STORE_LINK_CALLBACK, [clickURL.absoluteString UTF8String]);
}];
}
const void _generateUserInviteLink (const char* parameters, const char* objectName) {
generateInviteObjectName = stringFromChar(objectName);
[AppsFlyerShareInviteHelper generateInviteUrlWithLinkGenerator:^AppsFlyerLinkGenerator * _Nonnull(AppsFlyerLinkGenerator * _Nonnull generator) {
return generatorFromDictionary(dictionaryFromJson(parameters), generator);
} completionHandler:^(NSURL * _Nullable url) {
unityCallBack(generateInviteObjectName, GENERATE_LINK_CALLBACK, [url.absoluteString UTF8String]);
}];
}
const void _recordInvite (const char* channel, const char* parameters) {
[AppsFlyerShareInviteHelper logInvite:stringFromChar(channel) parameters:dictionaryFromJson(parameters)];
}
const void _setUserEmails (int emailCryptTypeInt , int length, const char **userEmails) {
if(length > 0 && userEmails) {
[[AppsFlyerLib shared] setUserEmails:NSArrayFromCArray(length, userEmails) withCryptType:emailCryptTypeFromInt(emailCryptTypeInt)];
}
}
const void _setPhoneNumber (const char* phoneNumber) {
[[AppsFlyerLib shared] setPhoneNumber:stringFromChar(phoneNumber)];
}
const void _setSharingFilterForAllPartners () {
[[AppsFlyerLib shared] setSharingFilterForAllPartners];
}
const void _setSharingFilter (int length, const char **partners) {
if(length > 0 && partners) {
[[AppsFlyerLib shared] setSharingFilter:NSArrayFromCArray(length, partners)];
}
}
const void _setSharingFilterForPartners (int length, const char **partners) {
if(length > 0 && partners) {
[[AppsFlyerLib shared] setSharingFilterForPartners:NSArrayFromCArray(length, partners)];
} else {
[[AppsFlyerLib shared] setSharingFilterForPartners:nil];
}
}
const void _validateAndSendInAppPurchase (const char* productIdentifier, const char* price, const char* currency, const char* transactionId, const char* additionalParameters, const char* objectName) {
validateObjectName = stringFromChar(objectName);
[[AppsFlyerLib shared]
validateAndLogInAppPurchase:stringFromChar(productIdentifier)
price:stringFromChar(price)
currency:stringFromChar(currency)
transactionId:stringFromChar(transactionId)
additionalParameters:dictionaryFromJson(additionalParameters)
success:^(NSDictionary *result){
unityCallBack(validateObjectName, VALIDATE_CALLBACK, stringFromdictionary(result));
} failure:^(NSError *error, id response) {
if(response && [response isKindOfClass:[NSDictionary class]]) {
NSDictionary* value = (NSDictionary*)response;
unityCallBack(validateObjectName, VALIDATE_ERROR_CALLBACK, stringFromdictionary(value));
} else {
unityCallBack(validateObjectName, VALIDATE_ERROR_CALLBACK, error ? [[error localizedDescription] UTF8String] : "error");
}
}];
}
const void _validateAndSendInAppPurchaseV2 (const char* product, const char* transactionId, int purchaseType, const char* purchaseAdditionalDetails, const char* objectName) {
validateAndLogObjectName = stringFromChar(objectName);
AFSDKPurchaseDetails *details = [[AFSDKPurchaseDetails alloc] initWithProductId:stringFromChar(product) transactionId:stringFromChar(transactionId) purchaseType:(AFSDKPurchaseType)purchaseType];
[[AppsFlyerLib shared]
validateAndLogInAppPurchase:details
purchaseAdditionalDetails:dictionaryFromJson(purchaseAdditionalDetails)
completion:^(NSDictionary * _Nullable response, NSError * _Nullable error) {
if (error) {
unityCallBack(validateAndLogObjectName, VALIDATE_AND_LOG_V2_ERROR_CALLBACK, stringFromdictionary(dictionaryFromNSError(error)));
} else {
// Check if the response indicates validation failure
BOOL isValidationFailure = NO;
if (response && [response isKindOfClass:[NSDictionary class]]) {
NSDictionary *resultDict = response[@"result"];
if (resultDict && [resultDict isKindOfClass:[NSDictionary class]]) {
NSDictionary *responseForProduct = resultDict.allValues.firstObject;
if (responseForProduct && [responseForProduct isKindOfClass:[NSDictionary class]]) {
BOOL validationResult = [responseForProduct[@"result"] boolValue];
if (!validationResult) {
isValidationFailure = YES;
}
}
}
}
if (isValidationFailure) {
unityCallBack(validateAndLogObjectName, VALIDATE_AND_LOG_V2_ERROR_CALLBACK, stringFromdictionary(response));
} else {
unityCallBack(validateAndLogObjectName, VALIDATE_AND_LOG_V2_CALLBACK, stringFromdictionary(response));
}
}
}];
}
const void _getConversionData(const char* objectName) {
if (_AppsFlyerdelegate == nil) {
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
}
ConversionDataCallbackObject = stringFromChar(objectName);
[[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
}
const void _waitForATTUserAuthorizationWithTimeoutInterval (int timeoutInterval) {
[[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval];
}
const void _disableSKAdNetwork (bool isDisabled) {
[AppsFlyerLib shared].disableSKAdNetwork = isDisabled;
}
const void _addPushNotificationDeepLinkPath (int length, const char **paths) {
if(length > 0 && paths) {
[[AppsFlyerLib shared] addPushNotificationDeepLinkPath:NSArrayFromCArray(length, paths)];
}
}
const void _subscribeForDeepLink (const char* objectName) {
onDeeplinkingObjectName = stringFromChar(objectName);
if (_AppsFlyerdelegate == nil) {
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
}
[[AppsFlyerLib shared] setDeepLinkDelegate:_AppsFlyerdelegate];
}
const void _setCurrentDeviceLanguage(const char* language) {
[[AppsFlyerLib shared] setCurrentDeviceLanguage:stringFromChar(language)];
}
const void _setPartnerData(const char* partnerId, const char* partnerInfo) {
[[AppsFlyerLib shared] setPartnerDataWithPartnerId: stringFromChar(partnerId) partnerInfo:dictionaryFromJson(partnerInfo)];
}
const void _disableIDFVCollection(bool isDisabled) {
[AppsFlyerLib shared].disableIDFVCollection = isDisabled;
}
// Purchase connector
const void _startObservingTransactions() {
[[PurchaseConnector shared] startObservingTransactions];
}
const void _stopObservingTransactions() {
[[PurchaseConnector shared] stopObservingTransactions];
}
const void _setIsSandbox(bool isSandBox) {
[[PurchaseConnector shared] setIsSandbox:isSandBox];
}
const void _setPurchaseRevenueDelegate() {
if (_AppsFlyerdelegate== nil) {
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
}
[[PurchaseConnector shared] setPurchaseRevenueDelegate:_AppsFlyerdelegate];
}
const void _setAutoLogPurchaseRevenue(int option) {
[[PurchaseConnector shared] setAutoLogPurchaseRevenue:option];
}
const void _initPurchaseConnector(const char* objectName) {
if (_AppsFlyerdelegate == nil) {
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
}
onPurchaseValidationObjectName = stringFromChar(objectName);
}
const void _setPurchaseRevenueDataSource(const char* objectName) {
if (_AppsFlyerdelegate == nil) {
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
}
if (strstr(objectName, "StoreKit2") != NULL) {
// Force protocol conformance
Protocol *sk2Protocol = @protocol(AppsFlyerPurchaseRevenueDataSourceStoreKit2);
class_addProtocol([_AppsFlyerdelegate class], sk2Protocol);
if (![_AppsFlyerdelegate conformsToProtocol:@protocol(AppsFlyerPurchaseRevenueDataSourceStoreKit2)]) {
NSLog(@"[AppsFlyer] Warning: SK2 protocol not conformed!");
}
}
[PurchaseConnector shared].purchaseRevenueDataSource = _AppsFlyerdelegate;
}
const void _setStoreKitVersion(int storeKitVersion) {
[[PurchaseConnector shared] setStoreKitVersion:(AFSDKStoreKitVersion)storeKitVersion];
}
const void _logConsumableTransaction(const char* transactionId) {
if (@available(iOS 15.0, *)) {
NSString *transactionIdStr = [NSString stringWithUTF8String:transactionId];
[AFUnityStoreKit2Bridge fetchAFSDKTransactionSK2WithTransactionId:transactionIdStr completion:^(AFSDKTransactionSK2 *afTransaction) {
if (afTransaction) {
[[PurchaseConnector shared] logConsumableTransaction:afTransaction];
} else {
NSLog(@"No AFSDKTransactionSK2 found for id %@", transactionIdStr);
}
}];
}
}
#ifdef __cplusplus
extern "C" {
#endif
typedef const char *(*UnityPurchaseCallback)(const char *, const char *);
UnityPurchaseCallback UnityPurchasesGetAdditionalParamsCallback = NULL;
UnityPurchaseCallback UnityPurchasesGetAdditionalParamsCallbackSK2 = NULL;
__attribute__((visibility("default")))
void RegisterUnityPurchaseRevenueParamsCallback(UnityPurchaseCallback callback) {
UnityPurchasesGetAdditionalParamsCallback = callback;
}
__attribute__((visibility("default")))
void RegisterUnityPurchaseRevenueParamsCallbackSK2(UnityPurchaseCallback callback) {
UnityPurchasesGetAdditionalParamsCallbackSK2 = callback;
}
#ifdef __cplusplus
}
#endif
}
@implementation AppsFlyeriOSWarpper
static BOOL didCallStart;
+ (BOOL) didCallStart
{ @synchronized(self) { return didCallStart; } }
+ (void) setDidCallStart:(BOOL)val
{ @synchronized(self) { didCallStart = val; } }
- (void)onConversionDataSuccess:(NSDictionary *)installData {
unityCallBack(ConversionDataCallbackObject, GCD_CALLBACK, stringFromdictionary(installData));
}
- (void)onConversionDataFail:(NSError *)error {
unityCallBack(ConversionDataCallbackObject, GCD_ERROR_CALLBACK, [[error localizedDescription] UTF8String]);
}
- (void)onAppOpenAttribution:(NSDictionary *)attributionData {
unityCallBack(ConversionDataCallbackObject, OAOA_CALLBACK, stringFromdictionary(attributionData));
}
- (void)onAppOpenAttributionFailure:(NSError *)error {
unityCallBack(ConversionDataCallbackObject, OAOA_ERROR_CALLBACK, [[error localizedDescription] UTF8String]);
}
- (void)didResolveDeepLink:(AppsFlyerDeepLinkResult *)result{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:stringFromDeepLinkResultError(result) forKey:@"error"];
[dict setValue:stringFromDeepLinkResultStatus(result.status) forKey:@"status"];
if(result && result.deepLink){
[dict setValue:result.deepLink.description forKey:@"deepLink"];
[dict setValue:@(result.deepLink.isDeferred) forKey:@"is_deferred"];
}
unityCallBack(onDeeplinkingObjectName, ON_DEEPLINKING, stringFromdictionary(dict));
}
// Purchase Connector
- (void)didReceivePurchaseRevenueValidationInfo:(NSDictionary *)validationInfo error:(NSError *)error {
if (error != nil) {
unityCallBack(onPurchaseValidationObjectName, PURCHASE_REVENUE_ERROR_CALLBACK, [[error localizedDescription] UTF8String]);
} else {
unityCallBack(onPurchaseValidationObjectName, PURCHASE_REVENUE_VALIDATION_CALLBACK, stringFromdictionary(validationInfo));
}
}
- (NSDictionary *)purchaseRevenueAdditionalParametersForProducts:(NSSet<SKProduct *> *)products
transactions:(NSSet<SKPaymentTransaction *> *)transactions {
NSMutableArray *productsArray = [NSMutableArray array];
for (SKProduct *product in products) {
[productsArray addObject:@{
@"productIdentifier": product.productIdentifier ?: @"",
@"localizedTitle": product.localizedTitle ?: @"",
@"localizedDescription": product.localizedDescription ?: @"",
@"price": [product.price stringValue] ?: @""
}];
}
NSMutableArray *transactionsArray = [NSMutableArray array];
for (SKPaymentTransaction *txn in transactions) {
[transactionsArray addObject:@{
@"transactionIdentifier": txn.transactionIdentifier ?: @"",
@"transactionState": @(txn.transactionState),
@"transactionDate": txn.transactionDate ? [@(txn.transactionDate.timeIntervalSince1970) stringValue] : @""
}];
}
NSDictionary *input = @{
@"products": productsArray,
@"transactions": transactionsArray
};
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:input options:0 error:&error];
if (error || !jsonData) {
NSLog(@"[AppsFlyer] Failed to serialize Unity purchase data: %@", error);
return @{};
}
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
if (!jsonString || !UnityPurchasesGetAdditionalParamsCallback) {
NSLog(@"[AppsFlyer] Unity callback not registered");
return @{};
}
const char *resultCStr = UnityPurchasesGetAdditionalParamsCallback([jsonString UTF8String], "");
if (!resultCStr) {
NSLog(@"[AppsFlyer] Unity callback returned null");
return @{};
}
NSString *resultJson = [NSString stringWithUTF8String:resultCStr];
NSData *resultData = [resultJson dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *parsedResult = [NSJSONSerialization JSONObjectWithData:resultData options:0 error:&error];
if (error || ![parsedResult isKindOfClass:[NSDictionary class]]) {
NSLog(@"[AppsFlyer] Failed to parse Unity response: %@", error);
return @{};
}
return parsedResult;
}
#pragma mark - AppsFlyerPurchaseRevenueDataSourceStoreKit2
- (NSDictionary *)purchaseRevenueAdditionalParametersStoreKit2ForProducts:(NSSet<AFSDKProductSK2 *> *)products transactions:(NSSet<AFSDKTransactionSK2 *> *)transactions {
if (@available(iOS 15.0, *)) {
NSArray *productInfoArray = [AFUnityStoreKit2Bridge extractSK2ProductInfo:[products allObjects]];
NSArray *transactionInfoArray = [AFUnityStoreKit2Bridge extractSK2TransactionInfo:[transactions allObjects]];
NSDictionary *input = @{
@"products": productInfoArray,
@"transactions": transactionInfoArray
};
if (UnityPurchasesGetAdditionalParamsCallbackSK2) {
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:input options:0 error:&error];
if (error || !jsonData) {
NSLog(@"[AppsFlyer] Failed to serialize Unity purchase data: %@", error);
return @{};
}
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
const char *resultCStr = UnityPurchasesGetAdditionalParamsCallbackSK2([jsonString UTF8String], "");
if (!resultCStr) {
NSLog(@"[AppsFlyer] Unity callback returned null");
return @{};
}
NSString *resultJson = [NSString stringWithUTF8String:resultCStr];
NSData *resultData = [resultJson dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *parsedResult = [NSJSONSerialization JSONObjectWithData:resultData options:0 error:&error];
if (error || ![parsedResult isKindOfClass:[NSDictionary class]]) {
NSLog(@"[AppsFlyer] Failed to parse Unity response: %@", error);
return @{};
}
return parsedResult;
} else {
NSLog(@"[AppsFlyer] SK2 - Unity callback is NOT registered");
}
} else {
NSLog(@"[AppsFlyer] SK2 - iOS version not supported");
}
return @{};
}
@end

View File

@ -0,0 +1,37 @@
fileFormatVersion: 2
guid: 2bff3788f3d8747fe9679bd3818e1d76
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
namespace AppsFlyerSDK
{
public enum MediationNetwork : ulong
{
GoogleAdMob = 1,
IronSource = 2,
ApplovinMax = 3,
Fyber = 4,
Appodeal = 5,
Admost = 6,
Topon = 7,
Tradplus = 8,
Yandex = 9,
ChartBoost = 10,
Unity = 11,
ToponPte = 12,
Custom = 13,
DirectMonetization = 14
}
public static class AdRevenueScheme
{
/**
* code ISO 3166-1 format
*/
public const string COUNTRY = "country";
/**
* ID of the ad unit for the impression
*/
public const string AD_UNIT = "ad_unit";
/**
* Format of the ad
*/
public const string AD_TYPE = "ad_type";
/**
* ID of the ad placement for the impression
*/
public const string PLACEMENT = "placement";
}
/// <summary>
// Data class representing ad revenue information.
//
// @property monetizationNetwork The name of the network that monetized the ad.
// @property mediationNetwork An instance of MediationNetwork representing the mediation service used.
// @property currencyIso4217Code The ISO 4217 currency code describing the currency of the revenue.
// @property eventRevenue The amount of revenue generated by the ad.
/// </summary>
public class AFAdRevenueData
{
public string monetizationNetwork { get; private set; }
public MediationNetwork mediationNetwork { get; private set; }
public string currencyIso4217Code { get; private set; }
public double eventRevenue { get; private set; }
public AFAdRevenueData(string monetization, MediationNetwork mediation, string currency, double revenue)
{
monetizationNetwork = monetization;
mediationNetwork = mediation;
currencyIso4217Code = currency;
eventRevenue = revenue;
}
}
}

View File

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

View File

@ -0,0 +1,72 @@
using UnityEngine;
using System.Collections;
public class AFInAppEvents {
/**
* Event Type
* */
public const string LEVEL_ACHIEVED = "af_level_achieved";
public const string ADD_PAYMENT_INFO = "af_add_payment_info";
public const string ADD_TO_CART = "af_add_to_cart";
public const string ADD_TO_WISH_LIST = "af_add_to_wishlist";
public const string COMPLETE_REGISTRATION = "af_complete_registration";
public const string TUTORIAL_COMPLETION = "af_tutorial_completion";
public const string INITIATED_CHECKOUT = "af_initiated_checkout";
public const string PURCHASE = "af_purchase";
public const string RATE = "af_rate";
public const string SEARCH = "af_search";
public const string SPENT_CREDIT = "af_spent_credits";
public const string ACHIEVEMENT_UNLOCKED = "af_achievement_unlocked";
public const string CONTENT_VIEW = "af_content_view";
public const string TRAVEL_BOOKING = "af_travel_booking";
public const string SHARE = "af_share";
public const string INVITE = "af_invite";
public const string LOGIN = "af_login";
public const string RE_ENGAGE = "af_re_engage";
public const string UPDATE = "af_update";
public const string OPENED_FROM_PUSH_NOTIFICATION = "af_opened_from_push_notification";
public const string LOCATION_CHANGED = "af_location_changed";
public const string LOCATION_COORDINATES = "af_location_coordinates";
public const string ORDER_ID = "af_order_id";
/**
* Event Parameter Name
* **/
public const string LEVEL = "af_level";
public const string SCORE = "af_score";
public const string SUCCESS = "af_success";
public const string PRICE = "af_price";
public const string CONTENT_TYPE = "af_content_type";
public const string CONTENT_ID = "af_content_id";
public const string CONTENT_LIST = "af_content_list";
public const string CURRENCY = "af_currency";
public const string QUANTITY = "af_quantity";
public const string REGSITRATION_METHOD = "af_registration_method";
public const string PAYMENT_INFO_AVAILIBLE = "af_payment_info_available";
public const string MAX_RATING_VALUE = "af_max_rating_value";
public const string RATING_VALUE = "af_rating_value";
public const string SEARCH_STRING = "af_search_string";
public const string DATE_A = "af_date_a";
public const string DATE_B = "af_date_b";
public const string DESTINATION_A = "af_destination_a";
public const string DESTINATION_B = "af_destination_b";
public const string DESCRIPTION = "af_description";
public const string CLASS = "af_class";
public const string EVENT_START = "af_event_start";
public const string EVENT_END = "af_event_end";
public const string LATITUDE = "af_lat";
public const string LONGTITUDE = "af_long";
public const string CUSTOMER_USER_ID = "af_customer_user_id";
public const string VALIDATED = "af_validated";
public const string REVENUE = "af_revenue";
public const string RECEIPT_ID = "af_receipt_id";
public const string PARAM_1 = "af_param_1";
public const string PARAM_2 = "af_param_2";
public const string PARAM_3 = "af_param_3";
public const string PARAM_4 = "af_param_4";
public const string PARAM_5 = "af_param_5";
public const string PARAM_6 = "af_param_6";
public const string PARAM_7 = "af_param_7";
public const string PARAM_8 = "af_param_8";
public const string PARAM_9 = "af_param_9";
public const string PARAM_10 = "af_param_10";
}

View File

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

View File

@ -0,0 +1,547 @@
/*
* Copyright (c) 2013 Calvin Rien
*
* Based on the JSON parser by Patrick van Bergen
* http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
*
* Simplified it so that it doesn't throw exceptions
* and can be used in Unity iPhone with maximum code stripping.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace AFMiniJSON {
// Example usage:
//
// using UnityEngine;
// using System.Collections;
// using System.Collections.Generic;
// using MiniJSON;
//
// public class MiniJSONTest : MonoBehaviour {
// void Start () {
// var jsonString = "{ \"array\": [1.44,2,3], " +
// "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
// "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
// "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
// "\"int\": 65536, " +
// "\"float\": 3.1415926, " +
// "\"bool\": true, " +
// "\"null\": null }";
//
// var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;
//
// Debug.Log("deserialized: " + dict.GetType());
// Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]);
// Debug.Log("dict['string']: " + (string) dict["string"]);
// Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles
// Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs
// Debug.Log("dict['unicode']: " + (string) dict["unicode"]);
//
// var str = Json.Serialize(dict);
//
// Debug.Log("serialized: " + str);
// }
// }
/// <summary>
/// This class encodes and decodes JSON strings.
/// Spec. details, see http://www.json.org/
///
/// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
/// All numbers are parsed to doubles.
/// </summary>
public static class Json {
/// <summary>
/// Parses the string json into a value
/// </summary>
/// <param name="json">A JSON string.</param>
/// <returns>An List&lt;object&gt;, a Dictionary&lt;string, object&gt;, a double, an integer,a string, null, true, or false</returns>
public static object Deserialize(string json) {
// save the string for debug information
if (json == null) {
return null;
}
return Parser.Parse(json);
}
sealed class Parser : IDisposable {
const string WORD_BREAK = "{}[],:\"";
public static bool IsWordBreak(char c) {
return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;
}
enum TOKEN {
NONE,
CURLY_OPEN,
CURLY_CLOSE,
SQUARED_OPEN,
SQUARED_CLOSE,
COLON,
COMMA,
STRING,
NUMBER,
TRUE,
FALSE,
NULL
};
StringReader json;
Parser(string jsonString) {
json = new StringReader(jsonString);
}
public static object Parse(string jsonString) {
using (var instance = new Parser(jsonString)) {
return instance.ParseValue();
}
}
public void Dispose() {
json.Dispose();
json = null;
}
Dictionary<string, object> ParseObject() {
Dictionary<string, object> table = new Dictionary<string, object>();
// ditch opening brace
json.Read();
// {
while (true) {
switch (NextToken) {
case TOKEN.NONE:
return null;
case TOKEN.COMMA:
continue;
case TOKEN.CURLY_CLOSE:
return table;
default:
// name
string name = ParseString();
if (name == null) {
return null;
}
// :
if (NextToken != TOKEN.COLON) {
return null;
}
// ditch the colon
json.Read();
// value
table[name] = ParseValue();
break;
}
}
}
List<object> ParseArray() {
List<object> array = new List<object>();
// ditch opening bracket
json.Read();
// [
var parsing = true;
while (parsing) {
TOKEN nextToken = NextToken;
switch (nextToken) {
case TOKEN.NONE:
return null;
case TOKEN.COMMA:
continue;
case TOKEN.SQUARED_CLOSE:
parsing = false;
break;
default:
object value = ParseByToken(nextToken);
array.Add(value);
break;
}
}
return array;
}
object ParseValue() {
TOKEN nextToken = NextToken;
return ParseByToken(nextToken);
}
object ParseByToken(TOKEN token) {
switch (token) {
case TOKEN.STRING:
return ParseString();
case TOKEN.NUMBER:
return ParseNumber();
case TOKEN.CURLY_OPEN:
return ParseObject();
case TOKEN.SQUARED_OPEN:
return ParseArray();
case TOKEN.TRUE:
return true;
case TOKEN.FALSE:
return false;
case TOKEN.NULL:
return null;
default:
return null;
}
}
string ParseString() {
StringBuilder s = new StringBuilder();
char c;
// ditch opening quote
json.Read();
bool parsing = true;
while (parsing) {
if (json.Peek() == -1) {
parsing = false;
break;
}
c = NextChar;
switch (c) {
case '"':
parsing = false;
break;
case '\\':
if (json.Peek() == -1) {
parsing = false;
break;
}
c = NextChar;
switch (c) {
case '"':
case '\\':
case '/':
s.Append(c);
break;
case 'b':
s.Append('\b');
break;
case 'f':
s.Append('\f');
break;
case 'n':
s.Append('\n');
break;
case 'r':
s.Append('\r');
break;
case 't':
s.Append('\t');
break;
case 'u':
var hex = new char[4];
for (int i=0; i< 4; i++) {
hex[i] = NextChar;
}
s.Append((char) Convert.ToInt32(new string(hex), 16));
break;
}
break;
default:
s.Append(c);
break;
}
}
return s.ToString();
}
object ParseNumber() {
string number = NextWord;
if (number.IndexOf('.') == -1) {
long parsedInt;
Int64.TryParse(number, out parsedInt);
return parsedInt;
}
double parsedDouble;
Double.TryParse(number, out parsedDouble);
return parsedDouble;
}
void EatWhitespace() {
while (Char.IsWhiteSpace(PeekChar)) {
json.Read();
if (json.Peek() == -1) {
break;
}
}
}
char PeekChar {
get {
return Convert.ToChar(json.Peek());
}
}
char NextChar {
get {
return Convert.ToChar(json.Read());
}
}
string NextWord {
get {
StringBuilder word = new StringBuilder();
while (!IsWordBreak(PeekChar)) {
word.Append(NextChar);
if (json.Peek() == -1) {
break;
}
}
return word.ToString();
}
}
TOKEN NextToken {
get {
EatWhitespace();
if (json.Peek() == -1) {
return TOKEN.NONE;
}
switch (PeekChar) {
case '{':
return TOKEN.CURLY_OPEN;
case '}':
json.Read();
return TOKEN.CURLY_CLOSE;
case '[':
return TOKEN.SQUARED_OPEN;
case ']':
json.Read();
return TOKEN.SQUARED_CLOSE;
case ',':
json.Read();
return TOKEN.COMMA;
case '"':
return TOKEN.STRING;
case ':':
return TOKEN.COLON;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
return TOKEN.NUMBER;
}
switch (NextWord) {
case "false":
return TOKEN.FALSE;
case "true":
return TOKEN.TRUE;
case "null":
return TOKEN.NULL;
}
return TOKEN.NONE;
}
}
}
/// <summary>
/// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string
/// </summary>
/// <param name="json">A Dictionary&lt;string, object&gt; / List&lt;object&gt;</param>
/// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
public static string Serialize(object obj) {
return Serializer.Serialize(obj);
}
sealed class Serializer {
StringBuilder builder;
Serializer() {
builder = new StringBuilder();
}
public static string Serialize(object obj) {
var instance = new Serializer();
instance.SerializeValue(obj);
return instance.builder.ToString();
}
void SerializeValue(object value) {
IList asList;
IDictionary asDict;
string asStr;
if (value == null) {
builder.Append("null");
} else if ((asStr = value as string) != null) {
SerializeString(asStr);
} else if (value is bool) {
builder.Append((bool) value ? "true" : "false");
} else if ((asList = value as IList) != null) {
SerializeArray(asList);
} else if ((asDict = value as IDictionary) != null) {
SerializeObject(asDict);
} else if (value is char) {
SerializeString(new string((char) value, 1));
} else {
SerializeOther(value);
}
}
void SerializeObject(IDictionary obj) {
bool first = true;
builder.Append('{');
foreach (object e in obj.Keys) {
if (!first) {
builder.Append(',');
}
SerializeString(e.ToString());
builder.Append(':');
SerializeValue(obj[e]);
first = false;
}
builder.Append('}');
}
void SerializeArray(IList anArray) {
builder.Append('[');
bool first = true;
foreach (object obj in anArray) {
if (!first) {
builder.Append(',');
}
SerializeValue(obj);
first = false;
}
builder.Append(']');
}
void SerializeString(string str) {
builder.Append('\"');
char[] charArray = str.ToCharArray();
foreach (var c in charArray) {
switch (c) {
case '"':
builder.Append("\\\"");
break;
case '\\':
builder.Append("\\\\");
break;
case '\b':
builder.Append("\\b");
break;
case '\f':
builder.Append("\\f");
break;
case '\n':
builder.Append("\\n");
break;
case '\r':
builder.Append("\\r");
break;
case '\t':
builder.Append("\\t");
break;
default:
int codepoint = Convert.ToInt32(c);
if ((codepoint >= 32) && (codepoint <= 126)) {
builder.Append(c);
} else {
builder.Append("\\u");
builder.Append(codepoint.ToString("x4"));
}
break;
}
}
builder.Append('\"');
}
void SerializeOther(object value) {
// NOTE: decimals lose precision during serialization.
// They always have, I'm just letting you know.
// Previously floats and doubles lost precision too.
if (value is float) {
builder.Append(((float) value).ToString("R"));
} else if (value is int
|| value is uint
|| value is long
|| value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is ulong) {
builder.Append(value);
} else if (value is double
|| value is decimal) {
builder.Append(Convert.ToDouble(value).ToString("R"));
} else {
SerializeString(value.ToString());
}
}
}
}
}

View File

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

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
namespace AppsFlyerSDK
{
public enum AFPurchaseType
{
Subscription = 0,
OneTimePurchase = 1
}
/// <summary>
/// Purchase details class matching Android SDK AFPurchaseDetails
/// </summary>
public class AFPurchaseDetailsAndroid
{
public AFPurchaseType purchaseType { get; private set; }
public string purchaseToken { get; private set; }
public string productId { get; private set; }
public AFPurchaseDetailsAndroid(AFPurchaseType type, String purchaseToken, String productId)
{
this.purchaseType = type;
this.purchaseToken = purchaseToken;
this.productId = productId;
}
}
}

View File

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

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
namespace AppsFlyerSDK
{
/// <summary>
/// Purchase type enum matching iOS SDK AFSDKPurchaseType
/// </summary>
public enum AFSDKPurchaseType
{
Subscription,
OneTimePurchase
}
/// <summary>
/// Purchase details class matching iOS SDK AFSDKPurchaseDetails
/// </summary>
public class AFSDKPurchaseDetailsIOS
{
public string productId { get; private set; }
public string transactionId { get; private set; }
public AFSDKPurchaseType purchaseType { get; private set; }
private AFSDKPurchaseDetailsIOS(string productId, string transactionId, AFSDKPurchaseType purchaseType)
{
this.productId = productId;
this.transactionId = transactionId;
this.purchaseType = purchaseType;
}
public static AFSDKPurchaseDetailsIOS Init(string productId, string transactionId, AFSDKPurchaseType purchaseType)
{
return new AFSDKPurchaseDetailsIOS(productId, transactionId, purchaseType);
}
}
}

View File

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

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
namespace AppsFlyerSDK
{
public enum AFSDKValidateAndLogStatus
{
AFSDKValidateAndLogStatusSuccess,
AFSDKValidateAndLogStatusFailure,
AFSDKValidateAndLogStatusError
}
/// <summary>
//
/// </summary>
public class AFSDKValidateAndLogResult
{
public AFSDKValidateAndLogStatus status { get; private set; }
public Dictionary<string, object> result { get; private set; }
public Dictionary<string, object> errorData { get; private set; }
public string error { get; private set; }
private AFSDKValidateAndLogResult(AFSDKValidateAndLogStatus status, Dictionary<string, object> result, Dictionary<string, object> errorData, string error)
{
this.status = status;
this.result = result;
this.errorData = errorData;
this.error = error;
}
public static AFSDKValidateAndLogResult Init(AFSDKValidateAndLogStatus status, Dictionary<string, object> result, Dictionary<string, object> errorData, string error)
{
return new AFSDKValidateAndLogResult(status, result, errorData, error);
}
}
}

View File

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

View File

@ -0,0 +1,13 @@
{
"name": "AppsFlyer",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,851 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace AppsFlyerSDK
{
#if UNITY_ANDROID
public class AppsFlyerAndroid : IAppsFlyerAndroidBridge
{
public bool isInit { get; set; }
private static AndroidJavaClass appsFlyerAndroid = new AndroidJavaClass("com.appsflyer.unity.AppsFlyerAndroidWrapper");
public AppsFlyerAndroid() { }
/// <summary>
/// Use this method to init the sdk for the application.
/// Call this method before startSDK.
/// </summary>
/// <param name="devkey"> AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param>
/// <param name="gameObject">The current game object. This is used to get the conversion data callbacks. Pass null if you do not need the callbacks.</param>
public void initSDK(string devkey, MonoBehaviour gameObject)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("initSDK", devkey, gameObject ? gameObject.name : null);
#endif
}
/// <summary>
/// Use this method to start the sdk for the application.
/// The AppsFlyer's Dev-Key must be provided.
/// </summary>
/// <param name="devkey"> AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param>
public void startSDK(bool onRequestResponse, string CallBackObjectName)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("startTracking", onRequestResponse, CallBackObjectName);
#endif
}
/// <summary>
/// Once this API is invoked, our SDK no longer communicates with our servers and stops functioning.
/// In some extreme cases you might want to shut down all SDK activity due to legal and privacy compliance.
/// This can be achieved with the stopSDK API.
/// </summary>
/// <param name="isSDKStopped">boolean should SDK be stopped.</param>
public void stopSDK(bool isSDKStopped)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("stopTracking", isSDKStopped);
#endif
}
/// <summary>
/// Get the AppsFlyer SDK version used in app.
/// </summary>
/// <returns>AppsFlyer SDK version.</returns>
public string getSdkVersion()
{
#if !UNITY_EDITOR
return appsFlyerAndroid.CallStatic<string>("getSdkVersion");
#else
return "";
#endif
}
/// <summary>
/// Manually pass the Firebase / GCM Device Token for Uninstall measurement.
/// </summary>
/// <param name="token">Firebase Device Token.</param>
public void updateServerUninstallToken(string token)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("updateServerUninstallToken", token);
#endif
}
/// <summary>
/// Enables Debug logs for the AppsFlyer SDK.
/// Should only be set to true in development / debug.
/// </summary>
/// <param name="shouldEnable">shouldEnable boolean.</param>
public void setIsDebug(bool shouldEnable)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setIsDebug", shouldEnable);
#endif
}
/// <summary>
/// By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat (4.4)
/// and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS).
/// Use this API to explicitly send IMEI to AppsFlyer.
/// </summary>
/// <param name="aImei">device's IMEI.</param>
public void setImeiData(string aImei)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setImeiData", aImei);
#endif
}
/// <summary>
/// By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat(4.4)
/// and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS).
/// Use this API to explicitly send Android ID to AppsFlyer.
/// </summary>
/// <param name="aAndroidId">device's Android ID.</param>
public void setAndroidIdData(string aAndroidId)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setAndroidIdData", aAndroidId);
#endif
}
/// <summary>
/// Setting your own customer ID enables you to cross-reference your own unique ID with AppsFlyers unique ID and the other devices IDs.
/// This ID is available in AppsFlyer CSV reports along with Postback APIs for cross-referencing with your internal IDs.
/// </summary>
/// <param name="id">Customer ID for client.</param>
public void setCustomerUserId(string id)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setCustomerUserId", id);
#endif
}
/// <summary>
/// It is possible to delay the SDK Initialization until the customerUserID is set.
/// This feature makes sure that the SDK doesn't begin functioning until the customerUserID is provided.
/// If this API is used, all in-app events and any other SDK API calls are discarded, until the customerUserID is provided.
/// </summary>
/// <param name="wait">wait boolean.</param>
public void waitForCustomerUserId(bool wait)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("waitForCustomerUserId", wait);
#endif
}
/// <summary>
/// Use this API to provide the SDK with the relevant customer user id and trigger the SDK to begin its normal activity.
/// </summary>
/// <param name="id">Customer ID for client.</param>
public void setCustomerIdAndStartSDK(string id)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setCustomerIdAndTrack", id);
#endif
}
/// <summary>
/// Get the current AF_STORE value.
/// </summary>
/// <returns>AF_Store value.</returns>
public string getOutOfStore()
{
#if !UNITY_EDITOR
return appsFlyerAndroid.CallStatic<string>("getOutOfStore");
#else
return "";
#endif
}
/// <summary>
/// Manually set the AF_STORE value.
/// </summary>
/// <param name="sourceName">value to be set.</param>
public void setOutOfStore(string sourceName)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setOutOfStore", sourceName);
#endif
}
/// <summary>
/// Set the OneLink ID that should be used for User-Invites.
/// The link that is generated for the user invite will use this OneLink as the base link.
/// </summary>
/// <param name="oneLinkId">OneLink ID obtained from the AppsFlyer Dashboard.</param>
public void setAppInviteOneLinkID(string oneLinkId)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setAppInviteOneLinkID", oneLinkId);
#endif
}
/// <summary>
/// Set additional data to be sent to AppsFlyer.
/// </summary>
/// <param name="customData">additional data Dictionary.</param>
public void setAdditionalData(Dictionary<string, string> customData)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setAdditionalData", convertDictionaryToJavaMap(customData));
#endif
}
//// <summary>
/// Set the deepLink timeout value that should be used for DDL.
/// </summary>
/// <param name="deepLinkTimeout">deepLink timeout in milliseconds.</param>
public void setDeepLinkTimeout(long deepLinkTimeout)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setDeepLinkTimeout", deepLinkTimeout);
#endif
}
/// <summary>
/// Set the user emails.
/// </summary>
/// <param name="emails">User emails.</param>
public void setUserEmails(params string[] userEmails)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setUserEmails", (object)userEmails);
#endif
}
/// <summary>
/// Set the user phone number.
/// </summary>
/// <param name="phoneNumber">User phoneNumber.</param>
public void setPhoneNumber(string phoneNumber){
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setPhoneNumber", phoneNumber);
#endif
}
/// <summary>
/// Set the user emails and encrypt them.
/// cryptMethod Encryption method:
/// EmailCryptType.EmailCryptTypeMD5
/// EmailCryptType.EmailCryptTypeSHA1
/// EmailCryptType.EmailCryptTypeSHA256
/// EmailCryptType.EmailCryptTypeNone
/// </summary>
/// <param name="cryptMethod">Encryption method.</param>
/// <param name="emails">User emails.</param>
public void setUserEmails(EmailCryptType cryptMethod, params string[] emails)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setUserEmails", getEmailType(cryptMethod), (object)emails);
#endif
}
/// <summary>
/// Opt-out of collection of Android ID.
/// If the app does NOT contain Google Play Services, Android ID is collected by the SDK.
/// However, apps with Google play services should avoid Android ID collection as this is in violation of the Google Play policy.
/// </summary>
/// <param name="isCollect">boolean, false to opt-out.</param>
public void setCollectAndroidID(bool isCollect)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setCollectAndroidID", isCollect);
#endif
}
/// <summary>
/// Opt-out of collection of IMEI.
/// If the app does NOT contain Google Play Services, device IMEI is collected by the SDK.
/// However, apps with Google play services should avoid IMEI collection as this is in violation of the Google Play policy.
/// </summary>
/// <param name="isCollect">boolean, false to opt-out.</param>
public void setCollectIMEI(bool isCollect)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setCollectIMEI", isCollect);
#endif
}
/// <summary>
/// Advertisers can wrap AppsFlyer OneLink within another Universal Link.
/// This Universal Link will invoke the app but any deep linking data will not propagate to AppsFlyer.
/// </summary>
/// <param name="urls">Array of urls.</param>
public void setResolveDeepLinkURLs(params string[] urls)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setResolveDeepLinkURLs", (object)urls);
#endif
}
/// <summary>
/// Advertisers can use this method to set vanity onelink domains.
/// </summary>
/// <param name="domains">Array of domains.</param>
public void setOneLinkCustomDomain(params string[] domains)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setOneLinkCustomDomain", (object)domains);
#endif
}
/// <summary>
/// Manually set that the application was updated.
/// </summary>
/// <param name="isUpdate">isUpdate boolean value.</param>
public void setIsUpdate(bool isUpdate)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setIsUpdate", isUpdate);
#endif
}
/// <summary>
/// Setting user local currency code for in-app purchases.
/// The currency code should be a 3 character ISO 4217 code. (default is USD).
/// You can set the currency code for all events by calling the following method.
/// </summary>
/// <param name="currencyCode">3 character ISO 4217 code.</param>
public void setCurrencyCode(string currencyCode)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setCurrencyCode", currencyCode);
#endif
}
/// <summary>
/// Manually record the location of the user.
/// </summary>
/// <param name="latitude">latitude as double.</param>
/// <param name="longitude">longitude as double.</param>
public void recordLocation(double latitude, double longitude)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("trackLocation", latitude, longitude);
#endif
}
/// <summary>
/// Send an In-App Event.
/// In-App Events provide insight on what is happening in your app.
/// </summary>
/// <param name="eventName">Event Name as String.</param>
/// <param name="eventValues">Event Values as Dictionary.</param>
public void sendEvent(string eventName, Dictionary<string, string> eventValues)
{
sendEvent(eventName, eventValues, false, AppsFlyer.CallBackObjectName);
}
public void sendEvent(string eventName, Dictionary<string, string> eventValues, bool shouldCallback, string callBackObjectName)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("trackEvent", eventName, convertDictionaryToJavaMap(eventValues), shouldCallback, callBackObjectName);
#endif
}
/// <summary>
/// Anonymize user Data.
/// Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions.
/// Default is false.
/// </summary>
/// <param name="isDisabled">isDisabled boolean.</param>
public void anonymizeUser(bool isDisabled)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setDeviceTrackingDisabled", isDisabled);
#endif
}
/// <summary>
/// Calling enableTCFDataCollection(true) will enable collecting and sending any TCF related data.
/// Calling enableTCFDataCollection(false) will disable the collection of TCF related data and from sending it.
/// </summary>
/// <param name = "shouldCollectTcfData" >should start TCF Data collection boolean.</param>
public void enableTCFDataCollection(bool shouldCollectTcfData)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("enableTCFDataCollection", shouldCollectTcfData);
#endif
}
/// <summary>
/// Enable the collection of Facebook Deferred AppLinks.
/// Requires Facebook SDK and Facebook app on target/client device.
/// This API must be invoked prior to initializing the AppsFlyer SDK in order to function properly.
/// </summary>
/// <param name="isEnabled">should Facebook's deferred app links be processed by the AppsFlyer SDK.</param>
public void enableFacebookDeferredApplinks(bool isEnabled)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("enableFacebookDeferredApplinks", isEnabled);
#endif
}
/// <summary>
/// Sets or updates the user consent data related to GDPR and DMA regulations for advertising and data usage purposes within the application.
/// call this method when GDPR user is true
/// </summary>
/// <param name = "hasConsentForDataUsage" >hasConsentForDataUsage boolean.</param>
/// <param name = "hasConsentForAdsPersonalization" >hasConsentForAdsPersonalization boolean.</param>
public void setConsentData(AppsFlyerConsent appsFlyerConsent)
{
#if !UNITY_EDITOR
string isUserSubjectToGDPR = appsFlyerConsent.isUserSubjectToGDPR?.ToString().ToLower() ?? "null";
string hasConsentForDataUsage = appsFlyerConsent.hasConsentForDataUsage?.ToString().ToLower() ?? "null";
string hasConsentForAdsPersonalization = appsFlyerConsent.hasConsentForAdsPersonalization?.ToString().ToLower() ?? "null";
string hasConsentForAdStorage = appsFlyerConsent.hasConsentForAdStorage?.ToString().ToLower() ?? "null";
appsFlyerAndroid.CallStatic("setConsentData", isUserSubjectToGDPR, hasConsentForDataUsage, hasConsentForAdsPersonalization, hasConsentForAdStorage);
#endif
}
/// <summary>
/// Logs ad revenue data along with additional parameters if provided.
/// <param name = "adRevenueData" >instance of AFAdRevenueData containing ad revenue information.</param>
/// <param name = "additionalParameters" >An optional map of additional parameters to be logged with ad revenue data. This can be null if there are no additional parameters.</param>
public void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary<string, string> additionalParameters)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("logAdRevenue", adRevenueData.monetizationNetwork, getMediationNetwork(adRevenueData.mediationNetwork), adRevenueData.currencyIso4217Code, adRevenueData.eventRevenue, convertDictionaryToJavaMap(additionalParameters));
#endif
}
/// <summary>
/// Restrict reengagement via deep-link to once per each unique deep-link.
/// Otherwise deep re-occurring deep-links will be permitted for non-singleTask Activities and deep-linking via AppsFlyer deep-links.
/// The default value is false.
/// </summary>
/// <param name="doConsume">doConsume boolean.</param>
public void setConsumeAFDeepLinks(bool doConsume)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setConsumeAFDeepLinks", doConsume);
#endif
}
/// <summary>
/// Specify the manufacturer or media source name to which the preinstall is attributed.
/// </summary>
/// <param name="mediaSource">Manufacturer or media source name for preinstall attribution.</param>
/// <param name="campaign">Campaign name for preinstall attribution.</param>
/// <param name="siteId">Site ID for preinstall attribution.</param>
public void setPreinstallAttribution(string mediaSource, string campaign, string siteId)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setPreinstallAttribution", mediaSource, campaign, siteId);
#endif
}
/// <summary>
/// Boolean indicator for preinstall by Manufacturer.
/// </summary>
/// <returns>boolean isPreInstalledApp.</returns>
public bool isPreInstalledApp()
{
#if !UNITY_EDITOR
return appsFlyerAndroid.CallStatic<bool>("isPreInstalledApp");
#else
return false;
#endif
}
/// <summary>
/// Get the Facebook attribution ID, if one exists.
/// </summary>
/// <returns>string Facebook attribution ID.</returns>
public string getAttributionId()
{
#if !UNITY_EDITOR
return appsFlyerAndroid.CallStatic<string>("getAttributionId");
#else
return "";
#endif
}
/// <summary>
/// Get AppsFlyer's unique device ID is created for every new install of an app.
/// </summary>
/// <returns>AppsFlyer's unique device ID.</returns>
public string getAppsFlyerId()
{
#if !UNITY_EDITOR
return appsFlyerAndroid.CallStatic<string>("getAppsFlyerId");
#else
return "";
#endif
}
/// <summary>
/// API for server verification of in-app purchases.
/// An af_purchase event with the relevant values will be automatically sent if the validation is successful.
/// </summary>
/// <param name="publicKey">License Key obtained from the Google Play Console.</param>
/// <param name="signature"><code>data.INAPP_DATA_SIGNATURE</code> from <code>onActivityResult(int requestCode, int resultCode, Intent data)</code></param>
/// <param name="purchaseData"><code>data.INAPP_PURCHASE_DATA</code> from <code>onActivityResult(int requestCode, int resultCode, Intent data)</code></param>
/// <param name="price">Purchase price, should be derived from <code>skuDetails.getStringArrayList("DETAILS_LIST")</code></param>
/// <param name="currency">Purchase currency, should be derived from <code>skuDetails.getStringArrayList("DETAILS_LIST")</code></param>
/// <param name="additionalParameters">additionalParameters Freehand parameters to be sent with the purchase (if validated).</param>
public void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("validateAndTrackInAppPurchase", publicKey, signature, purchaseData, price, currency, convertDictionaryToJavaMap(additionalParameters), gameObject ? gameObject.name : null);
#endif
}
/// <summary>
/// API for server verification of in-app purchases.
/// An af_purchase event with the relevant values will be automatically sent if the validation is successful.
/// </summary>
/// <param name="details">AFPurchaseDetailsAndroid instance.</param>
/// <param name="purchaseAdditionalDetails">purchaseAdditionalDetails Freehand parameters to be sent with the purchase (if validated).</param>
public void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("validateAndTrackInAppPurchaseV2", (int)details.purchaseType, details.purchaseToken, details.productId, convertDictionaryToJavaMap(purchaseAdditionalDetails), gameObject ? gameObject.name : null);
#endif
}
/// <summary>
/// Was the stopSDK(boolean) API set to true.
/// </summary>
/// <returns>boolean isSDKStopped.</returns>
public bool isSDKStopped()
{
#if !UNITY_EDITOR
return appsFlyerAndroid.CallStatic<bool>("isTrackingStopped");
#else
return false;
#endif
}
/// <summary>
/// Set a custom value for the minimum required time between sessions.
/// By default, at least 5 seconds must lapse between 2 app launches to count as separate 2 sessions.
/// </summary>
/// <param name="seconds">minimum time between 2 separate sessions in seconds.</param>
public void setMinTimeBetweenSessions(int seconds)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setMinTimeBetweenSessions", seconds);
#endif
}
/// <summary>
/// Set a custom host.
/// </summary>
/// <param name="hostPrefixName">Host prefix.</param>
/// <param name="hostName">Host name.</param>
public void setHost(string hostPrefixName, string hostName)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setHost", hostPrefixName, hostName);
#endif
}
/// <summary>
/// Get the host name.
/// Default value is "appsflyer.com".
/// </summary>
/// <returns>Host name.</returns>
public string getHostName()
{
#if !UNITY_EDITOR
return appsFlyerAndroid.CallStatic<string>("getHostName");
#else
return "";
#endif
}
/// <summary>
/// Get the custom host prefix.
/// </summary>
/// <returns>Host prefix.</returns>
public string getHostPrefix()
{
#if !UNITY_EDITOR
return appsFlyerAndroid.CallStatic<string>("getHostPrefix");
#else
return "";
#endif
}
/// <summary>
/// Used by advertisers to exclude all networks/integrated partners from getting data.
/// </summary>
public void setSharingFilterForAllPartners()
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setSharingFilterForAllPartners");
#endif
}
/// <summary>
/// Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data.
/// </summary>
/// <param name="partners">partners to exclude from getting data</param>
public void setSharingFilter(params string[] partners)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setSharingFilter", (object)partners);
#endif
}
/// <summary>
/// Lets you configure how which partners should the SDK exclude from data-sharing.
/// </summary>
/// <param name="partners">partners to exclude from getting data</param>
public static void setSharingFilterForPartners(params string[] partners)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setSharingFilterForPartners", (object)partners);
#endif
}
/// <summary>
/// Register a Conversion Data Listener.
/// Allows the developer to access the user attribution data in real-time for every new install, directly from the SDK level.
/// By doing this you can serve users with personalized content or send them to specific activities within the app,
/// which can greatly enhance their engagement with your app.
/// </summary>
public void getConversionData(string objectName)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("getConversionData", objectName);
#endif
}
/// <summary>
/// Register a validation listener for the validateAndSendInAppPurchase API.
/// </summary>
public void initInAppPurchaseValidatorListener(MonoBehaviour gameObject)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("initInAppPurchaseValidatorListener", gameObject ? gameObject.name : null);
#endif
}
/// <summary>
/// setCollectOaid
/// You must include the appsflyer oaid library for this api to work.
/// </summary>
/// <param name="isCollect">isCollect oaid - set fasle to opt out</param>
public void setCollectOaid(bool isCollect)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setCollectOaid", isCollect);
#endif
}
/// <summary>
/// Use the following API to attribute the click and launch the app store's app page.
/// </summary>
/// <param name="promoted_app_id">promoted App ID</param>
/// <param name="campaign">cross promotion campaign</param>
/// <param name="userParams">additional user params</param>
public void attributeAndOpenStore(string promoted_app_id, string campaign, Dictionary<string, string> userParams, MonoBehaviour gameObject)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("attributeAndOpenStore", promoted_app_id, campaign, convertDictionaryToJavaMap(userParams));
#endif
}
/// <summary>
/// To attribute an impression use the following API call.
/// Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard.
/// </summary>
/// <param name="appID">promoted App ID.</param>
/// <param name="campaign">cross promotion campaign.</param>
/// <param name="parameters">parameters Dictionary.</param>
public void recordCrossPromoteImpression(string appID, string campaign, Dictionary<string, string> parameters)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("recordCrossPromoteImpression", appID, campaign, convertDictionaryToJavaMap(parameters));
#endif
}
/// <summary>
/// The LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click.
/// See - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution-
/// </summary>
/// <param name="parameters">parameters Dictionary.</param>
public void generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("createOneLinkInviteListener", convertDictionaryToJavaMap(parameters), gameObject ? gameObject.name : null);
#endif
}
/// <summary>
/// To measure push notifications as part of a retargeting campaign.
/// </summary>
public void handlePushNotifications(){
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("handlePushNotifications");
#endif
}
/// <summary>
/// Use this method if youre integrating your app with push providers
/// that dont use the default push notification JSON schema the SDK expects.
/// See docs for more info.
/// </summary>
/// <param name="paths">array of nested json path</param>
public void addPushNotificationDeepLinkPath(params string[] paths)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("addPushNotificationDeepLinkPath", (object)paths);
#endif
}
/// <summary>
/// subscribe to unified deep link callbacks
/// </summary>
public void subscribeForDeepLink(string objectName){
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("subscribeForDeepLink", objectName);
#endif
}
/// <summary>
/// Disables collection of various Advertising IDs by the SDK. This includes Google Advertising ID (GAID), OAID and Amazon Advertising ID (AAID)
/// </summary>
/// <param name="disable">disable boolean.</param>
public void setDisableAdvertisingIdentifiers(bool disable)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setDisableAdvertisingIdentifiers", disable);
#endif
}
/// <summary>
/// Allows sending custom data for partner integration purposes.
/// </summary>
public void setPartnerData(string partnerId, Dictionary<string, string> partnerInfo)
{
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setPartnerData", partnerId, convertDictionaryToJavaMap(partnerInfo));
#endif
}
/// <summary>
/// Use to opt-out of collecting the network operator name (carrier) and sim operator name from the device.
/// </summary>
public void setDisableNetworkData(bool disable) {
#if !UNITY_EDITOR
appsFlyerAndroid.CallStatic("setDisableNetworkData", disable);
#endif
}
/// <summary>
/// Internal Helper Method.
/// </summary>
private static AndroidJavaObject getEmailType(EmailCryptType cryptType)
{
AndroidJavaClass emailsCryptTypeEnum = new AndroidJavaClass("com.appsflyer.AppsFlyerProperties$EmailsCryptType");
AndroidJavaObject emailsCryptType;
switch (cryptType)
{
case EmailCryptType.EmailCryptTypeSHA256:
emailsCryptType = emailsCryptTypeEnum.GetStatic<AndroidJavaObject>("SHA256");
break;
default:
emailsCryptType = emailsCryptTypeEnum.GetStatic<AndroidJavaObject>("NONE");
break;
}
return emailsCryptType;
}
/// <summary>
/// Internal Helper Method.
/// </summary>
private static AndroidJavaObject getMediationNetwork(MediationNetwork mediationNetwork)
{
AndroidJavaClass mediationNetworkEnumClass = new AndroidJavaClass("com.appsflyer.MediationNetwork");
AndroidJavaObject mediationNetworkObject;
switch (mediationNetwork)
{
case MediationNetwork.IronSource:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("IRONSOURCE");
break;
case MediationNetwork.ApplovinMax:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("APPLOVIN_MAX");
break;
case MediationNetwork.GoogleAdMob:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("GOOGLE_ADMOB");
break;
case MediationNetwork.Fyber:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("FYBER");
break;
case MediationNetwork.Appodeal:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("APPODEAL");
break;
case MediationNetwork.Admost:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("ADMOST");
break;
case MediationNetwork.Topon:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("TOPON");
break;
case MediationNetwork.Tradplus:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("TRADPLUS");
break;
case MediationNetwork.Yandex:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("YANDEX");
break;
case MediationNetwork.ChartBoost:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("CHARTBOOST");
break;
case MediationNetwork.Unity:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("UNITY");
break;
case MediationNetwork.ToponPte:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("TOPON_PTE");
break;
case MediationNetwork.Custom:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("CUSTOM_MEDIATION");
break;
case MediationNetwork.DirectMonetization:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("DIRECT_MONETIZATION_NETWORK");
break;
default:
mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>("NONE");
break;
}
return mediationNetworkObject;
}
/// <summary>
/// Internal Helper Method.
/// </summary>
private static AndroidJavaObject convertDictionaryToJavaMap(Dictionary<string, string> dictionary)
{
AndroidJavaObject map = new AndroidJavaObject("java.util.HashMap");
IntPtr putMethod = AndroidJNIHelper.GetMethodID(map.GetRawClass(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
jvalue[] val;
if (dictionary != null)
{
foreach (var entry in dictionary)
{
val = AndroidJNIHelper.CreateJNIArgArray(new object[] { entry.Key, entry.Value });
AndroidJNI.CallObjectMethod(map.GetRawObject(), putMethod,val);
AndroidJNI.DeleteLocalRef(val[0].l);
AndroidJNI.DeleteLocalRef(val[1].l);
}
}
return map;
}
}
#endif
}

View File

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

View File

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
namespace AppsFlyerSDK
{
/// <summary>
// Data class representing a user's consent for data processing in accordance with GDPR and DMA
// (Digital Markets Act) compliance, specifically regarding advertising preferences.
// This class should be used to notify and record the user's applicability
// under GDPR, their general consent to data usage, and their consent to personalized
// advertisements based on user data.
/// ## Properties:
/// - `isUserSubjectToGDPR` (optional) - Indicates whether GDPR regulations apply to the user.
/// This may also serve as a general compliance flag for other regional regulations.
/// - `hasConsentForDataUsage` (optional) - Indicates whether the user consents to the processing
/// of their data for advertising purposes.
/// - `hasConsentForAdsPersonalization` (optional) - Indicates whether the user consents to the
/// use of their data for personalized advertising.
/// - `hasConsentForAdStorage` (optional) - Indicates whether the user consents to ad-related storage access.
///
/// **Usage Example:**
/// ```csharp
/// var consent = new AppsFlyerConsent(
/// isUserSubjectToGDPR: true,
/// hasConsentForDataUsage: true,
/// hasConsentForAdsPersonalization: false,
/// hasConsentForAdStorage: true
/// );
/// **Deprecated APIs:**
/// - `ForGDPRUser(...)` and `ForNonGDPRUser(...)` should no longer be used.
/// - Use `new AppsFlyerConsent(...)` instead with relevant consent fields.
///
/// </summary>
public class AppsFlyerConsent
{
public bool? isUserSubjectToGDPR { get; private set; }
public bool? hasConsentForDataUsage { get; private set; }
public bool? hasConsentForAdsPersonalization { get; private set; }
public bool? hasConsentForAdStorage { get; private set; }
public AppsFlyerConsent( bool? isUserSubjectToGDPR = null, bool? hasConsentForDataUsage = null, bool? hasConsentForAdsPersonalization = null, bool? hasConsentForAdStorage = null)
{
this.isUserSubjectToGDPR = isUserSubjectToGDPR;
this.hasConsentForDataUsage = hasConsentForDataUsage;
this.hasConsentForAdsPersonalization = hasConsentForAdsPersonalization;
this.hasConsentForAdStorage = hasConsentForAdStorage;
}
[Obsolete("Use the new constructor with optional booleans instead.")]
private AppsFlyerConsent(bool isGDPR, bool hasForDataUsage, bool hasForAdsPersonalization)
{
isUserSubjectToGDPR = isGDPR;
hasConsentForDataUsage = hasForDataUsage;
hasConsentForAdsPersonalization = hasForAdsPersonalization;
}
[Obsolete("Use new AppsFlyerConsent(...) instead.")]
public static AppsFlyerConsent ForGDPRUser(bool hasConsentForDataUsage, bool hasConsentForAdsPersonalization)
{
return new AppsFlyerConsent(true, hasConsentForDataUsage, hasConsentForAdsPersonalization);
}
[Obsolete("Use new AppsFlyerConsent(...) instead.")]
public static AppsFlyerConsent ForNonGDPRUser()
{
return new AppsFlyerConsent(false);
}
}
}

View File

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

View File

@ -0,0 +1,218 @@
using System;
using System.Collections.Generic;
namespace AppsFlyerSDK
{
/// <summary>
/// Event args for AppsFlyer requests.
/// Used for sessions and in-app events.
/// Used to handle post request logic.
///
/// Examples:
/// statusCode / errorDescription
///
/// 200 - null
///
/// 10 - "Event timeout. Check 'minTimeBetweenSessions' param"
/// 11 - "Skipping event because 'isStopTracking' enabled"
/// 40 - Network error: Error description comes from Android
/// 41 - "No dev key"
/// 50 - "Status code failure" + actual response code from the server
///
/// </summary>
public class AppsFlyerRequestEventArgs : EventArgs
{
public AppsFlyerRequestEventArgs(int code, string description)
{
statusCode = code;
errorDescription = description;
}
public int statusCode { get; }
public string errorDescription { get; }
}
/// <summary>
/// Event args for OnDeepLinkReceived.
/// Used to handle deep linking results.
/// </summary>
public class DeepLinkEventsArgs : EventArgs
{
/// <summary>
/// DeepLink dictionary to get additional parameters
/// </summary>
public Dictionary<string, object> deepLink;
/// <summary>
/// DeepLink status: FOUND, NOT_FOUND, ERROR
/// </summary>
public DeepLinkStatus status { get; }
/// <summary>
/// DeepLink error: TIMEOUT, NETWORK, HTTP_STATUS_CODE, UNEXPECTED
/// </summary>
public DeepLinkError error { get; }
public string getMatchType()
{
return getDeepLinkParameter("match_type");
}
public string getDeepLinkValue()
{
return getDeepLinkParameter("deep_link_value");
}
public string getClickHttpReferrer()
{
return getDeepLinkParameter("click_http_referrer");
}
public string getMediaSource()
{
return getDeepLinkParameter("media_source");
}
public string getCampaign()
{
return getDeepLinkParameter("campaign");
}
public string getCampaignId()
{
return getDeepLinkParameter("campaign_id");
}
public string getAfSub1()
{
return getDeepLinkParameter("af_sub1");
}
public string getAfSub2()
{
return getDeepLinkParameter("af_sub2");
}
public string getAfSub3()
{
return getDeepLinkParameter("af_sub3");
}
public string getAfSub4()
{
return getDeepLinkParameter("af_sub4");
}
public string getAfSub5()
{
return getDeepLinkParameter("af_sub5");
}
public bool isDeferred()
{
if (deepLink != null && deepLink.ContainsKey("is_deferred"))
{
try
{
return (bool)deepLink["is_deferred"];
}
catch (Exception e)
{
AppsFlyer.AFLog("DeepLinkEventsArgs.isDeferred", String.Format("{0} Exception caught.", e));
}
}
return false;
}
public Dictionary<string, object> getDeepLinkDictionary()
{
return deepLink;
}
public DeepLinkEventsArgs(string str)
{
try
{
Dictionary<string, object> dictionary = AppsFlyer.CallbackStringToDictionary(str);
string status = "";
string error = "";
if (dictionary.ContainsKey("status") && dictionary["status"] != null)
{
status = dictionary["status"].ToString();
}
if (dictionary.ContainsKey("error") && dictionary["error"] != null)
{
error = dictionary["error"].ToString();
}
if (dictionary.ContainsKey("deepLink") && dictionary["deepLink"] != null)
{
this.deepLink = AppsFlyer.CallbackStringToDictionary(dictionary["deepLink"].ToString());
}
if (dictionary.ContainsKey("is_deferred"))
{
this.deepLink["is_deferred"] = dictionary["is_deferred"];
}
switch (status)
{
case "FOUND":
this.status = DeepLinkStatus.FOUND;
break;
case "NOT_FOUND":
this.status = DeepLinkStatus.NOT_FOUND;
break;
default:
this.status = DeepLinkStatus.ERROR;
break;
}
switch (error)
{
case "TIMEOUT":
this.error = DeepLinkError.TIMEOUT;
break;
case "NETWORK":
this.error = DeepLinkError.NETWORK;
break;
case "HTTP_STATUS_CODE":
this.error = DeepLinkError.HTTP_STATUS_CODE;
break;
default:
this.error = DeepLinkError.UNEXPECTED;
break;
}
}
catch (Exception e)
{
AppsFlyer.AFLog("DeepLinkEventsArgs.parseDeepLink", String.Format("{0} Exception caught.", e));
}
}
private string getDeepLinkParameter(string name)
{
if (deepLink != null && deepLink.ContainsKey(name) && deepLink[name] != null)
{
return deepLink[name].ToString();
}
return null;
}
}
public enum DeepLinkStatus {
FOUND, NOT_FOUND, ERROR
}
public enum DeepLinkError {
TIMEOUT, NETWORK, HTTP_STATUS_CODE, UNEXPECTED
}
}

View File

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

View File

@ -0,0 +1,49 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &7315102894599890749
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6207133488976360133}
- component: {fileID: 4405976200006927252}
m_Layer: 0
m_Name: AppsFlyerObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6207133488976360133
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7315102894599890749}
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!114 &4405976200006927252
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7315102894599890749}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2a2ec6ba1ee8b48749524f015ed572a6, type: 3}
m_Name:
m_EditorClassIdentifier:
devKey:
appID:
isDebug: 0
getConversionData: 0

View File

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

View File

@ -0,0 +1,70 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AppsFlyerSDK;
// This class is intended to be used the the AppsFlyerObject.prefab
public class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData
{
// These fields are set from the editor so do not modify!
//******************************//
public string devKey;
public string appID;
public string UWPAppID;
public string macOSAppID;
public bool isDebug;
public bool getConversionData;
//******************************//
void Start()
{
// These fields are set from the editor so do not modify!
//******************************//
AppsFlyer.setIsDebug(isDebug);
#if UNITY_WSA_10_0 && !UNITY_EDITOR
AppsFlyer.initSDK(devKey, UWPAppID, getConversionData ? this : null);
#elif UNITY_STANDALONE_OSX && !UNITY_EDITOR
AppsFlyer.initSDK(devKey, macOSAppID, getConversionData ? this : null);
#else
AppsFlyer.initSDK(devKey, appID, getConversionData ? this : null);
#endif
//******************************/
AppsFlyer.startSDK();
}
void Update()
{
}
// Mark AppsFlyer CallBacks
public void onConversionDataSuccess(string conversionData)
{
AppsFlyer.AFLog("didReceiveConversionData", conversionData);
Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
// add deferred deeplink logic here
}
public void onConversionDataFail(string error)
{
AppsFlyer.AFLog("didReceiveConversionDataWithError", error);
}
public void onAppOpenAttribution(string attributionData)
{
AppsFlyer.AFLog("onAppOpenAttribution", attributionData);
Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);
// add direct deeplink logic here
}
public void onAppOpenAttributionFailure(string error)
{
AppsFlyer.AFLog("onAppOpenAttributionFailure", error);
}
}

View File

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

View File

@ -0,0 +1,426 @@
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using System;
namespace AppsFlyerSDK
{
public interface IAppsFlyerPurchaseRevenueDataSource
{
Dictionary<string, object> PurchaseRevenueAdditionalParametersForProducts(HashSet<object> products, HashSet<object> transactions);
}
public interface IAppsFlyerPurchaseRevenueDataSourceStoreKit2
{
Dictionary<string, object> PurchaseRevenueAdditionalParametersStoreKit2ForProducts(HashSet<object> products, HashSet<object> transactions);
}
public class AppsFlyerPurchaseRevenueBridge : MonoBehaviour
{
#if UNITY_IOS && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void RegisterUnityPurchaseRevenueParamsCallback(Func<string, string, string> callback);
[DllImport("__Internal")]
private static extern void RegisterUnityPurchaseRevenueParamsCallbackSK2(Func<string, string, string> callback);
#endif
private static IAppsFlyerPurchaseRevenueDataSource _dataSource;
private static IAppsFlyerPurchaseRevenueDataSourceStoreKit2 _dataSourceSK2;
public static void RegisterDataSource(IAppsFlyerPurchaseRevenueDataSource dataSource)
{
_dataSource = dataSource;
#if UNITY_IOS && !UNITY_EDITOR
RegisterUnityPurchaseRevenueParamsCallback(GetAdditionalParameters);
#elif UNITY_ANDROID && !UNITY_EDITOR
using (AndroidJavaClass jc = new AndroidJavaClass("com.appsflyer.unity.PurchaseRevenueBridge"))
{
jc.CallStatic("setUnityBridge", new UnityPurchaseRevenueBridgeProxy());
}
#endif
}
public static void RegisterDataSourceStoreKit2(IAppsFlyerPurchaseRevenueDataSourceStoreKit2 dataSource)
{
#if UNITY_IOS && !UNITY_EDITOR
_dataSourceSK2 = dataSource;
RegisterUnityPurchaseRevenueParamsCallbackSK2(GetAdditionalParametersSK2);
#endif
}
public static Dictionary<string, object> GetAdditionalParametersForAndroid(HashSet<object> products, HashSet<object> transactions)
{
return _dataSource?.PurchaseRevenueAdditionalParametersForProducts(products, transactions)
?? new Dictionary<string, object>();
}
#if UNITY_IOS && !UNITY_EDITOR
[AOT.MonoPInvokeCallback(typeof(Func<string, string, string>))]
public static string GetAdditionalParameters(string productsJson, string transactionsJson)
{
try
{
HashSet<object> products = new HashSet<object>();
HashSet<object> transactions = new HashSet<object>();
if (!string.IsNullOrEmpty(productsJson))
{
var dict = AFMiniJSON.Json.Deserialize(productsJson) as Dictionary<string, object>;
if (dict != null)
{
if (dict.TryGetValue("products", out var productsObj) && productsObj is List<object> productList)
products = new HashSet<object>(productList);
if (dict.TryGetValue("transactions", out var transactionsObj) && transactionsObj is List<object> transactionList)
transactions = new HashSet<object>(transactionList);
}
}
var parameters = _dataSource?.PurchaseRevenueAdditionalParametersForProducts(products, transactions)
?? new Dictionary<string, object>();
return AFMiniJSON.Json.Serialize(parameters);
}
catch (Exception e)
{
Debug.LogError($"[AppsFlyer] Exception in GetAdditionalParameters: {e}");
return "{}";
}
}
#endif
#if UNITY_IOS && !UNITY_EDITOR
[AOT.MonoPInvokeCallback(typeof(Func<string, string, string>))]
public static string GetAdditionalParametersSK2(string productsJson, string transactionsJson)
{
try
{
HashSet<object> products = new HashSet<object>();
HashSet<object> transactions = new HashSet<object>();
if (!string.IsNullOrEmpty(productsJson))
{
var dict = AFMiniJSON.Json.Deserialize(productsJson) as Dictionary<string, object>;
if (dict != null && dict.TryGetValue("products", out var productsObj) && productsObj is List<object> productList)
products = new HashSet<object>(productList);
}
if (!string.IsNullOrEmpty(transactionsJson))
{
var dict = AFMiniJSON.Json.Deserialize(transactionsJson) as Dictionary<string, object>;
if (dict != null && dict.TryGetValue("transactions", out var transactionsObj) && transactionsObj is List<object> transactionList)
transactions = new HashSet<object>(transactionList);
}
var parameters = _dataSourceSK2?.PurchaseRevenueAdditionalParametersStoreKit2ForProducts(products, transactions)
?? new Dictionary<string, object>();
return AFMiniJSON.Json.Serialize(parameters);
}
catch (Exception e)
{
Debug.LogError($"[AppsFlyer] Exception in GetAdditionalParametersSK2: {e}");
return "{}";
}
}
#endif
}
public class UnityPurchaseRevenueBridgeProxy : AndroidJavaProxy
{
public UnityPurchaseRevenueBridgeProxy() : base("com.appsflyer.unity.PurchaseRevenueBridge$UnityPurchaseRevenueBridge") { }
public string getAdditionalParameters(string productsJson, string transactionsJson)
{
try
{
// Create empty sets if JSON is null or empty
HashSet<object> products = new HashSet<object>();
HashSet<object> transactions = new HashSet<object>();
// Only try to parse if we have valid JSON
if (!string.IsNullOrEmpty(productsJson))
{
try
{
// First try to parse as a simple array
var parsedProducts = AFMiniJSON.Json.Deserialize(productsJson);
if (parsedProducts is List<object> productList)
{
products = new HashSet<object>(productList);
}
else if (parsedProducts is Dictionary<string, object> dict)
{
if (dict.ContainsKey("events") && dict["events"] is List<object> eventsList)
{
products = new HashSet<object>(eventsList);
}
else
{
// If it's a dictionary but doesn't have events, add the whole dict
products.Add(dict);
}
}
}
catch (Exception e)
{
Debug.LogError($"Error parsing products JSON: {e.Message}\nJSON: {productsJson}");
}
}
if (!string.IsNullOrEmpty(transactionsJson))
{
try
{
// First try to parse as a simple array
var parsedTransactions = AFMiniJSON.Json.Deserialize(transactionsJson);
if (parsedTransactions is List<object> transactionList)
{
transactions = new HashSet<object>(transactionList);
}
else if (parsedTransactions is Dictionary<string, object> dict)
{
if (dict.ContainsKey("events") && dict["events"] is List<object> eventsList)
{
transactions = new HashSet<object>(eventsList);
}
else
{
// If it's a dictionary but doesn't have events, add the whole dict
transactions.Add(dict);
}
}
}
catch (Exception e)
{
Debug.LogError($"Error parsing transactions JSON: {e.Message}\nJSON: {transactionsJson}");
}
}
var parameters = AppsFlyerPurchaseRevenueBridge.GetAdditionalParametersForAndroid(products, transactions);
return AFMiniJSON.Json.Serialize(parameters);
}
catch (Exception e)
{
Debug.LogError($"Error in getAdditionalParameters: {e.Message}\nProducts JSON: {productsJson}\nTransactions JSON: {transactionsJson}");
return "{}";
}
}
}
public class AppsFlyerPurchaseConnector : MonoBehaviour {
private static AppsFlyerPurchaseConnector instance;
private Dictionary<string, object> pendingParameters;
private Action<Dictionary<string, object>> pendingCallback;
public static AppsFlyerPurchaseConnector Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("AppsFlyerPurchaseConnector");
instance = go.AddComponent<AppsFlyerPurchaseConnector>();
DontDestroyOnLoad(go);
}
return instance;
}
}
private void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
#if UNITY_ANDROID && !UNITY_EDITOR
private static AndroidJavaClass appsFlyerAndroidConnector = new AndroidJavaClass("com.appsflyer.unity.AppsFlyerAndroidWrapper");
#endif
public static void init(MonoBehaviour unityObject, Store s) {
#if UNITY_IOS && !UNITY_EDITOR
_initPurchaseConnector(unityObject.name);
#elif UNITY_ANDROID && !UNITY_EDITOR
int store = mapStoreToInt(s);
appsFlyerAndroidConnector.CallStatic("initPurchaseConnector", unityObject ? unityObject.name : null, store);
#endif
}
public static void build() {
#if UNITY_IOS && !UNITY_EDITOR
//not for iOS
#elif UNITY_ANDROID && !UNITY_EDITOR
appsFlyerAndroidConnector.CallStatic("build");
#else
#endif
}
public static void startObservingTransactions() {
#if UNITY_IOS && !UNITY_EDITOR
_startObservingTransactions();
#elif UNITY_ANDROID && !UNITY_EDITOR
appsFlyerAndroidConnector.CallStatic("startObservingTransactions");
#else
#endif
}
public static void stopObservingTransactions() {
#if UNITY_IOS && !UNITY_EDITOR
_stopObservingTransactions();
#elif UNITY_ANDROID && !UNITY_EDITOR
appsFlyerAndroidConnector.CallStatic("stopObservingTransactions");
#else
#endif
}
public static void setIsSandbox(bool isSandbox) {
#if UNITY_IOS && !UNITY_EDITOR
_setIsSandbox(isSandbox);
#elif UNITY_ANDROID && !UNITY_EDITOR
appsFlyerAndroidConnector.CallStatic("setIsSandbox", isSandbox);
#else
#endif
}
public static void setPurchaseRevenueValidationListeners(bool enableCallbacks) {
#if UNITY_IOS && !UNITY_EDITOR
_setPurchaseRevenueDelegate();
#elif UNITY_ANDROID && !UNITY_EDITOR
appsFlyerAndroidConnector.CallStatic("setPurchaseRevenueValidationListeners", enableCallbacks);
#else
#endif
}
public static void setAutoLogPurchaseRevenue(params AppsFlyerAutoLogPurchaseRevenueOptions[] autoLogPurchaseRevenueOptions) {
#if UNITY_IOS && !UNITY_EDITOR
int option = 0;
foreach (AppsFlyerAutoLogPurchaseRevenueOptions op in autoLogPurchaseRevenueOptions) {
option = option | (int)op;
}
_setAutoLogPurchaseRevenue(option);
#elif UNITY_ANDROID && !UNITY_EDITOR
if (autoLogPurchaseRevenueOptions.Length == 0) {
return;
}
foreach (AppsFlyerAutoLogPurchaseRevenueOptions op in autoLogPurchaseRevenueOptions) {
switch(op) {
case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsDisabled:
break;
case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions:
appsFlyerAndroidConnector.CallStatic("setAutoLogSubscriptions", true);
break;
case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases:
appsFlyerAndroidConnector.CallStatic("setAutoLogInApps", true);
break;
default:
break;
}
}
#else
#endif
}
public static void setPurchaseRevenueDataSource(IAppsFlyerPurchaseRevenueDataSource dataSource)
{
#if UNITY_IOS && !UNITY_EDITOR
if (dataSource != null)
{
_setPurchaseRevenueDataSource(dataSource.GetType().Name);
AppsFlyerPurchaseRevenueBridge.RegisterDataSource(dataSource);
}
#elif UNITY_ANDROID && !UNITY_EDITOR
if (dataSource != null)
{
AppsFlyerPurchaseRevenueBridge.RegisterDataSource(dataSource);
}
#endif
}
public static void setPurchaseRevenueDataSourceStoreKit2(IAppsFlyerPurchaseRevenueDataSourceStoreKit2 dataSourceSK2)
{
#if UNITY_IOS && !UNITY_EDITOR
if (dataSourceSK2 != null)
{
AppsFlyerPurchaseRevenueBridge.RegisterDataSourceStoreKit2(dataSourceSK2);
_setPurchaseRevenueDataSource("AppsFlyerObjectScript_StoreKit2");
}
#endif
}
private static int mapStoreToInt(Store s) {
switch(s) {
case(Store.GOOGLE):
return 0;
default:
return -1;
}
}
public static void setStoreKitVersion(StoreKitVersion storeKitVersion) {
#if UNITY_IOS && !UNITY_EDITOR
_setStoreKitVersion((int)storeKitVersion);
#elif UNITY_ANDROID && !UNITY_EDITOR
// Android doesn't use StoreKit
#else
#endif
}
public static void logConsumableTransaction(string transactionJson) {
#if UNITY_IOS && !UNITY_EDITOR
_logConsumableTransaction(transactionJson);
#elif UNITY_ANDROID && !UNITY_EDITOR
// Android doesn't use StoreKit
#else
#endif
}
#if UNITY_IOS && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void _startObservingTransactions();
[DllImport("__Internal")]
private static extern void _stopObservingTransactions();
[DllImport("__Internal")]
private static extern void _setIsSandbox(bool isSandbox);
[DllImport("__Internal")]
private static extern void _setPurchaseRevenueDelegate();
[DllImport("__Internal")]
private static extern void _setPurchaseRevenueDataSource(string dataSourceName);
[DllImport("__Internal")]
private static extern void _setAutoLogPurchaseRevenue(int option);
[DllImport("__Internal")]
private static extern void _initPurchaseConnector(string objectName);
[DllImport("__Internal")]
private static extern void _setStoreKitVersion(int storeKitVersion);
[DllImport("__Internal")]
private static extern void _logConsumableTransaction(string transactionJson);
#endif
}
public enum Store {
GOOGLE = 0
}
public enum AppsFlyerAutoLogPurchaseRevenueOptions
{
AppsFlyerAutoLogPurchaseRevenueOptionsDisabled = 0,
AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions = 1 << 0,
AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases = 1 << 1
}
public enum StoreKitVersion {
SK1 = 0,
SK2 = 1
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0636ea07d370d437183f3762280c08ce
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: b34371b3cc09641ebb007ffc4e9500f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,31 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AppsFlyerSDK
{
public interface IAppsFlyerAndroidBridge : IAppsFlyerNativeBridge
{
void updateServerUninstallToken(string token);
void setImeiData(string imei);
void setAndroidIdData(string androidId);
void waitForCustomerUserId(bool wait);
void setCustomerIdAndStartSDK(string id);
string getOutOfStore();
void setOutOfStore(string sourceName);
void setCollectAndroidID(bool isCollect);
void setCollectIMEI(bool isCollect);
void setIsUpdate(bool isUpdate);
void setPreinstallAttribution(string mediaSource, string campaign, string siteId);
bool isPreInstalledApp();
string getAttributionId();
void handlePushNotifications();
void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject);
void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject);
void setCollectOaid(bool isCollect);
void setDisableAdvertisingIdentifiers(bool disable);
void setDisableNetworkData(bool disable);
}
}

View File

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

View File

@ -0,0 +1,31 @@
namespace AppsFlyerSDK
{
public interface IAppsFlyerConversionData
{
/// <summary>
/// `conversionData` contains information about install. Organic/non-organic, etc.
/// <see>https://support.appsflyer.com/hc/en-us/articles/360000726098-Conversion-Data-Scenarios#Introduction</see>
/// </summary>
/// <param name="conversionData">JSON string of the returned conversion data.</param>
void onConversionDataSuccess(string conversionData);
/// <summary>
/// Any errors that occurred during the conversion request.
/// </summary>
/// <param name="error">A string describing the error.</param>
void onConversionDataFail(string error);
/// <summary>
/// `attributionData` contains information about OneLink, deeplink.
/// <see>https://support.appsflyer.com/hc/en-us/articles/208874366-OneLink-Deep-Linking-Guide#Intro</see>
/// </summary>
/// <param name="attributionData">JSON string of the returned deeplink data.</param>
void onAppOpenAttribution(string attributionData);
/// <summary>
/// Any errors that occurred during the attribution request.
/// </summary>
/// <param name="error">A string describing the error.</param>
void onAppOpenAttributionFailure(string error);
}
}

View File

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

View File

@ -0,0 +1,26 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AppsFlyerSDK
{
public interface IAppsFlyerIOSBridge : IAppsFlyerNativeBridge
{
void setDisableCollectAppleAdSupport(bool disable);
void setShouldCollectDeviceName(bool shouldCollectDeviceName);
void setDisableCollectIAd(bool disableCollectIAd);
void setUseReceiptValidationSandbox(bool useReceiptValidationSandbox);
void setUseUninstallSandbox(bool useUninstallSandbox);
void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject);
void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject);
void registerUninstall(byte[] deviceToken);
void handleOpenUrl(string url, string sourceApplication, string annotation);
void waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval);
void setCurrentDeviceLanguage(string language);
void disableSKAdNetwork(bool isDisabled);
void disableIDFVCollection(bool isDisabled);
}
}

View File

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

View File

@ -0,0 +1,76 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AppsFlyerSDK
{
public interface IAppsFlyerNativeBridge
{
bool isInit { get; set; }
void startSDK(bool onRequestResponse, string CallBackObjectName);
void sendEvent(string eventName, Dictionary<string, string> eventValues, bool onInAppResponse, string CallBackObjectName);
void stopSDK(bool isSDKStopped);
bool isSDKStopped();
string getSdkVersion();
void setCustomerUserId(string id);
void setAppInviteOneLinkID(string oneLinkId);
void setAdditionalData(Dictionary<string, string> customData);
void setDeepLinkTimeout(long deepLinkTimeout);
void setResolveDeepLinkURLs(params string[] urls);
void setOneLinkCustomDomain(params string[] domains);
void setCurrencyCode(string currencyCode);
void recordLocation(double latitude, double longitude);
void anonymizeUser(bool shouldAnonymizeUser);
string getAppsFlyerId();
void enableTCFDataCollection(bool shouldCollectTcfData);
void setConsentData(AppsFlyerConsent appsFlyerConsent);
void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary<string, string> additionalParameters);
void setMinTimeBetweenSessions(int seconds);
void setHost(string hostPrefixName, string hostName);
void setPhoneNumber(string phoneNumber);
void setSharingFilterForAllPartners();
void setSharingFilter(params string[] partners);
void getConversionData(string objectName);
void attributeAndOpenStore(string appID, string campaign, Dictionary<string, string> userParams, MonoBehaviour gameObject);
void recordCrossPromoteImpression(string appID, string campaign, Dictionary<string, string> parameters);
void generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject);
void addPushNotificationDeepLinkPath(params string[] paths);
void setUserEmails(EmailCryptType cryptType, params string[] userEmails);
void subscribeForDeepLink(string objectName);
void setIsDebug(bool shouldEnable);
void setPartnerData(string partnerId, Dictionary<string, string> partnerInfo);
}
}

View File

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

View File

@ -0,0 +1,8 @@
namespace AppsFlyerSDK
{
public interface IAppsFlyerPurchaseValidation
{
void didReceivePurchaseRevenueValidationInfo(string validationInfo);
void didReceivePurchaseRevenueError(string error);
}
}

View File

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

View File

@ -0,0 +1,26 @@
namespace AppsFlyerSDK
{
public interface IAppsFlyerUserInvite
{
/// <summary>
/// The success callback for generating OneLink URLs.
/// </summary>
/// <param name="link">A string of the newly created url.</param>
void onInviteLinkGenerated(string link);
/// <summary>
/// The error callback for generating OneLink URLs
/// </summary>
/// <param name="error">A string describing the error.</param>
void onInviteLinkGeneratedFailure(string error);
/// <summary>
/// (ios only) iOS allows you to utilize the StoreKit component to open
/// the App Store while remaining in the context of your app.
/// More details at <see>https://support.appsflyer.com/hc/en-us/articles/115004481946-Cross-Promotion-Tracking#tracking-cross-promotion-impressions</see>
/// </summary>
/// <param name="link">openStore callback Contains promoted `clickURL`</param>
void onOpenStoreLinkGenerated(string link);
}
}

View File

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

View File

@ -0,0 +1,19 @@
namespace AppsFlyerSDK
{
public interface IAppsFlyerValidateAndLog
{
/// <summary>
/// The success callback for validateAndSendInAppPurchase API.
/// For Android : the callback will return JSON string.
/// For iOS : the callback will return a JSON string from apples verifyReceipt API.
/// </summary>
/// <param name="result"></param>
void onValidateAndLogComplete(string result);
/// <summary>
/// The error callback for validateAndSendInAppPurchase API.
/// </summary>
/// <param name="error">A string describing the error.</param>
void onValidateAndLogFailure(string error);
}
}

View File

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

View File

@ -0,0 +1,19 @@
namespace AppsFlyerSDK
{
public interface IAppsFlyerValidateReceipt
{
/// <summary>
/// The success callback for validateAndSendInAppPurchase API.
/// For Android : the callback will return "Validate success".
/// For iOS : the callback will return a JSON string from apples verifyReceipt API.
/// </summary>
/// <param name="result"></param>
void didFinishValidateReceipt(string result);
/// <summary>
/// The error callback for validateAndSendInAppPurchase API.
/// </summary>
/// <param name="error">A string describing the error.</param>
void didFinishValidateReceiptWithError(string error);
}
}

View File

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

View File

@ -0,0 +1,184 @@
#nullable enable
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
[System.Serializable]
public class InAppPurchaseValidationResult : EventArgs
{
public bool success;
public ProductPurchase? productPurchase;
public ValidationFailureData? failureData;
public string? token;
}
[System.Serializable]
public class ProductPurchase
{
public string? kind;
public string? purchaseTimeMillis;
public int purchaseState;
public int consumptionState;
public string? developerPayload;
public string? orderId;
public int purchaseType;
public int acknowledgementState;
public string? purchaseToken;
public string? productId;
public int quantity;
public string? obfuscatedExternalAccountId;
public string? obfuscatedExternalProfil;
public string? regionCode;
}
[System.Serializable]
public class ValidationFailureData
{
public int status;
public string? description;
}
[System.Serializable]
public class SubscriptionValidationResult
{
public bool success;
public SubscriptionPurchase? subscriptionPurchase;
public ValidationFailureData? failureData;
public string? token;
}
[System.Serializable]
public class SubscriptionPurchase
{
public string? acknowledgementState;
public CanceledStateContext? canceledStateContext;
public ExternalAccountIdentifiers? externalAccountIdentifiers;
public string? kind;
public string? latestOrderId;
public List<SubscriptionPurchaseLineItem>? lineItems;
public string? linkedPurchaseToken;
public PausedStateContext? pausedStateContext;
public string? regionCode;
public string? startTime;
public SubscribeWithGoogleInfo? subscribeWithGoogleInfo;
public string? subscriptionState;
public TestPurchase? testPurchase;
}
[System.Serializable]
public class CanceledStateContext
{
public DeveloperInitiatedCancellation? developerInitiatedCancellation;
public ReplacementCancellation? replacementCancellation;
public SystemInitiatedCancellation? systemInitiatedCancellation;
public UserInitiatedCancellation? userInitiatedCancellation;
}
[System.Serializable]
public class ExternalAccountIdentifiers
{
public string? externalAccountId;
public string? obfuscatedExternalAccountId;
public string? obfuscatedExternalProfileId;
}
[System.Serializable]
public class SubscriptionPurchaseLineItem
{
public AutoRenewingPlan? autoRenewingPlan;
public DeferredItemReplacement? deferredItemReplacement;
public string? expiryTime;
public OfferDetails? offerDetails;
public PrepaidPlan? prepaidPlan;
public string? productId;
}
[System.Serializable]
public class PausedStateContext
{
public string? autoResumeTime;
}
[System.Serializable]
public class SubscribeWithGoogleInfo
{
public string? emailAddress;
public string? familyName;
public string? givenName;
public string? profileId;
public string? profileName;
}
[System.Serializable]
public class TestPurchase{}
[System.Serializable]
public class DeveloperInitiatedCancellation{}
[System.Serializable]
public class ReplacementCancellation{}
[System.Serializable]
public class SystemInitiatedCancellation{}
[System.Serializable]
public class UserInitiatedCancellation
{
public CancelSurveyResult? cancelSurveyResult;
public string? cancelTime;
}
[System.Serializable]
public class AutoRenewingPlan
{
public string? autoRenewEnabled;
public SubscriptionItemPriceChangeDetails? priceChangeDetails;
}
[System.Serializable]
public class DeferredItemReplacement
{
public string? productId;
}
[System.Serializable]
public class OfferDetails
{
public List<string>? offerTags;
public string? basePlanId;
public string? offerId;
}
[System.Serializable]
public class PrepaidPlan
{
public string? allowExtendAfterTime;
}
[System.Serializable]
public class CancelSurveyResult
{
public string? reason;
public string? reasonUserInput;
}
[System.Serializable]
public class SubscriptionItemPriceChangeDetails
{
public string? expectedNewPriceChargeTime;
public Money? newPrice;
public string? priceChangeMode;
public string? priceChangeState;
}
[System.Serializable]
public class Money
{
public string? currencyCode;
public long nanos;
public long units;
}

View File

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

View File

@ -0,0 +1,6 @@
{
"name": "com.bywaystudios.appsflyersdk",
"displayName": "AppsFlyerSDK",
"version": "6.17.72-exp.1",
"description": "AppsFlyer Unity SDK"
}

View File

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

48
Packages/manifest.json Normal file
View File

@ -0,0 +1,48 @@
{
"dependencies": {
"com.unity.asset-store-validation": "0.6.0",
"com.unity.collab-proxy": "2.10.2",
"com.unity.editorcoroutines": "1.0.1",
"com.unity.feature.development": "1.0.1",
"com.unity.ide.rider": "3.0.38",
"com.unity.ide.visualstudio": "2.0.25",
"com.unity.ide.vscode": "1.2.5",
"com.unity.nuget.newtonsoft-json": "3.2.2",
"com.unity.performance.profile-analyzer": "1.2.4",
"com.unity.settings-manager": "2.1.1",
"com.unity.test-framework": "1.1.33",
"com.unity.testtools.codecoverage": "1.2.7",
"com.unity.upm.develop": "0.5.3-exp.1",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}

375
Packages/packages-lock.json Normal file
View File

@ -0,0 +1,375 @@
{
"dependencies": {
"com.bywaystudios.appsflyersdk": {
"version": "file:com.bywaystudios.appsflyersdk",
"depth": 0,
"source": "embedded",
"dependencies": {}
},
"com.unity.asset-store-validation": {
"version": "0.6.0",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.nuget.newtonsoft-json": "2.0.2"
},
"url": "https://packages.unity.com"
},
"com.unity.collab-proxy": {
"version": "2.10.2",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.editorcoroutines": {
"version": "1.0.1",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
"version": "1.0.6",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.feature.development": {
"version": "1.0.1",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.ide.visualstudio": "2.0.22",
"com.unity.ide.rider": "3.0.36",
"com.unity.ide.vscode": "1.2.5",
"com.unity.editorcoroutines": "1.0.0",
"com.unity.performance.profile-analyzer": "1.2.3",
"com.unity.test-framework": "1.1.33",
"com.unity.testtools.codecoverage": "1.2.6"
}
},
"com.unity.ide.rider": {
"version": "3.0.38",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.25",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.31"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.vscode": {
"version": "1.2.5",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.nuget.newtonsoft-json": {
"version": "3.2.2",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.performance.profile-analyzer": {
"version": "1.2.4",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.settings-manager": {
"version": "2.1.1",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.33",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.testtools.codecoverage": {
"version": "1.2.7",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.0.16",
"com.unity.settings-manager": "1.0.1"
},
"url": "https://packages.unity.com"
},
"com.unity.upm.develop": {
"version": "0.5.3-exp.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.20",
"com.unity.nuget.newtonsoft-json": "2.0.2",
"com.unity.asset-store-validation": "0.1.3"
},
"url": "https://packages.unity.com"
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imgui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.jsonserialize": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics2d": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.screencapture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.subsystems": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.uielements": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.umbra": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unityanalytics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.unitywebrequest": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unitywebrequestassetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.unitywebrequestaudio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.audio": "1.0.0"
}
},
"com.unity.modules.unitywebrequesttexture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.unitywebrequestwww": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.video": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.vr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"com.unity.modules.wind": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.xr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.subsystems": "1.0.0"
}
}
}
}

View File

@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!11 &1
AudioManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Volume: 1
Rolloff Scale: 1
Doppler Factor: 1
Default Speaker Mode: 2
m_SampleRate: 0
m_DSPBufferSize: 1024
m_VirtualVoiceCount: 512
m_RealVoiceCount: 32
m_SpatializerPlugin:
m_AmbisonicDecoderPlugin:
m_DisableAudio: 0
m_VirtualizeEffects: 1
m_RequestedDSPBufferSize: 1024

View File

@ -0,0 +1,6 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!236 &1
ClusterInputManager:
m_ObjectHideFlags: 0
m_Inputs: []

View File

@ -0,0 +1,34 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!55 &1
PhysicsManager:
m_ObjectHideFlags: 0
serializedVersion: 11
m_Gravity: {x: 0, y: -9.81, z: 0}
m_DefaultMaterial: {fileID: 0}
m_BounceThreshold: 2
m_SleepThreshold: 0.005
m_DefaultContactOffset: 0.01
m_DefaultSolverIterations: 6
m_DefaultSolverVelocityIterations: 1
m_QueriesHitBackfaces: 0
m_QueriesHitTriggers: 1
m_EnableAdaptiveForce: 0
m_ClothInterCollisionDistance: 0
m_ClothInterCollisionStiffness: 0
m_ContactsGeneration: 1
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_AutoSimulation: 1
m_AutoSyncTransforms: 0
m_ReuseCollisionCallbacks: 1
m_ClothInterCollisionSettingsToggle: 0
m_ContactPairsMode: 0
m_BroadphaseType: 0
m_WorldBounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 250, y: 250, z: 250}
m_WorldSubdivisions: 8
m_FrictionType: 0
m_EnableEnhancedDeterminism: 0
m_EnableUnifiedHeightmaps: 1
m_DefaultMaxAngluarSpeed: 7

View File

@ -0,0 +1,8 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1045 &1
EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes: []
m_configObjects: {}

View File

@ -0,0 +1,30 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!159 &1
EditorSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_ExternalVersionControlSupport: Visible Meta Files
m_SerializationMode: 2
m_LineEndingsForNewScripts: 0
m_DefaultBehaviorMode: 0
m_PrefabRegularEnvironment: {fileID: 0}
m_PrefabUIEnvironment: {fileID: 0}
m_SpritePackerMode: 0
m_SpritePackerPaddingPower: 1
m_EtcTextureCompressorBehavior: 1
m_EtcTextureFastCompressor: 1
m_EtcTextureNormalCompressor: 2
m_EtcTextureBestCompressor: 4
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref
m_ProjectGenerationRootNamespace:
m_CollabEditorSettings:
inProgressEnabled: 1
m_EnableTextureStreamingInEditMode: 1
m_EnableTextureStreamingInPlayMode: 1
m_AsyncShaderCompilation: 1
m_EnterPlayModeOptionsEnabled: 0
m_EnterPlayModeOptions: 3
m_ShowLightmapResolutionOverlay: 1
m_UseLegacyProbeSampleCount: 0
m_SerializeInlineMappingsOnOneLine: 1

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