[M] deep link
This commit is contained in:
206
sdk-intergration/Assets/Scripts/AFDeepLinkHelper.cs
Normal file
206
sdk-intergration/Assets/Scripts/AFDeepLinkHelper.cs
Normal file
@@ -0,0 +1,206 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using AppsFlyerSDK;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
public class AFDeepLinkHelper : MonoBehaviour, IAppsFlyerConversionData, IAppsFlyerUserInvite
|
||||
{
|
||||
public bool DidReceivedDeepLink {get; private set;} // marks if we got a DL and processed it
|
||||
private Dictionary<string, object> _conversionDataDictionary;
|
||||
private Dictionary<string, object> _deepLinkParamsDictionary;
|
||||
|
||||
public bool IsFirstLaunch {get ; private set;}
|
||||
public string AFState {get ; private set;}
|
||||
public IReadOnlyDictionary<string, object> DeepLinkParamsDictionary => _deepLinkParamsDictionary;
|
||||
public IReadOnlyDictionary<string, object> ConversionDataDictionary => _conversionDataDictionary;
|
||||
public string AttributionData {get; private set;}
|
||||
|
||||
private string _referrerUID;
|
||||
private string _inviteLink;
|
||||
private TaskCompletionSource<string> _tcs;
|
||||
public string StoreLink {get; private set;}
|
||||
|
||||
public bool GetDLReferer(out string pid, out string uid)
|
||||
{
|
||||
pid = null;
|
||||
uid = null;
|
||||
|
||||
if(!DidReceivedDeepLink)
|
||||
return false;
|
||||
if(_deepLinkParamsDictionary == null)
|
||||
return false;
|
||||
|
||||
if(_deepLinkParamsDictionary.TryGetValue("deep_link_value", out var deep_link_value))
|
||||
{
|
||||
if((string)deep_link_value != "friend_invite")
|
||||
return false;
|
||||
|
||||
if(_deepLinkParamsDictionary.TryGetValue("deep_link_sub2", out var referrer_pid))
|
||||
pid = (string)referrer_pid;
|
||||
if(_deepLinkParamsDictionary.TryGetValue("deep_link_sub1", out var referrer_uid))
|
||||
uid = (string)referrer_uid;
|
||||
|
||||
if(!string.IsNullOrEmpty(pid) && !string.IsNullOrEmpty(uid))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static AFDeepLinkHelper Instance {get; private set;}
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
AppsFlyer.setIsDebug(true);
|
||||
AppsFlyer.setAppInviteOneLinkID("jT1Q");
|
||||
AppsFlyer.initSDK("rSySeWtvKabfbPZE7Lmx7C", "6505145935", this);
|
||||
AppsFlyer.OnDeepLinkReceived += OnDeepLink;
|
||||
AppsFlyer.startSDK();
|
||||
}
|
||||
|
||||
public async Task<string> GenInviteLink(string referrerUID, string referrerPID)
|
||||
{
|
||||
if(referrerUID == _referrerUID && !string.IsNullOrEmpty(_inviteLink))
|
||||
return _inviteLink;
|
||||
_inviteLink = string.Empty;
|
||||
Dictionary<string, string> parameters = new Dictionary<string, string>();
|
||||
parameters.Add("channel", "mobile_share");
|
||||
parameters.Add("campaign", "friend_invite");
|
||||
|
||||
parameters.Add("deep_link_value", "friend_invite");
|
||||
parameters.Add("deep_link_sub1", referrerUID);
|
||||
parameters.Add("deep_link_sub2", referrerPID);
|
||||
// Optional; makes the referrer ID available in the installs raw-data report
|
||||
parameters.Add("af_sub1", referrerPID);
|
||||
|
||||
_tcs = new TaskCompletionSource<string>();
|
||||
AppsFlyer.generateUserInviteLink(parameters, this);
|
||||
_inviteLink = await _tcs.Task;
|
||||
return _inviteLink;
|
||||
}
|
||||
|
||||
#region Implement IAppsFlyerConversionData
|
||||
|
||||
public void onConversionDataSuccess(string conversionData)
|
||||
{
|
||||
Debug.Log("[AFDeepLinkHelper::didReceiveConversionData] success" );
|
||||
Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
|
||||
_conversionDataDictionary = conversionDataDictionary;
|
||||
|
||||
// af_status and is_first_launch always received with onConversionDataSuccess, no need to check if the keys exist
|
||||
AFState = _conversionDataDictionary["af_status"].ToString();
|
||||
IsFirstLaunch = (bool)_conversionDataDictionary["is_first_launch"];
|
||||
}
|
||||
|
||||
public void onConversionDataFail(string error)
|
||||
{
|
||||
Debug.LogWarning("[AFDeepLinkHelper::didReceiveConversionData] error: " + error);
|
||||
_conversionDataDictionary = null;
|
||||
}
|
||||
|
||||
public void onAppOpenAttribution(string attributionData)
|
||||
{
|
||||
Debug.Log("[AFDeepLinkHelper::onAppOpenAttribution] " + attributionData);
|
||||
AttributionData = attributionData;
|
||||
}
|
||||
|
||||
public void onAppOpenAttributionFailure(string error)
|
||||
{
|
||||
Debug.LogWarning("[AFDeepLinkHelper::onAppOpenAttributionFailure] error: " + error);
|
||||
AttributionData = null;
|
||||
}
|
||||
|
||||
#endregion // Implement IAppsFlyerConversionData
|
||||
|
||||
#region Implement IAppsFlyerUserInvite
|
||||
|
||||
public void onInviteLinkGenerated(string link)
|
||||
{
|
||||
if(_tcs != null)
|
||||
{
|
||||
_tcs.SetResult(link);
|
||||
}
|
||||
}
|
||||
|
||||
public void onInviteLinkGeneratedFailure(string error)
|
||||
{
|
||||
if(_tcs != null)
|
||||
{
|
||||
_tcs.SetResult(string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public void onOpenStoreLinkGenerated(string link)
|
||||
{
|
||||
Debug.Log("[AFDeepLinkHelper::onOpenStoreLinkGenerated] " + link);
|
||||
StoreLink = link;
|
||||
}
|
||||
|
||||
#endregion // Implement IAppsFlyerUserInvite
|
||||
|
||||
|
||||
#region Deeplink
|
||||
|
||||
/** All the DeepLink handling has to be done under the onDeepLink handler **/
|
||||
void OnDeepLink(object sender, EventArgs args)
|
||||
{
|
||||
if (!(args is DeepLinkEventsArgs deepLinkEventArgs)) return;
|
||||
|
||||
Debug.Log($"[AFDeepLinkHelper::onDeepLink] DeepLink Status {deepLinkEventArgs.status.ToString()}");
|
||||
|
||||
switch (deepLinkEventArgs.status)
|
||||
{
|
||||
case DeepLinkStatus.FOUND:
|
||||
|
||||
DidReceivedDeepLink = true;
|
||||
|
||||
if (deepLinkEventArgs.isDeferred())
|
||||
{
|
||||
Debug.Log($"[AFDeepLinkHelper::onDeepLink] DeepLink is deferred");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"[AFDeepLinkHelper::onDeepLink] This is a direct deep link");
|
||||
}
|
||||
_deepLinkParamsDictionary = GetDeepLinkParamsDictionary(deepLinkEventArgs);
|
||||
break;
|
||||
|
||||
case DeepLinkStatus.NOT_FOUND:
|
||||
Debug.Log($"[AFDeepLinkHelper::onDeepLink] DeepLink not found");
|
||||
break;
|
||||
default:
|
||||
Debug.LogWarning($"[AFDeepLinkHelper::onDeepLink] DeepLink error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the DeepLink params depending on the device OS **/
|
||||
private Dictionary<string, object> GetDeepLinkParamsDictionary(DeepLinkEventsArgs deepLinkEventArgs)
|
||||
{
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
if (deepLinkEventArgs.deepLink.ContainsKey("click_event") && deepLinkEventArgs.deepLink["click_event"] != null)
|
||||
{
|
||||
return deepLinkEventArgs.deepLink["click_event"] as Dictionary<string, object>;
|
||||
}
|
||||
#elif UNITY_ANDROID && !UNITY_EDITOR
|
||||
return deepLinkEventArgs.deepLink;
|
||||
#endif
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion // Deeplink
|
||||
}
|
||||
11
sdk-intergration/Assets/Scripts/AFDeepLinkHelper.cs.meta
Normal file
11
sdk-intergration/Assets/Scripts/AFDeepLinkHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 523a95a3b13874c0d9fa51543e9024ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
78
sdk-intergration/Assets/Scripts/AFInit.cs
Normal file
78
sdk-intergration/Assets/Scripts/AFInit.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System.Text;
|
||||
using AppsFlyerSDK;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class AFInit
|
||||
{
|
||||
public Text text {get; set;}
|
||||
|
||||
[Btn("Clear")]
|
||||
public void Clear()
|
||||
{
|
||||
text.text = "";
|
||||
}
|
||||
|
||||
[Btn("Init AF")]
|
||||
public void InitAF()
|
||||
{
|
||||
AFDeepLinkHelper.Instance.Init();
|
||||
text.text = $"Init AF {AppsFlyer.CallBackObjectName}\n";
|
||||
}
|
||||
|
||||
[Btn("Gen Url")]
|
||||
public async void GenInviteUrl()
|
||||
{
|
||||
var url = await AFDeepLinkHelper.Instance.GenInviteLink("Mustapha", "123456");
|
||||
if(url != null)
|
||||
{
|
||||
Debug.Log($"[AFInit::GenInviteUrl] {url}");
|
||||
text.text = $"{url}\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
text.text = $"Error\n";
|
||||
}
|
||||
}
|
||||
|
||||
[Btn("DeepLinkData")]
|
||||
public void DeepLinkData()
|
||||
{
|
||||
if(AFDeepLinkHelper.Instance.DidReceivedDeepLink)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append($"DeepLinkData \n");
|
||||
foreach(var item in AFDeepLinkHelper.Instance.DeepLinkParamsDictionary)
|
||||
{
|
||||
sb.Append($"{item.Key} : {item.Value}\n");
|
||||
sb.AppendLine();
|
||||
}
|
||||
var data = sb.ToString();
|
||||
text.text = data;
|
||||
Debug.Log($"[AFInit::DeepLinkData]\r\n{data}");
|
||||
}
|
||||
else
|
||||
text.text = $"No DL\n";
|
||||
}
|
||||
|
||||
[Btn("Referrer")]
|
||||
public void Referer()
|
||||
{
|
||||
if(AFDeepLinkHelper.Instance.GetDLReferer(out string pid, out string uid))
|
||||
{
|
||||
text.text = $"Referrer pid:{pid} uid:{uid}\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
text.text = $"No Referrer\n";
|
||||
}
|
||||
}
|
||||
|
||||
[Btn("SDK Test")]
|
||||
public void SDKTest()
|
||||
{
|
||||
SceneManager.LoadScene("SampleScene");
|
||||
}
|
||||
|
||||
}
|
||||
11
sdk-intergration/Assets/Scripts/AFInit.cs.meta
Normal file
11
sdk-intergration/Assets/Scripts/AFInit.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 517033da1396840dc92b14ef319d1606
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
45
sdk-intergration/Assets/Scripts/OneLinkTest.cs
Normal file
45
sdk-intergration/Assets/Scripts/OneLinkTest.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class OneLinkTest : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private GameObject btnContainer;
|
||||
|
||||
[SerializeField] private GameObject btn;
|
||||
|
||||
[SerializeField] private Text message;
|
||||
|
||||
void Start()
|
||||
{
|
||||
var aFInit = new AFInit();
|
||||
|
||||
aFInit.text = message;
|
||||
// Get funcs methods witch has Btn attribute
|
||||
var methods = aFInit.GetType().GetMethods();
|
||||
foreach (var method in methods)
|
||||
{
|
||||
var btnAttr = method.GetCustomAttribute<BtnAttribute>();
|
||||
if (btnAttr == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var btnObj = Instantiate(btn, btnContainer.transform);
|
||||
btnObj.GetComponentInChildren<Text>().text = btnAttr.btnName;
|
||||
btnObj.GetComponent<Button>().onClick.AddListener(() => method.Invoke(aFInit, null));
|
||||
btnObj.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
|
||||
public class BtnAttribute : Attribute
|
||||
{
|
||||
public string btnName;
|
||||
public BtnAttribute(string btnName)
|
||||
{
|
||||
this.btnName = btnName;
|
||||
}
|
||||
}
|
||||
11
sdk-intergration/Assets/Scripts/OneLinkTest.cs.meta
Normal file
11
sdk-intergration/Assets/Scripts/OneLinkTest.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6214202362ba44a71a557a55ce271445
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user