update: 重构 自打点属性上报逻辑, CodeReview

Signed-off-by: huyufei <yufei.hu@castbox.fm>
胡宇飞 2024-08-07 03:28:07 +08:00
parent ca036ba584
commit d37c1c4216
19 changed files with 1017 additions and 244 deletions

View File

@ -18,7 +18,7 @@ namespace Guru
public const string K_IAP_PURCHASE = "iap_purchase"; // 固定点位事件
public const string K_SUB_PURCHASE = "sub_purchase"; // 固定点位事件
private static Action<string> _onInitComplete;
private static Action<string, string, string> _onInitComplete;
private static Action<string> _onGetGoogleAdidHandler;
private static string _googleAdId = "";
@ -60,7 +60,7 @@ namespace Guru
/// <param name="onDeeplinkCallback"></param>
/// <param name="onGetGoogleAdIdCallback"></param>
public static void StartService(string appToken, string fbAppId = "", string firebaseId = "", string deviceId = "",
Action<string> onInitComplete = null, Action<string> onDeeplinkCallback = null, Action<string> onGetGoogleAdIdCallback = null)
Action<string, string, string> onInitComplete = null, Action<string> onDeeplinkCallback = null, Action<string> onGetGoogleAdIdCallback = null)
{
if (string.IsNullOrEmpty(appToken))
{
@ -79,6 +79,7 @@ namespace Guru
config.setDelayStart(DelayTime);
config.setPreinstallTrackingEnabled(true); // Adjust Preinstall
config.setSessionSuccessDelegate(OnSessionSuccessCallback); // SessionSuccess
config.setSessionFailureDelegate(OnSessionFailureCallback); // SessionFailed
if(onDeeplinkCallback != null)
config.setDeferredDeeplinkDelegate(onDeeplinkCallback);
@ -91,7 +92,6 @@ namespace Guru
config.setLogDelegate(log => LogI(LOG_TAG, log));
config.setEventSuccessDelegate(OnEventSuccessCallback);
config.setEventFailureDelegate(OnEventFailureCallback);
config.setSessionFailureDelegate(OnSessionFailureCallback);
config.setAttributionChangedDelegate(OnAttributionChangedCallback);
#endif
// 检查场景实例
@ -182,7 +182,7 @@ namespace Guru
var adid = sessionSuccessData.Adid;
_adjustId = adid;
_isReady = true;
_onInitComplete?.Invoke(adid);
_onInitComplete?.Invoke(adid, Adjust.getIdfv(), Adjust.getIdfa());
}
@ -305,7 +305,7 @@ namespace Guru
private static void OnSessionFailureCallback(AdjustSessionFailure sessionFailureData)
{
LogI(LOG_TAG,"Session tracking failed!");
LogE(LOG_TAG,"Session tracking failed!");
if (sessionFailureData.Message != null)
{

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8009d3bf70bb4438599a32f6ea601f9d
guid: b4c3c75418e9c43c0a14510620fadda4
PluginImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -1,8 +1,9 @@
// ==============================================
// U3DConsent.mm
// UnityFramework
// U3DAnalytics 1.12.0
// Native Framework Version 0.3.6
// update date: 2024-08-06 -- by HuYufei
//
// Created by EricHu on 2022/11/17.
// Created by HuYufei on 2022/11/17.
// Copyright © 2022 guru. All rights reserved.
// ==============================================
@ -26,7 +27,7 @@ static GuruAnalytics *_analytics;
@implementation U3DAnalytics
// Const value define
NSString * const Version = @"1.9.0";
NSString * const Version = @"1.12.0";
static const double kUploadPeriodInSecond = 60.0;
static const int kBatchLimit = 15;
@ -89,6 +90,7 @@ NSString * const TchError = @"tch_error";
[GuruAnalytics registerInternalEventObserverWithReportCallback:^(NSInteger code, NSString * info){
[U3DAnalytics onEventCallback:code andInfo:info];
}];
}
}
@ -241,7 +243,6 @@ NSString * const TchError = @"tch_error";
//---------------------------
@end
//============================ UNITY PUBLIC API ============================
@ -249,7 +250,7 @@ NSString * const TchError = @"tch_error";
extern "C" {
// 请求GDPR
void unityInitAnalytics(const char *appId, const char *deviceInfo, bool isDebug)
void unityInitAnalytics(const char *appId, const char *deviceInfo, bool isDebug, const char *baseUrl, const char *uploadIpAddress)
{
// NSLog(@"--- [iOS] init Analytics libs");
[GuruAnalytics initializeLibWithUploadPeriodInSecond:kUploadPeriodInSecond
@ -297,6 +298,11 @@ extern "C" {
[GuruAnalytics setDeviceId:[U3DAnalytics charToString:did]];
}
// 设置 EndHostUrl
void unitySetEndPointWithHost(const char *host){
[GuruAnalytics setEventsUploadEndPointWithHost:[U3DAnalytics charToString:host]];
}
// 设置用户属性
void unitySetUserProperty(const char *key, const char *value){
[GuruAnalytics setUserProperty:[U3DAnalytics charToString:value]

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 621002eb5acb547ec95af0d804cfb17f
guid: 504c48c6ad50247199d9301760f9c1a5
PluginImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -29,7 +29,6 @@ GuruAnalyticsLib 的 Unity 插件库
- Pod 库改为 本地文件引用 (配合外部发行项目)
### 1.11.0
- Android 端对齐 `1.0.3`
> Hash: 1978686dbcba38b7b0421d8b6b2bef111356366b

View File

@ -224,7 +224,7 @@ namespace Guru
}
public void SetAndroidID(string androidId)
public void SetAndroidId(string androidId)
{
if (!_isReady) return;
if (string.IsNullOrEmpty(androidId)) return;

View File

@ -98,30 +98,29 @@ namespace Guru
{
_isDebug = isDebug;
string bundleId = Application.identifier;
CallSDKInit(appId, deviceInfo, bundleId, baseUrl, uploadIpAddress , true, false, _isDebug); // 调用接口
CallSDKInit(appId, deviceInfo, bundleId, _isDebug, baseUrl, uploadIpAddress , true, false); // 调用接口
onInitComplete?.Invoke();
}
/********* Android API **********
public static void init(String appId,
public static void init(String appId,
String deviceInfo,
String bundleId,
boolean debug,
boolean useWorker,
boolean enabledCronet,
String baseUrl,
List<String> uploadIpAddress)
String uploadIpAddressStr,
boolean useWorker,
boolean enabledCronet)
*/
private void CallSDKInit(string appId,
string deviceInfo,
string bundleId,
bool isDebug = false,
string baseUrl = "",
string[] uploadIpAddress = null,
bool useWorker = true,
bool useCronet = false,
bool isDebug = false)
bool useCronet = false)
{
CallStatic("init", appId, deviceInfo, bundleId, isDebug, useWorker, useCronet, baseUrl, string.Join(",", uploadIpAddress ?? Array.Empty<string>())); // 调用接口
}

View File

@ -1,3 +1,5 @@
using System.Collections.Generic;
namespace Guru
{
public enum ELevelResult
@ -12,7 +14,7 @@ namespace Guru
//打点常量定义
public static partial class Analytics
{
public const string TAG = "Analytics";
public const string TAG = "[GA]";
// 美元符号
public const string USD = "USD";
// 广告平台
@ -113,20 +115,41 @@ namespace Guru
public const string PropertyLastPlayedLevel = "last_played_level";
public const string PropertyGrade = "grade"; //当游戏玩家角色升级时触发
public const string PropertyIsIAPUser = "is_iap_user"; //付费成功后设置属性参数为true如果没有发生付费可以不用设置该属性
public const string PropertyNetwork = "network"; // network属性
public const string PropertyAdjustId = "adjust_id"; // network属性
public const string PropertyIAPCoin = "iap_coin"; //付费所得的总金币数(iap获取累计值)\
public const string PropertyNonIAPCoin = "noniap_coin"; //非付费iap获取累计值
public const string PropertyCoin = "coin"; //当前金币数
public const string PropertyExp = "exp"; // 经验值
public const string PropertyHp = "hp"; // 生命值/体力
public const string PropertyAndroidID = "android_id"; // Android 平台 AndroidID
public const string PropertyAndroidId = "android_id"; // Android 平台 AndroidID
public const string PropertyIDFV = "idfv"; // iOS 平台 IDFV
public const string PropertyIDFA = "idfa"; // iOS 平台 IDFA
public const string PropertyPicture = "picture"; // 玩家在主线的mapid
public const string PropertyNoAds = "no_ads"; // 玩家是否去广告
public const string PropertyATTStatus = "att_status"; // ATT 状态
public const string PropertyAttStatus = "att_status"; // ATT 状态
public const string PropertyNotiPerm = "noti_perm"; // ATT 状态
public const string PropertyGDPR = "gdpr"; // GDPR状态
public const string PropertySignUpMethod = "sign_up_method"; // 用户登录方式
public const string PropertyFirebaseId = "firebase_id"; // FirebaseID
public const string PropertyGoogleAdId = "ad_id"; // FirebaseID
public static HashSet<string> PredefinedMidWareProperties = new HashSet<string>()
{
PropertyFirstOpenTime,
PropertyDeviceID,
PropertyUserID,
PropertyIsIAPUser,
PropertyNetwork,
PropertyAdjustId,
PropertyAndroidId,
PropertyIDFV,
PropertyIDFA,
PropertyAttStatus,
PropertyNotiPerm,
PropertyFirebaseId,
PropertyGoogleAdId,
};
// 经济相关
public const string ParameterBalance = "balance"; // 用于余额

View File

@ -1,24 +1,16 @@
namespace Guru
{
using System;
using Firebase.Analytics;
using Firebase.Crashlytics;
using Firebase.Extensions;
using UnityEngine;
/// <summary>
/// 自打点逻辑
/// </summary>
public partial class Analytics
{
private static bool _hasSetFirebaseId; //已取得FirebaseId
private static bool _hasSetAdId; // 已取得AdId
private static bool _hasSetIDFA; // 已取得IDFA
private static bool _hasSetAdjustId; // 已取得AdjustId
private static bool _hasSetDeviceId; // 已取得DeviceId
private static bool _hasSetUid; // 已取得UID
private static bool _hasSetIDFV; // 已经取得 IDFV
private static bool _hasSetAndroidId; // 已取得AndroidId
private static DateTime _lastReportRateDate; //上次上报信息的日期
private static double _reportSuccessInterval; // 上报频率
#if UNITY_IOS
@ -37,12 +29,7 @@ namespace Guru
{
string appId = IPMConfig.IPM_X_APP_ID;
string deviceInfo = new DeviceInfoData().ToString();
_hasSetFirebaseId = false;
_hasSetAdId = false;
_hasSetAdjustId = false;
_hasSetDeviceId = false;
_hasSetUid = false;
_lastReportRateDate = DateTime.Now;
_reportSuccessInterval = 120; // 2分钟上报一次
@ -53,7 +40,7 @@ namespace Guru
OnGuruAnalyticsInitComplete();
Debug.Log($"{TAG} [guru_analytic]--- Guru EXP: GroupId: {GuruAnalytics.Instance.ExperimentGroupId}");
SetUserProperty(GuruAnalyticsConfigManager.KEY_GURU_ANALYTICS_EXP, GuruAnalytics.Instance.ExperimentGroupId);
ApplyAllUserProperties();
ApplyAllMidWareProperties();
}, IsDebug, firebaseId); // Android 初始化
}
@ -62,193 +49,6 @@ namespace Guru
LogCrashlytics(ex);
}
}
#region 各ID上报信息
/// <summary>
/// 设置用户ID
/// </summary>
public static void SetUid(string uid)
{
if (_hasSetUid) return;
if (string.IsNullOrEmpty(uid)) return;
if (!IsFirebaseReady) return;
SetFirebaseUserId(uid);
if (!GuruAnalytics.IsReady) return;
GuruAnalytics.Instance.SetUid(uid);
Debug.Log($"---[ANA] UID: {uid}");
_hasSetUid = true;
}
/// <summary>
/// 设置设备ID
/// </summary>
private static void SetDeviceId(string deviceId)
{
if (_hasSetDeviceId) return;
if (string.IsNullOrEmpty(deviceId)) return;
if (!GuruAnalytics.IsReady) return;
GuruAnalytics.Instance.SetDeviceId(deviceId);
_hasSetDeviceId = true;
}
/// <summary>
/// 设置 AdjustId
/// </summary>
private static void SetAdjustId(string adjustId)
{
if (_hasSetAdjustId) return;
if (string.IsNullOrEmpty(adjustId)) return;
if (!GuruAnalytics.IsReady) return;
GuruAnalytics.Instance.SetAdjustId(adjustId);
_hasSetAdjustId = true;
}
/// <summary>
/// 设置 AdId
/// </summary>
private static void SetAdId(string adId)
{
if (_hasSetAdId) return;
if (string.IsNullOrEmpty(adId)) return;
if (!GuruAnalytics.IsReady) return;
GuruAnalytics.Instance.SetAdId(adId);
_hasSetAdId = true;
}
/// <summary>
/// 设置FirebaseId
/// </summary>
private static void SetFirebaseId(string firebaseId)
{
if (_hasSetFirebaseId) return;
if (string.IsNullOrEmpty(firebaseId)) return;
if (!GuruAnalytics.IsReady) return;
GuruAnalytics.Instance.SetFirebaseId(firebaseId);
_hasSetFirebaseId = true;
}
/// <summary>
/// 获取FirebaseID
/// </summary>
private static void FetchFirebaseId()
{
if (!IsFirebaseReady) return;
FirebaseAnalytics.GetAnalyticsInstanceIdAsync()
.ContinueWithOnMainThread(task =>
{
if (task != null && task.IsCompleted)
{
var fid = task.Result;
if (!string.IsNullOrEmpty(fid)
&& string.IsNullOrEmpty(IPMConfig.FIREBASE_ID))
{
IPMConfig.FIREBASE_ID = fid;
}
}
});
}
#if UNITY_IOS
/// <summary>
/// 更新ATT状态 (Only IOS 有效)
/// </summary>
private static void ApplyATTStatus()
{
string status = ATTManager.GetStatus();
GuruAnalytics.Instance.SetUserProperty(ParameterATTStatus, status);
}
private static void SetIDFV(string idfv)
{
if (_hasSetIDFV) return;
if (string.IsNullOrEmpty(idfv)) return;
if (!GuruAnalytics.IsReady) return;
GuruAnalytics.Instance.SetIDFV(idfv);
_hasSetIDFV = true;
}
private static void SetIDFA(string idfa)
{
if (_hasSetIDFA) return;
if (string.IsNullOrEmpty(idfa)) return;
if (!GuruAnalytics.IsReady) return;
GuruAnalytics.Instance.SetIDFA(idfa);
_hasSetIDFA = true;
}
#endif
#if UNITY_ANDROID
/// <summary>
/// 更新 Android ID 的参数
/// </summary>
private static void SetAndroidId(string androidId)
{
if (_hasSetAndroidId) return;
if (string.IsNullOrEmpty(androidId)) return;
if (!GuruAnalytics.IsReady) return;
GuruAnalytics.Instance.SetAndroidID(androidId);
_hasSetAndroidId = true;
}
#endif
/// <summary>
/// 上报中台打点的用户属性
/// </summary>
private static void ApplyAllUserProperties()
{
Debug.Log($"{TAG} --- UpdateAllValues");
SetUid(IPMConfig.IPM_UID);
SetDeviceId(IPMConfig.IPM_DEVICE_ID);
SetAdjustId(IPMConfig.ADJUST_ID);
if (string.IsNullOrEmpty(IPMConfig.FIREBASE_ID))
{
FetchFirebaseId();
}
else
{
SetFirebaseId(IPMConfig.FIREBASE_ID);
}
SetAdId(IPMConfig.ADJUST_ADID);
#if UNITY_ANDROID
SetAndroidId(DeviceIDHelper.AndroidID);
#endif
#if UNITY_IOS
ApplyATTStatus();
SetIDFV(IPMConfig.ADJUST_IDFV);
SetIDFA(IPMConfig.ADJUST_IDFA);
#endif
ReportEventSuccessRate();
}
/// <summary>
/// 上报事件成功率
/// </summary>
private static void ReportEventSuccessRate()
{
var interval = (DateTime.Now - _lastReportRateDate).TotalSeconds;
if (interval > _reportSuccessInterval)
{
GuruAnalytics.Instance.ReportEventSuccessRate();
_lastReportRateDate = DateTime.Now;
}
}
#endregion
#region 设置太极02 值

View File

@ -1,11 +1,21 @@
namespace Guru
{
using System;
using UnityEngine;
using Firebase.Analytics;
using System.Collections.Generic;
/// <summary>
/// 上报用户属性逻辑
/// Firebase 中台属性上报: https://docs.google.com/spreadsheets/d/1N47rXgjatRHFvzWWx0Hqv5C1D9NHHGbggi6pQ65c-zQ/edit?gid=1858695240#gid=1858695240
/// Guru自打点 中台属性上报https://docs.google.com/spreadsheets/d/1N47rXgjatRHFvzWWx0Hqv5C1D9NHHGbggi6pQ65c-zQ/edit?gid=1736574940#gid=1736574940
/// </summary>
public static partial class Analytics
{
#region Old Properties
/// <summary>
/// B_Level 属性
/// </summary>
@ -38,5 +48,543 @@ namespace Guru
return stamp;
}
}
#endregion
#region Update all neccessary properties
//---------------- 设置所有必要的属性 ---------------------
/// <summary>
/// 应用所有的中台属性
/// </summary>
private static void ApplyAllMidWareProperties()
{
MidWarePropertiesManager.Instance.ApplyAllProperties();
}
/// <summary>
/// 设置用户ID
/// </summary>
public static void SetUid(string uid)
{
MidWarePropertiesManager.Instance.ReportUid(uid);
}
/// <summary>
/// 设置设备ID
/// (Firebase, Guru)
/// </summary>
private static void SetDeviceId(string deviceId)
{
MidWarePropertiesManager.Instance.ReportDeviceId(deviceId);
}
/// <summary>
/// 设置首次启动时间
/// </summary>
/// <param name="firstOpenTime"></param>
private static void SetFirstOpenTime(string firstOpenTime)
{
MidWarePropertiesManager.Instance.ReportFirstOpenTime(firstOpenTime);
}
/// <summary>
/// 设置 IsIapUser
/// (Firebase, Guru)
/// </summary>
public static void SetIsIapUser(bool isIapUser)
{
MidWarePropertiesManager.Instance.ReportIsIapUser(isIapUser);
}
/// <summary>
/// 设置 Network
/// (Firebase, Guru)
/// </summary>
public static void SetNetworkStatus(string networkStatus)
{
MidWarePropertiesManager.Instance.ReportNetworkStatus(networkStatus);
}
/// <summary>
/// 设置 AdjustId
/// (Firebase)
/// </summary>
public static void SetAdjustId(string adjustId)
{
MidWarePropertiesManager.Instance.ReportAdjustId(adjustId);
}
/// <summary>
/// 设置 AndroidId
/// (Firebase)
/// </summary>
public static void SetAndroidId(string androidId)
{
MidWarePropertiesManager.Instance.ReportAndroidId(androidId);
}
/// <summary>
/// 设置 AttStatus
/// (Firebase)
/// </summary>
public static void SetAttStatus(string attStatus)
{
MidWarePropertiesManager.Instance.ReportAttStatus(attStatus);
}
/// <summary>
/// 设置 AttStatus
/// (Firebase)
/// </summary>
public static void SetNotiPerm(string notiPrem)
{
MidWarePropertiesManager.Instance.ReportNotiPerm(notiPrem);
}
/// <summary>
/// 设置 AdId
/// </summary>
public static void SetGoogleAdId(string adId)
{
MidWarePropertiesManager.Instance.ReportGoogleAdId(adId);
}
public static void SetIDFV(string idfv)
{
MidWarePropertiesManager.Instance.ReportIDFV(idfv);
}
public static void SetIDFA(string idfa)
{
MidWarePropertiesManager.Instance.ReportIDFA(idfa);
}
#endregion
#region 中台属性管理
/// <summary>
/// 中台必要用户属性对象
/// </summary>
private abstract class AbstractMidWareProperty
{
public readonly string key;
protected readonly string value;
private readonly ReportPropertyTarget reportTarget;
private bool HasValue => !string.IsNullOrEmpty(value);
protected AbstractMidWareProperty(string key, string value,
ReportPropertyTarget reportTarget = ReportPropertyTarget.Both)
{
this.key = key;
this.value = value;
this.reportTarget = reportTarget;
}
public void Report()
{
if (!HasValue) return;
BeforeReportProperty();
ReportPropertyByTarget();
}
protected abstract void BeforeReportProperty();
private void ReportPropertyByTarget()
{
if (!HasValue) return;
switch (reportTarget)
{
case ReportPropertyTarget.Firebase:
// Firebase
_firebaseEventDriver.AddProperty(key, value);
break;
case ReportPropertyTarget.Guru:
// Guru
_guruEventDriver.AddProperty(key, value);
break;
case ReportPropertyTarget.Both:
// 双平台上报
_firebaseEventDriver.AddProperty(key, value);
_guruEventDriver.AddProperty(key, value);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
/// <summary>
/// UID
/// </summary>
private class MidWarePropertyUid : AbstractMidWareProperty
{
public MidWarePropertyUid(string value)
: base(PropertyUserID, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
_firebaseEventDriver.SetUid(value);
_guruEventDriver.SetUid(value);
}
}
/// <summary>
/// DeviceId
/// </summary>
private class MidWarePropertyDeviceId : AbstractMidWareProperty
{
public MidWarePropertyDeviceId(string value)
: base(PropertyDeviceID, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
_guruEventDriver.SetDeviceId(value);
}
}
/// <summary>
/// FirstOpenTime
/// </summary>
private class MidWarePropertyFirstOpenTime : AbstractMidWareProperty
{
public MidWarePropertyFirstOpenTime(string value)
: base(PropertyFirstOpenTime, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
}
}
/// <summary>
/// IsIapUser
/// </summary>
private class MidWarePropertyIsIapUser : AbstractMidWareProperty
{
public MidWarePropertyIsIapUser(bool value)
: base(PropertyIsIAPUser, value?"true":"false", ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty() { }
}
/// <summary>
/// Network
/// </summary>
private class MidWarePropertyNetwork : AbstractMidWareProperty
{
public MidWarePropertyNetwork(string value)
: base(PropertyNetwork, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty() { }
}
/// <summary>
/// AdjustId
/// </summary>
private class MidWarePropertyAdjustId : AbstractMidWareProperty
{
public MidWarePropertyAdjustId(string value)
: base(PropertyAdjustId, value, ReportPropertyTarget.Firebase)
{
}
protected override void BeforeReportProperty()
{
_guruEventDriver.SetAdjustId(value);
}
}
/// <summary>
/// AttStatus
/// </summary>
private class MidWarePropertyAttStatus : AbstractMidWareProperty
{
public MidWarePropertyAttStatus(string value)
: base(PropertyAttStatus, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
}
}
/// <summary>
/// AttStatus
/// </summary>
private class MidWarePropertyNotiPerm : AbstractMidWareProperty
{
public MidWarePropertyNotiPerm(string value)
: base(PropertyNotiPerm, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
}
}
/// <summary>
/// AndroidId
/// </summary>
private class MidWarePropertyAndroidId : AbstractMidWareProperty
{
public MidWarePropertyAndroidId(string value)
: base(PropertyAndroidId, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
_guruEventDriver.SetAndroidId(value);
}
}
/// <summary>
/// FirebaseId
/// </summary>
private class MidWarePropertyGoogleAdId : AbstractMidWareProperty
{
public MidWarePropertyGoogleAdId(string value)
: base(PropertyGoogleAdId, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
_guruEventDriver.SetGoogleAdId(value);
}
}
/// <summary>
/// IDFV
/// </summary>
private class MidWarePropertyIDFV : AbstractMidWareProperty
{
public MidWarePropertyIDFV(string value)
: base(PropertyIDFV, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
_guruEventDriver.SetIDFV(value);
}
}
/// <summary>
/// IDFV
/// </summary>
private class MidWarePropertyIDFA : AbstractMidWareProperty
{
public MidWarePropertyIDFA(string value)
: base(PropertyIDFA, value, ReportPropertyTarget.Both)
{
}
protected override void BeforeReportProperty()
{
_guruEventDriver.SetIDFA(value);
}
}
/// <summary>
/// 必要属性上报配置
/// </summary>
internal enum ReportPropertyTarget
{
Firebase = 1,
Guru = 2,
Both = 3,
}
/// <summary>
/// 全部属性集合
/// </summary>
internal class MidWarePropertiesManager
{
private static MidWarePropertiesManager _instance;
public static MidWarePropertiesManager Instance
{
get
{
if (_instance == null) _instance = new MidWarePropertiesManager();
return _instance;
}
}
private readonly Dictionary<string, AbstractMidWareProperty> _propertyMap = new Dictionary<string, AbstractMidWareProperty>(10);
/*
======= ========
user_id (F,G)
device_id (F,G)
first_open_time (F,G)
is_iap_user (F,G)
network (F,G)
adjust_id (F)
att_status (F)
noti_perm (F)
======= ========
======= ========
firebase_id
idfv
idfa
======= ========
*/
//-------------------- 设置所有的属性 -----------------------
public void ReportUid(string uid)
{
var prop = new MidWarePropertyUid(uid);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportDeviceId(string deviceId)
{
var prop = new MidWarePropertyDeviceId(deviceId);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportFirstOpenTime(string firstOpenTime)
{
var prop = new MidWarePropertyFirstOpenTime(firstOpenTime);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportIsIapUser(bool isIapUser)
{
var prop = new MidWarePropertyIsIapUser(isIapUser);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportNetworkStatus(string networkStatus)
{
var prop = new MidWarePropertyNetwork(networkStatus);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportAdjustId(string adjustId)
{
var prop = new MidWarePropertyAdjustId(adjustId);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportAttStatus(string attStatus)
{
var prop = new MidWarePropertyAttStatus(attStatus);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportNotiPerm(string notiPerm)
{
var prop = new MidWarePropertyNotiPerm(notiPerm);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportAndroidId(string androidId)
{
var prop = new MidWarePropertyAndroidId(androidId);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportGoogleAdId(string googleAdId)
{
var prop = new MidWarePropertyGoogleAdId(googleAdId);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportIDFV(string idfv)
{
var prop = new MidWarePropertyIDFV(idfv);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
public void ReportIDFA(string idfa)
{
var prop = new MidWarePropertyIDFA(idfa);
_propertyMap.TryAdd(prop.key, prop);
prop.Report();
}
/// <summary>
/// 应用所有中台打点的用户属性
/// </summary>
public void ApplyAllProperties()
{
// 应用所有用户属性
Debug.Log($"{TAG} --- UpdateAllValues ---");
foreach (var prop in _propertyMap.Values)
{
prop.Report();
}
ReportEventSuccessRate();
}
/// <summary>
/// 上报事件成功率
/// </summary>
private static void ReportEventSuccessRate()
{
var interval = (DateTime.Now - _lastReportRateDate).TotalSeconds;
if (interval > _reportSuccessInterval)
{
GuruAnalytics.Instance.ReportEventSuccessRate();
_lastReportRateDate = DateTime.Now;
}
}
}
#endregion
}
}

View File

@ -47,6 +47,7 @@ namespace Guru
private static bool IsDebug => PlatformUtil.IsDebug();
private static bool IsFirebaseReady => FirebaseUtil.IsFirebaseInitialized;
private static bool IsGuruAnalyticsReady => GuruAnalytics.IsReady;
private static AdjustEventDriver _adjustEventDriver;
private static FBEventDriver _fbEventDriver;
@ -68,6 +69,9 @@ namespace Guru
_fbEventDriver = new FBEventDriver();
_firebaseEventDriver = new FirebaseEventDriver();
_guruEventDriver = new GuruEventDriver();
SetDeviceId(IPMConfig.IPM_DEVICE_ID);
SetFirstOpenTime(IPMConfig.FIRST_OPEN_TIME);
}
/// <summary>
@ -100,9 +104,19 @@ namespace Guru
_adjustEventDriver.TriggerFlush();
}
public static void OnGuruAnalyticsInitComplete()
private static void OnGuruAnalyticsInitComplete()
{
_guruEventDriver.TriggerFlush();
ShouldFlushGuruEvents();
}
public static void ShouldFlushGuruEvents()
{
if (!string.IsNullOrEmpty(IPMConfig.IPM_UID) && !_guruEventDriver.IsReady)
{
_guruEventDriver.TriggerFlush();
}
}
@ -166,7 +180,7 @@ namespace Guru
_guruEventDriver.AddProperty(key, value);
_firebaseEventDriver.AddProperty(key, value);
// 更新所有必要的用户属性
ApplyAllUserProperties();
ApplyAllMidWareProperties();
Debug.Log($"{TAG} --- SetUserProperty -> propertyName:{key}, propertyValue:{value}");
}
catch (Exception ex)

View File

@ -1,3 +1,7 @@
using System;
using System.Collections;
using UnityEngine;
namespace Guru
{
using System.Collections.Concurrent;
@ -13,15 +17,47 @@ namespace Guru
void AddProperty(string key, string value);
}
internal class MidWarePropertyDelayedAction
{
internal readonly string key;
private readonly string value;
private readonly Action<string> reportAction;
internal MidWarePropertyDelayedAction(string key, string value, Action<string> reportAction)
{
this.key = key;
this.value = value;
this.reportAction = reportAction;
}
internal void Execute()
{
reportAction.Invoke(value);
}
public override bool Equals(object obj)
{
if (obj is not MidWarePropertyDelayedAction action) return false;
return key == action.key;
}
public override int GetHashCode()
{
return key.GetHashCode();
}
}
public abstract class AbstractEventDriver: IEventDriver, IPropertyCollector
{
private readonly GuruEventBuffer<TrackingEvent> _eventBuffer = new GuruEventBuffer<TrackingEvent>();
private readonly ConcurrentDictionary<string, string> _userPropertyMap = new ConcurrentDictionary<string, string>();
private readonly HashSet<MidWarePropertyDelayedAction> _predefinedPropertyDelayedActions = new HashSet<MidWarePropertyDelayedAction>();
// Firebase 是否可用
private bool _isDriverReady;
public bool IsReady => _isDriverReady;
public void TriggerFlush()
{
@ -79,17 +115,26 @@ namespace Guru
{
while(_eventBuffer.Pop(out var trackingEvent))
{
Debug.Log($"[ANU] --- GuruAnalytics: FlushAll Events: {trackingEvent.eventName}");
FlushTrackingEvent(trackingEvent);
}
foreach (var key in _userPropertyMap.Keys)
{
Debug.Log($"[ANU] --- GuruAnalytics: FlushAll Properties: {key}:{ _userPropertyMap[key]}");
SetUserProperty(key, _userPropertyMap[key]);
}
_userPropertyMap.Clear();
foreach (var propertyAction in _predefinedPropertyDelayedActions)
{
Debug.Log($"[ANU] --- GuruAnalytics: FlushAll predefined Properties: {propertyAction.key}:{ propertyAction}");
propertyAction.Execute();
}
_predefinedPropertyDelayedActions.Clear();
}
/// <summary>
/// 发送事件
/// </summary>
@ -98,7 +143,151 @@ namespace Guru
protected abstract void SetUserProperty(string key, string value);
/// <summary>
/// 设置用户ID
/// </summary>
public void SetUid(string uid)
{
if (_isDriverReady)
{
ReportUid(uid);
}
else
{
_predefinedPropertyDelayedActions.Add(new MidWarePropertyDelayedAction(Analytics.PropertyUserID, uid, ReportUid));
}
}
public void SetDeviceId(string deviceId)
{
if (_isDriverReady)
{
ReportDeviceId(deviceId);
}
else
{
_predefinedPropertyDelayedActions.Add(new MidWarePropertyDelayedAction(Analytics.PropertyDeviceID, deviceId, ReportDeviceId));
}
}
/// <summary>
/// 设置 AdjustId
/// (Firebase)
/// </summary>
public void SetAdjustId(string adjustId)
{
if (_isDriverReady)
{
ReportAdjustId(adjustId);
}
else
{
_predefinedPropertyDelayedActions.Add(new MidWarePropertyDelayedAction(Analytics.PropertyAdjustId, adjustId, ReportAdjustId));
}
}
/// <summary>
/// 设置 AdId
/// </summary>
public void SetGoogleAdId(string googleAdId)
{
if (_isDriverReady)
{
ReportGoogleAdId(googleAdId);
}
else
{
_predefinedPropertyDelayedActions.Add(new MidWarePropertyDelayedAction(Analytics.PropertyGoogleAdId, googleAdId, ReportGoogleAdId));
}
}
/// <summary>
/// 设置 AndroidId
/// </summary>
/// <param name="androidId"></param>
public void SetAndroidId(string androidId)
{
if (_isDriverReady)
{
ReportAndroidId(androidId);
}
else
{
_predefinedPropertyDelayedActions.Add(new MidWarePropertyDelayedAction(Analytics.PropertyAndroidId, androidId, ReportAndroidId));
}
}
/// <summary>
/// 设置 IDFV
/// </summary>
public void SetIDFV(string idfv)
{
if (_isDriverReady)
{
ReportIDFV(idfv);
}
else
{
_predefinedPropertyDelayedActions.Add(new MidWarePropertyDelayedAction(Analytics.PropertyIDFV, idfv, ReportIDFV));
}
}
/// <summary>
/// 设置 IDFA
/// </summary>
public void SetIDFA(string idfa)
{
if (_isDriverReady)
{
ReportIDFA(idfa);
}
else
{
_predefinedPropertyDelayedActions.Add(new MidWarePropertyDelayedAction(Analytics.PropertyIDFA, idfa, ReportIDFA));
}
}
/// <summary>
/// 设置用户ID
/// (Firebase, Guru)
/// </summary>
protected abstract void ReportUid(string uid);
/// <summary>
/// 设置设备ID
/// (Firebase, Guru)
/// </summary>
protected abstract void ReportDeviceId(string deviceId);
/// <summary>
/// 设置 AdjustId
/// (Firebase)
/// </summary>
protected abstract void ReportAdjustId(string adjustId);
/// <summary>
/// 设置 googleAdId
/// </summary>
protected abstract void ReportGoogleAdId(string googleAdId);
/// <summary>
/// 设置 AndroidId
/// </summary>
protected abstract void ReportAndroidId(string androidId);
/// <summary>
/// 设置 IDFV
/// </summary>
protected abstract void ReportIDFV(string idfv);
/// <summary>
/// 设置 IDFA
/// </summary>
protected abstract void ReportIDFA(string idfa);
}

View File

@ -31,5 +31,53 @@ namespace Guru
{
}
//---------------- 单独实现所有的独立属性打点 ------------------
/// <summary>
/// 设置用户ID
/// </summary>
protected override void ReportUid(string uid)
{
}
protected override void ReportDeviceId(string deviceId)
{
}
/// <summary>
/// 设置 AdjustId
/// (Firebase)
/// </summary>
protected override void ReportAdjustId(string adjustId)
{
}
/// <summary>
/// 设置 AdId
/// </summary>
protected override void ReportGoogleAdId(string adId)
{
}
protected override void ReportAndroidId(string androidId)
{
}
/// <summary>
/// 设置 IDFV
/// </summary>
protected override void ReportIDFV(string idfv)
{
}
/// <summary>
/// 设置 IDFA
/// </summary>
protected override void ReportIDFA(string idfa)
{
}
}
}

View File

@ -1,8 +1,9 @@
using System;
using UnityEngine;
namespace Guru
{
using UnityEngine;
public class FBEventDriver: AbstractEventDriver
{
/// <summary>
@ -22,5 +23,57 @@ namespace Guru
{
}
//---------------- 单独实现所有的独立属性打点 ------------------
/// <summary>
/// 设置用户ID
/// </summary>
protected override void ReportUid(string uid)
{
}
protected override void ReportDeviceId(string deviceId)
{
}
/// <summary>
/// 设置 AdjustId
/// (Firebase)
/// </summary>
protected override void ReportAdjustId(string adjustId)
{
}
/// <summary>
/// 设置 AdId
/// </summary>
protected override void ReportGoogleAdId(string adId)
{
}
protected override void ReportAndroidId(string adId)
{
}
/// <summary>
/// 设置 IDFV
/// </summary>
protected override void ReportIDFV(string idfv)
{
}
/// <summary>
/// 设置 IDFA
/// </summary>
protected override void ReportIDFA(string idfa)
{
}
}
}

View File

@ -59,5 +59,33 @@ namespace Guru
FirebaseAnalytics.SetUserProperty(key, value);
}
protected override void ReportUid(string uid)
{
FirebaseAnalytics.SetUserId(uid);
}
protected override void ReportDeviceId(string deviceId)
{
}
protected override void ReportAdjustId(string adjustId)
{
}
protected override void ReportGoogleAdId(string adId)
{
}
protected override void ReportAndroidId(string adId)
{
}
protected override void ReportIDFV(string idfv)
{
}
protected override void ReportIDFA(string idfa)
{
}
}
}

View File

@ -1,5 +1,7 @@
namespace Guru
{
public class GuruEventDriver: AbstractEventDriver
{
protected override void FlushTrackingEvent(TrackingEvent trackingEvent)
@ -16,6 +18,62 @@ namespace Guru
// ReSharper disable once Unity.PerformanceCriticalCodeInvocation
GuruAnalytics.Instance.SetUserProperty(key, value);
}
//---------------- 单独实现所有的独立属性打点 ------------------
/// <summary>
/// 设置用户ID
/// </summary>
protected override void ReportUid(string uid)
{
GuruAnalytics.Instance.SetUid(uid);
}
/// <summary>
/// 设置设备ID
/// (Firebase, Guru)
/// </summary>
protected override void ReportDeviceId(string deviceId)
{
GuruAnalytics.Instance.SetDeviceId(deviceId);
}
/// <summary>
/// 设置 AdjustId
/// (Firebase)
/// </summary>
protected override void ReportAdjustId(string adjustId)
{
GuruAnalytics.Instance.SetAdjustId(adjustId);
}
protected override void ReportAndroidId(string androidId)
{
GuruAnalytics.Instance.SetAndroidId(androidId);
}
/// <summary>
/// 设置 AdId
/// </summary>
protected override void ReportGoogleAdId(string adId)
{
GuruAnalytics.Instance.SetAdId(adId);
}
/// <summary>
/// 设置 IDFV
/// </summary>
protected override void ReportIDFV(string idfv)
{
GuruAnalytics.Instance.SetIDFV(idfv);
}
/// <summary>
/// 设置 IDFA
/// </summary>
protected override void ReportIDFA(string idfa)
{
GuruAnalytics.Instance.SetIDFA(idfa);
}
}
}

View File

@ -261,12 +261,20 @@ namespace Guru
get => PlayerPrefs.GetString(nameof(ADJUST_GOOGLE_ADID), "");
set => PlayerPrefs.SetString(nameof(ADJUST_GOOGLE_ADID), value);
}
public static string FirstOpenTime
public static string FIRST_OPEN_TIME
{
get => PlayerPrefs.GetString(nameof(FirstOpenTime), "");
set => PlayerPrefs.SetString(nameof(FirstOpenTime), value);
get
{
var value = PlayerPrefs.GetString(nameof(FIRST_OPEN_TIME), "");
if (string.IsNullOrEmpty(value))
{
value = TimeUtil.GetCurrentTimeStamp().ToString();
FIRST_OPEN_TIME = value;
}
return value;
}
set => PlayerPrefs.SetString(nameof(FIRST_OPEN_TIME), value);
}
}
}