提示:Unity接入AppsFlyer这里不进行介绍了(后面有时间我再单独写一个AppsFlyer的接入),可以查阅官方文档,写的很详细
Unity接入AppsFlyer官方文档
提示:这篇文字只介绍在Unity中如何使用AppsFlyer动态生成DeepLink
文章目录
前言
为什么要使用AppsFlyer的DeepLink:
原因1:AppsFlyer是海外市场最大的归因平台,也可选择Adjust或Branch,这是海外最大的3个平台
原因2:DeepLink实际上就是一个网页,里面附带了许多参数,可以获取App安装来源的信息,这种功能实际上可以自己的后端实现,但是别人是实现好了的,直接用就行了。
一、AppsFlyer后台设置
1、进入AF后台,左侧菜单栏,点开互动,选择OneLink管理
2、选择对应的App
3、点击右侧3个点,点击添加OneLink模板
4、填写模板名称,选择App,填写子域名,这个域名可以随便取一个自己喜欢的。
5、跳转设置:若用户未安装应用,他会默认选择跳转到对应的市场,重点就设置一下用户已安装应用的情况,我们选择URI scheme备用方案,使用URI scheme调起应用,里面配置URI scheme,这个值需要和AndroidManifest里面的scheme对应,否则无法连接无法调起App
6、点击右下角创建模板即可。
二、生成动态DeepLink关键代码
1、需要继承IAppsFlyerUserInvite并实现里面的3个接口
public class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData , IAppsFlyerUserInvite
public void onInviteLinkGenerated(string link)
{
AppsFlyer.AFLog("onInviteLinkGenerated", link);
if(generateLinkHandle!=null)
{
//生成DeepLink成功,这里需要写自己的逻辑,把Link返回给上层。
//generateLinkHandle(link);
}
}
public void onInviteLinkGeneratedFailure(string error)
{
AppsFlyer.AFLog("onInviteLinkGeneratedFailure", error);
}
public void onOpenStoreLinkGenerated(string link)
{
AppsFlyer.AFLog("onOpenStoreLinkGenerated", link);
}
2、AF初始化时只需添加一句代码:AppsFlyer.setAppInviteOneLinkID(linkTemplate);
代码如下:
//linkTemplate是AF后台创建的模板ID。
AppsFlyer.setAppInviteOneLinkID(liknTemplate);
3、底层完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AppsFlyerSDK;
using System.Runtime.InteropServices;
using System;
// This class is intended to be used the the AppsFlyerObject.prefab
public class AppsFlyerObjectScript : MonoBehaviour, IAppsFlyerConversionData, IAppsFlyerUserInvite
{
// These fields are set from the editor so do not modify!
//******************************//
public string devKey= "TWdfkBQ7ngU33bKkHDo4KW";//这个key需要换成自己AF的appKey
public string iosdevKey= "";
public string appID= "";
public bool isDebug=false;
public bool getConversionData=true;
public static string deepLinkUrl = "";
public static string afCallBackData = "";
private string liknTemplate = "VEdu";//这个liknTemplate需要换成自己AF的模板ID
private static Action<string> generateLinkHandle = null;
public static string afAttributionData = "";
//******************************//
#if UNITY_IPHONE
[DllImport("__Internal")]
private static extern string _getUrlFromAppsFlyer();
#endif
void Start()
{
AppsFlyer.OnRequestResponse += AppsFlyerOnRequestResponse;
AppsFlyer.OnInAppResponse += (sender, args) =>
{
var af_args = args as AppsFlyerRequestEventArgs;
AppsFlyer.AFLog("OnInAppResponse", " status code " + af_args.statusCode);
};
// These fields are set from the editor so do not modify!
//******************************//
AppsFlyer.setIsDebug(isDebug);
#if UNITY_IOS && !UNITY_EDITOR
AppsFlyer.initSDK(iosdevKey, appID,this);
#elif UNITY_ANDROID && !UNITY_EDITOR
AppsFlyer.initSDK(devKey, appID,this);
#else
#endif
//******************************//
AppsFlyer.setAppInviteOneLinkID(liknTemplate);
AppsFlyer.startSDK();
}
void AppsFlyerOnRequestResponse(object sender, EventArgs e)
{
var args = e as AppsFlyerRequestEventArgs;
AppsFlyer.AFLog("AppsFlyerOnRequestResponse", " status code " + args.statusCode);
}
void Update()
{
}
public static string GetAFDeepLinkUrl()
{
#if UNITY_ANDROID
if(!string.IsNullOrEmpty(deepLinkUrl))
{
string depurl=deepLinkUrl;
deepLinkUrl="";
return depurl;
}
else
{
return "";
}
#elif UNITY_IPHONE
string iosDeepUrl=_getUrlFromAppsFlyer();
UnityEngine.Debug.Log("iosDeepUrl:-------:"+iosDeepUrl);
return iosDeepUrl;
#endif
return "";
}
// Mark AppsFlyer CallBacks
public void onConversionDataSuccess(string conversionData)
{
afCallBackData = conversionData;
AppsFlyer.AFLog("didReceiveConversionData", conversionData);
Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
// add deferred deeplink logic here
bool afdp = conversionDataDictionary.ContainsKey("link");
if (afdp == true)
{
object val = null;
bool afdpvalue = conversionDataDictionary.TryGetValue("link", out val);
if (afdpvalue == true)
{
deepLinkUrl = val as string;
}
}
UnityEngine.Debug.Log("延迟深度链接:-------:" + deepLinkUrl);
}
public void onConversionDataFail(string error)
{
AppsFlyer.AFLog("didReceiveConversionDataWithError", error);
}
public void onAppOpenAttribution(string attributionData)
{
afAttributionData = attributionData;
AppsFlyer.AFLog("onAppOpenAttribution", attributionData);
Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);
// add direct deeplink logic here
bool afdp = attributionDataDictionary.ContainsKey("link");
if (afdp == true)
{
object val = null;
bool afdpvalue = attributionDataDictionary.TryGetValue("link", out val);
if (afdpvalue == true)
{
deepLinkUrl = val as string;
}
}
UnityEngine.Debug.Log("深度链接:-------:" + deepLinkUrl);
}
public void onAppOpenAttributionFailure(string error)
{
AppsFlyer.AFLog("onAppOpenAttributionFailure", error);
}
public static void TriggerLogEvent(string eventName, string[] keys, string[] values)
{
var afparameters = new Dictionary<string, string>();
for (int i = 0; i < keys.Length; i++)
{
afparameters[keys[i]] = values[i];
}
AppsFlyer.sendEvent(
eventName,
afparameters
);
}
public static string GetgetAppsFlyerId()
{
return AppsFlyer.getAppsFlyerId();
}
public static string GetAFCallBackData()
{
return afCallBackData;
}
public static string GetAFAttributionData()
{
return afAttributionData;
}
//生成DddpLink
public void generateAppsFlyerLink(string[] keys, string[] values, Action<string> linkHandle)
{
generateLinkHandle = linkHandle;
Dictionary<string, string> parameters = new Dictionary<string, string>();
for (int i = 0; i < keys.Length; i++)
{
parameters[keys[i]] = values[i];
}
AppsFlyer.generateUserInviteLink(parameters, this);
}
public void onInviteLinkGenerated(string link)
{
AppsFlyer.AFLog("onInviteLinkGenerated", link);
if(generateLinkHandle!=null)
{
generateLinkHandle(link);
}
}
public void onInviteLinkGeneratedFailure(string error)
{
AppsFlyer.AFLog("onInviteLinkGeneratedFailure", error);
}
public void onOpenStoreLinkGenerated(string link)
{
AppsFlyer.AFLog("onOpenStoreLinkGenerated", link);
}
}
4、业务层调用动态生成连接
//linkTemplate是AF后台创建的模板ID。
public void generateShareGameLink()
{
GameObject go = GameObject.Find("SdkObj");
AppsFlyerObjectScript Af = go.GetComponent<AppsFlyerObjectScript>();
string param1 = "playerIdA";
string param2 = "teamId";
string param3 = "groupId";
Dictionary<string, string> m = new();
m.Add("af_channel", "custom_channel"); //自定义渠道名
m.Add("af_dp", "mySchemeUrl://");//调起APP的scheme URL
m.Add("c", "inviteGame"); //活动名称
m.Add("deep_link_value", param1);//客户端APP内实现深度链接参数
m.Add("deep_link_sub1", param2);//客户端APP内实现深度链接参数,deep_link_sub1到deep_link_sub10共10个参数可用
m.Add("deep_link_sub2", param3);//客户端APP内实现深度链接参数,deep_link_sub1到deep_link_sub10共10个参数可用
m.Add("is_retargeting", "false");//如果将此链接用于吸引现有及流失用户再次互动,请启用再营销,传True。这里默认传false
m.Add("pid", "af_app_invites");//媒体渠道,默认,AF后台进行统计用
m.Add("af_og_title", "Hello DeepLink");//供聊天软件抓取网页用的 社交媒体预览图谱 标题
m.Add("af_og_description", "Welcome use DeepLink");//供聊天软件抓取网页用的 社交媒体预览图谱 描述
m.Add("af_og_image", "https://www.baidu.com/123.png");//供聊天软件抓取网页用的 社交媒体预览图谱 展示图片
Af.generateAppsFlyerLink(m, generateShareGameLinkHandle);
}
private void generateShareGameLinkHandle(string link)
{
//生成DeepLink的回调,这里需要自己实现逻辑
//一般是调起分享
}
5、应用场景举例
比如策划有这样一个需求:游戏里需要添加一个邀请好友的功能,玩家A点击了某个按钮,会跳转到第三方聊天软件,同时会生成一个连接,玩家可以将这个连接发送给自己的聊天平台的好友B,他的好友点击了连接下载或进入了游戏,那么玩家A获得了奖励,玩家B也获得了奖励。
那么玩家A点击邀请按钮生成DeepLink时,需要把自己在游戏里的ID带入,玩家B在进入游戏时可以获取到玩家A分享的DeepLink。客户端此时将DeepLink中携带的玩家A的游戏ID以及玩家B的游戏ID发送到服务器,即可发送奖励。
生成连接时deep_link_sub1到deep_link_sub10是可用的参数,他们会携带在Link里面,被邀请的玩家通过连接进入游戏,都可以轻松获取到这些参数,从而实现分享的玩家与被邀请玩家的关联。