Compare commits

...

15 Commits

Author SHA1 Message Date
胡宇飞 dc47cec8bd fix: 修复一个 Json 解析的错误问题
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-07-01 20:41:24 +08:00
胡宇飞 2075f676b9 fix: 删除 RemoteConfigBase 内OnChange 回调的JSON 属性
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-07-01 18:27:47 +08:00
胡宇飞 660303e45d update: 添加 Amazon 测试接口
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-07-01 18:21:41 +08:00
胡宇飞 2a895b370e Merge branch 'hotfix/1.0.13' into dev
Signed-off-by: huyufei <yufei.hu@castbox.fm>

# Conflicts:
#	Runtime/GuruCore/Runtime/Analytics/Analytics.TemplateDefine.cs
2024-07-01 14:25:18 +08:00
胡宇飞 c0c557b34e Merge branch 'hotfix/1.0.12.1' into hotfix/1.0.13
Signed-off-by: huyufei <yufei.hu@castbox.fm>

# Conflicts:
#	Runtime/GuruCore/Runtime/Analytics/Analytics.TemplateDefine.cs
2024-07-01 13:46:27 +08:00
胡宇飞 edcc533d33 fix: Adjust 打点测试支付也会上报
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-07-01 12:36:55 +08:00
胡宇飞 3d9d027e89 fix: 修复 Adjust 事件重复上报以及为调用接口导致 revenue 没有正确上报的 BUG
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-07-01 09:49:52 +08:00
胡宇飞 1256880b22 update: 更新 IOS 内的打包管线逻辑. UnityFramework 设置ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES ->NO
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-06-28 12:25:52 +08:00
胡宇飞 e77994d811 update: 更新 DeviceInfo 上报日志
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-06-27 21:13:57 +08:00
胡宇飞 85dc4a7ddc update: 新增打印 DeviceData 的日志
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-06-27 18:53:57 +08:00
胡宇飞 b7aacb61e4 fix: 修复 AdStatus 的显示 BUG
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-06-27 18:53:48 +08:00
胡宇飞 8cc083410d update: 新增打印 DeviceData 的日志
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-06-27 18:53:24 +08:00
胡宇飞 81f37625c1 fix: 修复 AdStatus 的显示 BUG
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-06-27 18:47:36 +08:00
胡宇飞 1a9481b094 update: Tch 001 和 Tch 02 打点, 添加 sandbox 参数
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-06-26 16:17:23 +08:00
胡宇飞 e8c17f4cf4 fix: 对齐 SDK 接口参数
Signed-off-by: huyufei <yufei.hu@castbox.fm>
2024-06-25 10:35:03 +08:00
15 changed files with 148 additions and 65 deletions

View File

@ -11,7 +11,7 @@ namespace Guru
/// </summary>
public class IOSPostBuildSwift
{
[PostProcessBuild(40)]
[PostProcessBuild(2000)]
public static void OnPostProcessBuild(BuildTarget target, string buildPath)
{
if (target != BuildTarget.iOS) return;
@ -43,7 +43,7 @@ namespace Guru
// 设置主项目的SWIFT构建支持
project.SetBuildProperty(mainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
project.SetBuildProperty(frameworkTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "NO");
project.WriteToFile(projectPath);
}

View File

@ -79,7 +79,7 @@ namespace Guru
/// <summary>
/// 初始化平台
/// </summary>
public void Initialize()
public void Initialize(bool isDebug = false)
{
#if UNITY_EDITOR
Debug.Log($"<color=orange>=== Amazon will not init on Editor ===</color>");
@ -93,11 +93,8 @@ namespace Guru
// 初始化Amazon
Amazon.Initialize (AmazonAppID);
Amazon.SetAdNetworkInfo(new AdNetworkInfo(DTBAdNetwork.MAX));
#if UNITY_EDITOR || DEBUG
Amazon.EnableTesting (true); // Make sure to take this off when going live.
#else
Amazon.EnableLogging (false);
#endif
Amazon.EnableTesting (isDebug); // Make sure to take this off when going live.
Amazon.EnableLogging (isDebug);
#if UNITY_IOS
Amazon.SetAPSPublisherExtendedIdFeatureEnabled(true);

View File

@ -50,7 +50,7 @@ namespace Guru
* before it can request an ad using OpenWrap SDK.
* The storeURL is the URL where users can download your app from the App Store/Google Play Store.
*/
public void Initialize()
public void Initialize(bool isDebug = false)
{
#if UNITY_EDITOR
Debug.Log($"<color=orange>=== PubMatic will not init on Editor ===</color>");

View File

@ -23,7 +23,7 @@ namespace Guru
protected override void InitService()
{
base.InitService();
InitChannels(); // 启动各广告渠道代理
InitChannels(_isDebug); // 启动各广告渠道代理
}
#endregion
@ -37,14 +37,14 @@ namespace Guru
/// <summary>
/// 各渠道初始化
/// </summary>
private void InitChannels()
private void InitChannels(bool isDebug)
{
_adChannels = new HashSet<IAdChannel>();
IAdChannel channel = null;
_asyncLoader = null;
_chanelMax = new AdChanelMax(); // 默认持有MAXChannel
_chanelMax.Initialize();
_chanelMax.Initialize(isDebug);
if(_initSpec != null) _chanelMax.SetBannerBackColor(_initSpec.bannerColorHex);
//------------ 以下为扩展的广告渠道 ------------------
@ -52,7 +52,7 @@ namespace Guru
// 开启渠道需要添加对应的宏
channel = new AdChanelAmazon();
channel.Initialize();
channel.Initialize(isDebug);
_adChannels.Add(channel); // Amazon
_asyncLoader = channel as IAsyncRequestChannel;
if (_asyncLoader != null)

View File

@ -49,6 +49,7 @@ namespace Guru
}
}
internal bool _isDebug = false;
/// <summary>
/// 启动广告服务
@ -61,20 +62,22 @@ namespace Guru
if (IsInitialized) return; // 已经初始化后, 无需再次初始化
_initSpec = initSpec;
if (_initSpec == null) _initSpec = AdsInitSpec.BuildDefault();
_isDebug = _initSpec.isDebug;
_isServiceStarted = true;
_onSdkInitReady = callback;
if(_model == null) _model = AdsModel.Create();
this.Log("AD SDK Start Init");
InitMaxAds(); // 初始化 MAX 广告
InitMaxCallbacks(); // 初始化 MAX 广告
InitService(); // 内部继承接口
}
/// <summary>
/// 初始化 MAX 广告组件
/// </summary>
private void InitMaxAds()
private void InitMaxCallbacks()
{
//-------------- 初始化回调 ------------------
MaxSdkCallbacks.OnSdkInitializedEvent += OnMaxSdkInitializedCallBack;
@ -103,8 +106,6 @@ namespace Guru
MaxSdkCallbacks.Rewarded.OnAdReceivedRewardEvent += OnRewardedAdReceivedRewardEvent;
//-------------- SDK 初始化 -------------------
if (_initSpec == null) _initSpec = AdsInitSpec.BuildDefault();
MaxSdk.SetVerboseLogging(_initSpec.isDebug);
MaxSdk.SetExtraParameter("enable_black_screen_fixes", "true"); // 修复黑屏
}

View File

@ -32,10 +32,11 @@ namespace Guru
/// <summary>
/// MAX 渠道初始化, 启动服务
/// </summary>
public void Initialize()
public void Initialize(bool isDebug = false)
{
MaxSdk.SetSdkKey(GuruSettings.Instance.ADSetting.SDK_KEY);
MaxSdk.SetUserId(IPMConfig.IPM_UID); // 上报用户ID
MaxSdk.SetVerboseLogging(isDebug); // 设置调试数据
MaxSdk.InitializeSdk();
}

View File

@ -8,7 +8,7 @@ namespace Guru
{
// Action<string> OnRequestOver { get; set; }
void Initialize();
void Initialize(bool isDebug = false);
string Name { get;}

View File

@ -224,17 +224,17 @@ namespace Guru
/// </summary>
/// <param name="status"></param>
/// <param name="channel"></param>
/// <param name="others"></param>
public static void AttResult(string status, string type = "custom", string others = "")
/// <param name="scene"></param>
public static void AttResult(string status, string type = "custom", string scene = "")
{
SetAttProperty(status);
Debug.Log($"{TAG} AttResult: {status} type:{type} others:{others}");
Debug.Log($"{TAG} AttResult: {status} type:{type} others:{scene}");
var dict = new Dictionary<string, dynamic>()
{
{ ParameterItemCategory, status },
{ "type", type }
};
if(!string.IsNullOrEmpty(others)) dict[ParameterItemName] = others;
if(!string.IsNullOrEmpty(scene)) dict[ParameterItemName] = scene;
LogEvent(EventATTResult, dict);
}

View File

@ -1,5 +1,4 @@
using System.Data.Odbc;
using JetBrains.Annotations;
namespace Guru
{
@ -296,9 +295,10 @@ namespace Guru
/// <param name="orderId"></param>
/// <param name="orderType"></param>
/// <param name="timestamp"></param>
public static void Tch001IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
/// <param name="isTest"></param>
public static void Tch001IAPRev(double value, string productId, string orderId, string orderType, string timestamp, bool isTest = false)
{
TchRevEvent(EventTchAdRev001Impression, IAPPlatform, value, orderType, productId, orderId, timestamp);
TchRevEvent(EventTchAdRev001Impression, IAPPlatform, value, orderType, productId, orderId, timestamp, isTest);
}
/// <summary>
@ -310,11 +310,12 @@ namespace Guru
/// <param name="orderId"></param>
/// <param name="orderType"></param>
/// <param name="timestamp"></param>
/// <param name="isSandbox"></param>
// public static void Tch02IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
public static void Tch02IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
public static void Tch02IAPRev(double value, string productId, string orderId, string orderType, string timestamp, bool isTest = false)
{
if (!EnableTch02Event) return;
TchRevEvent(EventTchAdRev02Impression, IAPPlatform, value, orderType, productId, orderId, timestamp);
TchRevEvent(EventTchAdRev02Impression, IAPPlatform, value, orderType, productId, orderId, timestamp, isTest);
}
/// <summary>
@ -363,8 +364,9 @@ namespace Guru
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="timestamp"></param>
/// <param name="isTest"></param>
private static void TchRevEvent(string evtName, string platform, double value,
string orderType = "", string productId = "", string orderId = "", string timestamp = "")
string orderType = "", string productId = "", string orderId = "", string timestamp = "", bool isTest = false)
{
var data = new Dictionary<string, dynamic>()
{
@ -373,11 +375,16 @@ namespace Guru
{ ParameterCurrency, USD },
};
string sandbox = isTest ? "true" : "false";
//--------- Extra data for IAP receipt ---------------
if(!string.IsNullOrEmpty(orderType)) data["order_type"] = orderType;
if(!string.IsNullOrEmpty(productId)) data["product_id"] = productId;
if(!string.IsNullOrEmpty(orderId)) data["order_id"] = orderId;
if(!string.IsNullOrEmpty(timestamp)) data["trans_ts"] = timestamp;
if(!string.IsNullOrEmpty(sandbox)) data["sandbox"] = sandbox;
//--------- Extra data for IAP receipt ---------------
LogEvent(evtName, data);
@ -626,22 +633,38 @@ namespace Guru
string scene = orderData.scene;
bool isFree = orderData.isFree;
string offerId = orderData.offerId;
string transactionId = "";
string productToken = "";
string receipt = "";
if (orderData is GoogleOrderData gdata)
{
productToken = gdata.token;
}
else if (orderData is AppleOrderData adata)
{
receipt = adata.receipt;
}
// TCH 001
Tch001IAPRev(usdPrice, productId, orderId, orderType, orderDate);
Tch001IAPRev(usdPrice, productId, orderId, orderType, orderDate, isTest);
// TCH 020
Tch02IAPRev(usdPrice, productId, orderId, orderType, orderDate);
Tch02IAPRev(usdPrice, productId, orderId, orderType, orderDate, isTest);
// Facebook Track IAP Purchase
FBPurchase(usdPrice, USD, "iap", IAPPlatform);
if (orderData.orderType == 1)
{
// sub_pruchase : Firebase + Guru + Adjust
SubPurchase(usdPrice, productId, orderId, orderDate, isTest);
SubPurchase(usdPrice, productId, orderId, orderDate, productToken, receipt);
}
else
{
// iap_purchase : Firebase + Guru + Adjust
IAPPurchase(usdPrice, productId, orderId, orderDate, isTest);
IAPPurchase(usdPrice, productId, orderId, orderDate, productToken, receipt);
}
// IAP Ret true : Firebase + Guru + Adjust
@ -660,20 +683,34 @@ namespace Guru
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="orderDate"></param>
public static void IAPPurchase(double value, string productId, string orderId, string orderDate, bool isSandbox = false)
/// <param name="purchaseToken"></param>
/// <param name="receipt"></param>
public static void IAPPurchase(double value, string productId, string orderId, string orderDate,
string purchaseToken = "", string receipt = "")
{
IAPPurchaseReport(EventIAPPurchase, value, productId, orderId, "IAP", orderDate, isSandbox);
IAPPurchaseReport(EventIAPPurchase, value, productId, orderId, "IAP", orderDate, purchaseToken, receipt);
}
public static void SubPurchase(double value, string productId, string orderId, string orderDate, bool isSandbox = false)
/// <summary>
/// SUB 订阅上报
/// </summary>
/// <param name="value"></param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="orderDate"></param>
/// <param name="purchaseToken"></param>
/// <param name="receipt"></param>
public static void SubPurchase(double value, string productId, string orderId, string orderDate,
string purchaseToken = "", string receipt = "")
{
IAPPurchaseReport(EventSubPurchase, value, productId, orderId, "SUB", orderDate, isSandbox);
IAPPurchaseReport(EventSubPurchase, value, productId, orderId, "SUB", orderDate, purchaseToken, receipt);
}
private static void IAPPurchaseReport(string eventName, double value, string productId, string orderId, string orderType, string orderDate, bool isSandbox = false)
private static void IAPPurchaseReport(string eventName, double value, string productId,
string orderId, string orderType, string orderDate, string purchaseToken = "", string receipt = "")
{
LogEvent(eventName, new Dictionary<string, dynamic>()
var dict = new Dictionary<string, dynamic>()
{
[ParameterPlatform] = IAPPlatform,
[ParameterValue] = value,
@ -681,13 +718,14 @@ namespace Guru
[ParameterProductId] = productId,
["order_id"] = orderId,
["order_type"] = orderType,
["trans_ts"] = orderDate,
["sandbox"] = isSandbox? "true": "false"
}, new EventSetting()
{
EnableFirebaseAnalytics = true,
EnableAdjustAnalytics = true,
});
["trans_ts"] = orderDate
};
// 上报Firebase + 自打点
LogEvent(eventName, dict, new EventSetting() { EnableFirebaseAnalytics = true });
// 上报 Adjust 支付事件
LogAdjustRevenueEvent(eventName, value, productId, orderId, purchaseToken, receipt, dict);
}
#endregion

View File

@ -250,6 +250,44 @@ namespace Guru
}
}
/// <summary>
/// 上报 Adjust 事件
/// </summary>
/// <param name="eventName"></param>
/// <param name="productId"></param>
/// <param name="receipt"></param>
/// <param name="data"></param>
/// <param name="usdPrice"></param>
/// <param name="transactionId"></param>
/// <param name="purchaseToken"></param>
/// <returns></returns>
internal static bool LogAdjustRevenueEvent(string eventName, double usdPrice,
string productId = "", string transactionId = "", string purchaseToken = "", string receipt = "",
Dictionary<string, object> data = null )
{
AdjustEvent adjustEvent = Analytics.CreateAdjustEvent(eventName);
if (adjustEvent != null)
{
adjustEvent.setRevenue(usdPrice, USD);
if (!string.IsNullOrEmpty(productId)) adjustEvent.setProductId(productId);
if (!string.IsNullOrEmpty(transactionId)) adjustEvent.setTransactionId(transactionId);
if (!string.IsNullOrEmpty(purchaseToken)) adjustEvent.setPurchaseToken(purchaseToken);
if (!string.IsNullOrEmpty(receipt)) adjustEvent.setReceipt(receipt);
if (data != null && data.Count > 0)
{
foreach (var kv in data)
{
adjustEvent.AddEventParameter(kv.Key, kv.Value.ToString());
}
}
Adjust.trackEvent(adjustEvent);
return true;
}
return false;
}
#endregion
#region 通用打点

View File

@ -52,7 +52,10 @@ namespace Guru
try
{
// return JsonMapper.ToObject<T>(jsonStr);
return JsonConvert.DeserializeObject<T>(jsonStr);
return JsonConvert.DeserializeObject<T>(jsonStr, new JsonSerializerSettings()
{
ObjectCreationHandling = ObjectCreationHandling.Replace,
});
}
catch (Exception e)
{

View File

@ -72,7 +72,7 @@ namespace Guru
$"{nameof(language)}: {language}, {nameof(locale)}: {locale}, {nameof(deviceToken)}: {deviceToken}, {nameof(deviceType)}: {deviceType}, " +
$"{nameof(pushType)}: {pushType}, {nameof(appIdentifier)}: {appIdentifier}, {nameof(appVersion)}: {appVersion}, {nameof(brand)}: {brand}, " +
$"{nameof(model)}: {model}, {nameof(timezone)}: {timezone}, {nameof(pushNotificationEnable)}: {pushNotificationEnable}, " +
$"{nameof(firebaseAppInstanceId)}: {firebaseAppInstanceId}, {nameof(idfa)}: {idfa}, {nameof(adid)}: {adid}, {nameof(gpsAdid)}: {gpsAdid}";
$"{nameof(firebaseAppInstanceId)}: {firebaseAppInstanceId}, {nameof(idfa)}: {idfa}, {nameof(adid)}: {adid}, {nameof(gpsAdid)}: {gpsAdid}, {nameof(userUuid)}: {userUuid}";
}
}

View File

@ -19,7 +19,7 @@ namespace Guru
{
DeviceData deviceData = new DeviceData();
deviceData.pushNotificationEnable = _isPushEnabled;
this.Log($"send deviceData:{deviceData}");
UnityEngine.Debug.Log($"[SDK] --- Send DeviceData:{deviceData}");
var request = new UnityWebRequest(RequestURL, "POST");
request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(JsonUtility.ToJson(deviceData)));
request.downloadHandler = new DownloadHandlerBuffer();
@ -31,10 +31,10 @@ namespace Guru
protected override void RequestSuccessCallBack(string response)
{
this.Log("@@@ Send OK!");
UnityEngine.Debug.Log("[SDK] --- Send DeviceData Success");
IPMConfig.IS_UPLOAD_DEVICE_SUCCESS = true;
}
/// <summary>
/// 设置是否打开推送
/// </summary>

View File

@ -99,22 +99,22 @@ namespace Guru
UpdateView(); // 刷新视图
}
// 字段缓冲
private StringBuilder _infoBuff;
private string CreateMonitorInfo()
{
string msg = "";
bool loaded = false;
StringBuilder sb = new StringBuilder();
if (!ADService.Instance.IsInitialized)
{
msg = ColoredText("AdService not initialized...", Consts.ColorRed);
return msg;
}
if (_infoBuff == null) _infoBuff = new StringBuilder();
_infoBuff.Clear();
if (_curBadsInfo == null)
{
msg = $"BADS: {ColoredText("not ready", Consts.ColorRed)}\n";
@ -137,7 +137,7 @@ namespace Guru
msg = $"BADS: {ColoredText("loading...", Consts.ColorYellow)}\n\tformat: {_curBadsInfo.format}\n";
break;
case AdStatusType.Paid:
msg = $"BADS: {ColoredText("display", Consts.ColorGreen)}\n\tnetwork: {_curIadsInfo.network}\n\trevenue: {_curBadsInfo.revenue}\n";
msg = $"BADS: {ColoredText("display", Consts.ColorGreen)}\n\tnetwork: {_curBadsInfo.network}\n\trevenue: {_curBadsInfo.revenue}\n";
break;
case AdStatusType.NotReady:
msg = $"BADS: {ColoredText("not ready", Consts.ColorGray)}\n\t{ColoredText("---", Consts.ColorGray)}\n";
@ -147,7 +147,7 @@ namespace Guru
break;
}
}
sb.Append(msg);
_infoBuff.Append(msg);
if (_curIadsInfo == null)
@ -159,7 +159,7 @@ namespace Guru
switch (_curIadsInfo.status)
{
case AdStatusType.Loaded:
msg = $"IADS: {ColoredText("loaded", Consts.ColorGreen)}\n\tnetwork: {_curIadsInfo.network}\n\twaterfall: {_curBadsInfo.waterfall}\n";
msg = $"IADS: {ColoredText("loaded", Consts.ColorGreen)}\n\tnetwork: {_curIadsInfo.network}\n\twaterfall: {_curIadsInfo.waterfall}\n";
break;
case AdStatusType.LoadFailed:
msg = $"IADS: {ColoredText("loading failed", Consts.ColorRed)}\n\tmessage: {_curIadsInfo.info}\n";
@ -181,7 +181,7 @@ namespace Guru
break;
}
}
sb.Append(msg);
_infoBuff.Append(msg);
if (_curRadsInfo == null)
@ -215,10 +215,11 @@ namespace Guru
break;
}
}
sb.Append(msg);
_infoBuff.Append(msg);
return sb.ToString();
return _infoBuff.ToString();
}

View File

@ -1,6 +1,8 @@
namespace Guru
{
using System;
using UnityEngine;
using Newtonsoft.Json;
public abstract class RemoteConfigBase<T>: IRemoteConfig<T> where T : IRemoteConfig<T>
{
@ -8,6 +10,8 @@ namespace Guru
/// 配置是否可用
/// </summary>
public bool enable { get; set; } = true;
[JsonIgnore]
public Action<T> OnValueChanged { get; set; }
/// <summary>
/// 转为Json