update: 重构用户属性打点代码, CodeReview

main
胡宇飞 2024-08-09 02:40:36 +08:00
parent a063c4866d
commit c001fe09ac
8 changed files with 186 additions and 257 deletions

View File

@ -1,3 +1,4 @@
namespace Guru namespace Guru
{ {
using System.Collections.Generic; using System.Collections.Generic;
@ -51,11 +52,24 @@ namespace Guru
/// Debug模式下开启打点默认关闭 /// Debug模式下开启打点默认关闭
/// </summary> /// </summary>
public bool EnableDebugLogEvent = false; public bool EnableDebugLogEvent = false;
private Dictionary<string, object> _defaultRemoteData = new Dictionary<string, object>();
/// <summary> /// <summary>
/// 云控参数的默认配置 /// 云控参数的默认配置
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public Dictionary<string, object> DefaultRemoteData = new Dictionary<string, object>(); public Dictionary<string, object> DefaultRemoteData
{
set
{
if (value != null)
{
_defaultRemoteData = value;
}
}
get => _defaultRemoteData;
}
/// <summary> /// <summary>
/// 启用 AdjustDeeplink /// 启用 AdjustDeeplink
/// </summary> /// </summary>

View File

@ -7,7 +7,7 @@ namespace Guru
/// 获取BLevel /// 获取BLevel
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
protected override int GetBLevel() => Model.SuccessLevelId; // BLevel protected override int GetBLevel() => Model.BLevel; // BLevel
private GuruSDKModel Model => GuruSDKModel.Instance; private GuruSDKModel Model => GuruSDKModel.Instance;

View File

@ -12,27 +12,17 @@ namespace Guru
get => _value; get => _value;
set set
{ {
if (_value.Equals(value)) return;
_value = value; _value = value;
OnValueChanged?.Invoke(value); OnValueChanged?.Invoke(value);
} }
} }
public event Action<T> OnValueChanged; public event Action<T> OnValueChanged;
public BindableProperty(T initValue)
public BindableProperty()
{
}
public BindableProperty(Action<T> onChanged)
{
OnValueChanged = onChanged;
}
public BindableProperty(T initValue, Action<T> onChanged)
{ {
_value = initValue; _value = initValue;
OnValueChanged = onChanged;
} }
} }
} }

View File

@ -1,18 +1,55 @@
namespace Guru namespace Guru
{ {
using System; using System;
using UnityEngine; using UnityEngine;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json;
using System.Linq; using System.Linq;
[Serializable]
class PurchasedProduct
{
public string productName;
public string productId;
public string receipt;
public bool appleProductIsRestored;
}
[Serializable]
class GuruSDKSerializedModel
{
//-------------- data ---------------
[JsonProperty(PropertyName = "uid")]
public string uid = "";
[JsonProperty(PropertyName = "b_level")]
public int bLevel = 0;
[JsonProperty(PropertyName = "b_play")]
public int bPlay = 0;
[JsonProperty(PropertyName = "no_ads")]
public bool noAds = false;
[JsonProperty(PropertyName = "purchased")]
public List<PurchasedProduct> purchased = new List<PurchasedProduct>(10);
//-------------- data ---------------
}
[Serializable] [Serializable]
internal class GuruSDKModel internal class GuruSDKModel
{ {
private const float SaveInterval = 3; private const float SaveInterval = 3;
private const string SaveKey = "com.guru.sdk.model.save"; private const string SaveKey = "com.guru.sdk.model.save";
private float _lastSavedTime = 0;
private bool _noAds = false;
private readonly BindableProperty<int> _bLevel;
private readonly BindableProperty<int> _bPlay;
private string _uid;
private List<PurchasedProduct> _purchased;
private static GuruSDKModel _instance; private static GuruSDKModel _instance;
@ -20,120 +57,88 @@ namespace Guru
{ {
get get
{ {
if (null == _instance) _instance = Load(); if (null == _instance) _instance = new GuruSDKModel();
return _instance; return _instance;
} }
} }
//-------------- data --------------- public GuruSDKModel()
public string uid = "";
public int b_level = 0;
public int b_play = 0;
public int buy_count = 0;
public bool no_ads = false;
public string first_open_time = "";
public List<PurchasedProduct> purchased;
public Dictionary<string, int> event_priorities;
//-------------- data ---------------
private float _lastSavedTime = 0;
public int SuccessLevelId
{ {
get GuruSDKSerializedModel model = LoadModel();
{
if(_successLevel == null) InitProperties(); _uid = model.uid;
return _successLevel.Value; _noAds = model.noAds;
} _bLevel = new BindableProperty<int>(model.bLevel);
_bPlay = new BindableProperty<int>(model.bPlay);
_purchased = model.purchased;
}
public int BLevel
{
get => _bLevel.Value;
set set
{ {
if(_successLevel == null) InitProperties(); if (value < _bLevel.Value)
_successLevel.Value = value; {
// b_level 必须比上一次的值大
Debug.LogWarning($"[SDK] :: Set b_level [{value}] should not be less than original value [{_bLevel.Value}]");
return;
}
_bLevel.Value = value;
Save();
} }
} }
public int TotalPlayedCount public int BPlay
{ {
get get => _bPlay.Value;
{
if(_totalPlayed == null) InitProperties();
return _totalPlayed.Value;
}
set set
{ {
if(_totalPlayed == null) InitProperties(); _bPlay.Value = value;
_totalPlayed.Value = value; Save();
}
}
public int PurchasedCount
{
get
{
if(_purchasedCount == null) InitProperties();
return _purchasedCount.Value;
}
set
{
if(_purchasedCount == null) InitProperties();
_purchasedCount.Value = value;
} }
} }
public string UserId public string UserId
{ {
get get => _uid;
{
if(_uid == null) InitProperties();
return _uid.Value;
}
set set
{ {
if(_uid == null) InitProperties(); _uid = value;
_uid.Value = value;
}
}
public string FirstOpenTime
{
get => first_open_time;
set
{
first_open_time = value;
Save(); Save();
} }
} }
public bool IsIapUser => PurchasedCount > 0;
public bool IsIapUser => _purchased.Count > 0;
public bool IsNoAds public bool IsNoAds
{ {
get => no_ads; get => _noAds;
set set
{ {
no_ads = value; _noAds = value;
Save(); Save();
} }
} }
public void SetOnBLevelChanged(Action<int> action)
{
_bLevel.OnValueChanged += action;
}
private BindableProperty<int> _successLevel; public void SetOnBPlayChanged(Action<int> action)
private BindableProperty<int> _totalPlayed; {
private BindableProperty<int> _purchasedCount; _bPlay.OnValueChanged += action;
private BindableProperty<string> _uid; }
private BindableProperty<bool> _isIapUser;
public BindableProperty<int> PropBLevel => _successLevel;
public BindableProperty<int> PropBPlay => _totalPlayed;
public BindableProperty<int> PropBuyCount => _purchasedCount;
public BindableProperty<string> Uid => _uid;
#region 初始化 #region 初始化
public static GuruSDKModel Load()
private GuruSDKSerializedModel LoadModel()
{ {
GuruSDKModel model = null; GuruSDKSerializedModel model = null;
if (PlayerPrefs.HasKey(SaveKey)) if (PlayerPrefs.HasKey(SaveKey))
{ {
var json = PlayerPrefs.GetString(SaveKey, ""); var json = PlayerPrefs.GetString(SaveKey, "");
@ -141,39 +146,35 @@ namespace Guru
{ {
try try
{ {
model = JsonUtility.FromJson<GuruSDKModel>(json); model = JsonUtility.FromJson<GuruSDKSerializedModel>(json);
} }
catch (Exception e) catch (Exception e)
{ {
UnityEngine.Debug.LogError(e); Debug.LogError(e);
} }
} }
} }
if(model == null) model = new GuruSDKModel(); if(model == null) model = new GuruSDKSerializedModel();
model.InitProperties();
return model; return model;
} }
public static string GetFirstOpenTime() => TimeUtil.GetCurrentTimeStamp().ToString();
/// <summary> /// <summary>
/// 保存至数据 /// 保存至数据
/// </summary> /// </summary>
private void SaveToPlayerPrefs() private void SaveToPlayerPrefs()
{ {
var json = JsonUtility.ToJson(this); var model = new GuruSDKSerializedModel()
{
uid = _uid,
bLevel = _bLevel.Value,
bPlay = _bPlay.Value,
noAds = _noAds,
purchased = _purchased,
};
var json = JsonUtility.ToJson(model);
PlayerPrefs.SetString(SaveKey, json); PlayerPrefs.SetString(SaveKey, json);
} }
public void InitProperties()
{
if (_successLevel == null) _successLevel = new BindableProperty<int>(b_level, OnLevelChanged);
if (_totalPlayed == null) _totalPlayed = new BindableProperty<int>(b_play, OnPlayedChanged);
if (_purchasedCount == null) _purchasedCount = new BindableProperty<int>(buy_count, OnPurchasedNumChanged);
if (_uid == null) _uid = new BindableProperty<string>(uid, OnUidChanged);
if (purchased == null) purchased = new List<PurchasedProduct>(20);
if (event_priorities == null) event_priorities = new Dictionary<string, int>(10);
}
/// <summary> /// <summary>
/// 保存数据 /// 保存数据
@ -188,68 +189,16 @@ namespace Guru
SaveToPlayerPrefs(); SaveToPlayerPrefs();
} }
} }
internal void SetBLevelValue(int value) => OnLevelChanged(value);
internal void SetBPlayValue(int value) => OnPlayedChanged(value);
#endregion
#region 数据绑定变化
private void OnLevelChanged(int value)
{
b_level = value;
Save();
}
private void OnPlayedChanged(int value)
{
b_play = value;
Save();
}
private void OnPurchasedNumChanged(int value)
{
buy_count = value;
Save();
}
private void OnUidChanged(string value)
{
uid = value;
Save();
}
#endregion #endregion
#region 启动配置
/// <summary>
/// 从 Streaming 加载 AppServices 配置
/// </summary>
/// <returns></returns>
public string LoadDefaltServicesConfigJson()
{
try
{
var txt = Resources.Load<TextAsset>(GuruSDK.ServicesConfigKey);
return txt?.text ?? "";
}
catch (Exception e)
{
Log.Exception(e);
}
return "";
}
#endregion
#region 订单记录 #region 订单记录
public bool HasPurchasedProduct(string receipt) public bool HasPurchasedProduct(string receipt)
{ {
if(purchased == null || purchased.Count == 0) return false; if(_purchased.Count == 0) return false;
return purchased.Exists(p => p.receipt == receipt); return _purchased.Exists(p => p.receipt == receipt);
} }
/// <summary> /// <summary>
@ -258,12 +207,12 @@ namespace Guru
/// <param name="receipt"></param> /// <param name="receipt"></param>
/// <param name="productName"></param> /// <param name="productName"></param>
/// <param name="productId"></param> /// <param name="productId"></param>
/// <param name="appleProductIsRestored"></param>
public void AddReceipt(string receipt, string productName, string productId, bool appleProductIsRestored = false) public void AddReceipt(string receipt, string productName, string productId, bool appleProductIsRestored = false)
{ {
if (purchased == null) purchased = new List<PurchasedProduct>(20);
if (!HasPurchasedProduct(receipt)) if (!HasPurchasedProduct(receipt))
{ {
purchased.Add(new PurchasedProduct() _purchased.Add(new PurchasedProduct()
{ {
receipt = receipt, receipt = receipt,
productName = productName, productName = productName,
@ -276,22 +225,16 @@ namespace Guru
public string[] GetReceipts(string productName) public string[] GetReceipts(string productName)
{ {
int count = purchased?.Count ?? 0; var receipts = new List<string>();
if (count == 0) count = 20; receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productName == productName select purchasedProduct.receipt);
if (purchased == null) purchased = new List<PurchasedProduct>(count);
var receipts = new List<string>(count);
receipts.AddRange(from purchasedProduct in purchased where purchasedProduct.productName == productName select purchasedProduct.receipt);
return receipts.ToArray(); return receipts.ToArray();
} }
public string[] GetReceiptsById(string productId) public string[] GetReceiptsById(string productId)
{ {
int count = purchased?.Count ?? 0; var receipts = new List<string>();
if (count == 0) count = 20; receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productId == productId select purchasedProduct.receipt);
if (purchased == null) purchased = new List<PurchasedProduct>(count);
var receipts = new List<string>(count);
receipts.AddRange(from purchasedProduct in purchased where purchasedProduct.productId == productId select purchasedProduct.receipt);
return receipts.ToArray(); return receipts.ToArray();
} }
@ -304,28 +247,13 @@ namespace Guru
public void ClearData() public void ClearData()
{ {
uid = ""; PlayerPrefs.DeleteKey(SaveKey);
b_level = 0;
b_play = 0;
buy_count = 0;
no_ads = false;
first_open_time = "";
purchased?.Clear();
event_priorities?.Clear();
} }
#endregion #endregion
} }
[Serializable]
internal class PurchasedProduct
{
public string productName;
public string productId;
public string receipt;
public bool appleProductIsRestored;
}

View File

@ -55,22 +55,12 @@ namespace Guru
public static void SetUserBLevel(int bLevel) public static void SetUserBLevel(int bLevel)
{ {
if (!InitConfig.AutoRecordFinishedLevels) Model.BLevel = bLevel;
{
Model.SetBLevelValue(bLevel);
Analytics.BLevel = bLevel;
}
Analytics.SetBLevel(bLevel);
} }
public static void SetUserBPlay(int bPlay) public static void SetUserBPlay(int bPlay)
{ {
if (!InitConfig.AutoRecordFinishedLevels) Model.BPlay = bPlay;
{
Model.SetBPlayValue(bPlay);
Analytics.BPlay = bPlay;
}
Analytics.SetBPlay(bPlay);
} }
/// <summary> /// <summary>
@ -202,6 +192,9 @@ namespace Guru
$"{Tag} :: LogLevelEnd {levelId} :: Please call <GuruSDK.Start()> first, before you call <LogLevelEnd>."); $"{Tag} :: LogLevelEnd {levelId} :: Please call <GuruSDK.Start()> first, before you call <LogLevelEnd>.");
return; return;
} }
if (extra == null) extra = new Dictionary<string, object>();
// 优先打 level_end 事件 // 优先打 level_end 事件
Analytics.LogLevelEnd(levelId, result, levelName, levelType, itemId, duration, step, score, extra); Analytics.LogLevelEnd(levelId, result, levelName, levelType, itemId, duration, step, score, extra);
@ -212,15 +205,12 @@ namespace Guru
{ {
if (levelType.ToLower() == Consts.LevelTypeMain) if (levelType.ToLower() == Consts.LevelTypeMain)
{ {
if (levelId >= Model.SuccessLevelId) Model.SuccessLevelId = levelId; // 自动记录关卡完成次数 Model.BLevel = levelId; // 自动记录 [主线] 关卡完成次数
} }
Model.TotalPlayedCount++; // 自动记录关卡总次数 Model.BPlay++; // 自动记录关卡总次数
Analytics.LevelEndSuccess(Model.TotalPlayedCount); // 自动 level_end_success Analytics.LevelEndSuccess(Model.BPlay, extra); // 自动 level_end_success
} }
Analytics.BLevel = Model.SuccessLevelId; // 记录 BLevel
Analytics.BPlay = Model.TotalPlayedCount; // 记录 BPlay
} }
} }
@ -247,7 +237,7 @@ namespace Guru
/// /// <param name="extra">扩展参数</param> /// /// <param name="extra">扩展参数</param>
public static void LogLevelEndSuccess(int bPlay, Dictionary<string, object> extra = null) public static void LogLevelEndSuccess(int bPlay, Dictionary<string, object> extra = null)
{ {
if (InitConfig.AutoRecordFinishedLevels) return; if (extra == null) extra = new Dictionary<string, object>();
Analytics.LevelEndSuccess(bPlay, extra); Analytics.LevelEndSuccess(bPlay, extra);
} }
@ -1179,6 +1169,7 @@ namespace Guru
#region 优先级设置 #region 优先级设置
private static readonly Dictionary<string, int> _eventPriorities = new Dictionary<string, int>(10);
/// <summary> /// <summary>
/// 设置 /// 设置
@ -1187,15 +1178,13 @@ namespace Guru
/// <param name="eventNames"></param> /// <param name="eventNames"></param>
public static void SetEventPriority(EventPriority priority, string[] eventNames) public static void SetEventPriority(EventPriority priority, string[] eventNames)
{ {
if (Model.event_priorities == null) Model.event_priorities = new Dictionary<string, int>(10);
int i = 0; int i = 0;
while (i < eventNames.Length) while (i < eventNames.Length)
{ {
var evt = eventNames[i]; var evt = eventNames[i];
if (!string.IsNullOrEmpty(evt)) if (!string.IsNullOrEmpty(evt))
{ {
Model.event_priorities[evt] = (int)priority; _eventPriorities[evt] = (int)priority;
} }
i++; i++;
} }
@ -1208,15 +1197,14 @@ namespace Guru
public static EventPriority GetEventPriority(string eventName) public static EventPriority GetEventPriority(string eventName)
{ {
if (Model.event_priorities != null if (_eventPriorities.TryGetValue(eventName, out int p))
&& Model.event_priorities.TryGetValue(eventName, out int p))
{ {
return (EventPriority)p; return (EventPriority)p;
} }
return EventPriority.Default; return EventPriority.Default;
} }
internal static int GetEventPriorityInt(string eventName) public static int GetEventPriorityInt(string eventName)
{ {
return (int)GetEventPriority(eventName); return (int)GetEventPriority(eventName);
} }
@ -1224,7 +1212,7 @@ namespace Guru
/// <summary> /// <summary>
/// set all events as 'Emergence' event, which will be triggered immediately /// set all events as 'Emergence' event, which will be triggered immediately
/// </summary> /// </summary>
internal void SetSDKEventPriority() private void SetSDKEventPriority()
{ {
SetEventPriority(EventPriority.Emergence, new [] SetEventPriority(EventPriority.Emergence, new []
{ {

View File

@ -180,7 +180,6 @@ namespace Guru
/// <param name="success"></param> /// <param name="success"></param>
private static void OnBuyEnd(string productName, bool success) private static void OnBuyEnd(string productName, bool success)
{ {
if (success) Model.PurchasedCount++;
InvokeOnPurchaseCallback?.Invoke(productName, success); InvokeOnPurchaseCallback?.Invoke(productName, success);
Callbacks.IAP.InvokeOnPurchaseEnd(productName, success); Callbacks.IAP.InvokeOnPurchaseEnd(productName, success);
} }

View File

@ -83,8 +83,8 @@ namespace Guru
/// </summary> /// </summary>
public static int SuccessLevelCount public static int SuccessLevelCount
{ {
get => GuruSDKModel.Instance.SuccessLevelId; get => GuruSDKModel.Instance.BLevel;
set => GuruSDKModel.Instance.SuccessLevelId = value; set => GuruSDKModel.Instance.BLevel = value;
} }
/// <summary> /// <summary>
@ -92,8 +92,8 @@ namespace Guru
/// </summary> /// </summary>
public static int TotalPlayedCount public static int TotalPlayedCount
{ {
get => GuruSDKModel.Instance.TotalPlayedCount; get => GuruSDKModel.Instance.BPlay;
set => GuruSDKModel.Instance.TotalPlayedCount = value; set => GuruSDKModel.Instance.BPlay = value;
} }

View File

@ -1,10 +1,11 @@
using System.Linq;
namespace Guru namespace Guru
{ {
using UnityEngine; using UnityEngine;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using Debug = UnityEngine.Debug; using Debug = UnityEngine.Debug;
using Guru.Network; using Guru.Network;
@ -111,8 +112,8 @@ namespace Guru
/// <param name="onComplete"></param> /// <param name="onComplete"></param>
private void StartWithConfig(GuruSDKInitConfig config, Action<bool> onComplete) private void StartWithConfig(GuruSDKInitConfig config, Action<bool> onComplete)
{ {
Model.PropBLevel.OnValueChanged += OnBLevelChanged; Model.SetOnBLevelChanged(OnBLevelChanged);
Model.PropBPlay.OnValueChanged += OnBPlayChanged; Model.SetOnBPlayChanged(OnBPlayChanged);
IsInitialSuccess = false; IsInitialSuccess = false;
_initConfig = config; _initConfig = config;
@ -137,8 +138,8 @@ namespace Guru
Analytics.Init(); Analytics.Init();
// 从 Model 中注入打点属性初始值 // 从 Model 中注入打点属性初始值
Analytics.SetIsIapUser(Model.IsIapUser); Analytics.SetIsIapUser(Model.IsIapUser);
Analytics.SetBLevel(Model.SuccessLevelId); Analytics.SetBLevel(Model.BLevel);
Analytics.SetBPlay(Model.TotalPlayedCount); Analytics.SetBPlay(Model.BPlay);
//---- Start All tools ---- //---- Start All tools ----
LogI($"#2 --- InitFirebase ---"); LogI($"#2 --- InitFirebase ---");
@ -154,17 +155,16 @@ namespace Guru
/// <summary> /// <summary>
/// 注入云控参数基础数据 /// 注入云控参数基础数据
/// </summary> /// </summary>
/// <param name="dict"></param>
/// <returns></returns> /// <returns></returns>
private Dictionary<string, object> BuildDefaultRemoteData(Dictionary<string, object> dict) private string LoadDefaultGuruServiceJson()
{ {
if (dict == null) dict = new Dictionary<string, object>(3); // 加载本地 Services 配置值
var txtAsset = Resources.Load<TextAsset>(ServicesConfigKey);
// 注入默认的 Services 配置值 if (txtAsset != null)
string json = Model.LoadDefaltServicesConfigJson(); {
if (!string.IsNullOrEmpty(json)) dict[ServicesConfigKey] = json; return txtAsset.text;
}
return dict; return "";
} }
/// <summary> /// <summary>
@ -306,7 +306,7 @@ namespace Guru
Try(() => Try(() =>
{ {
LogI($"#4.4 --- Start Keywords ---"); LogI($"#4.4 --- Start Keywords ---");
KeywordsManager.Install(Model.IsIapUser, Model.SuccessLevelId); // 启动Keyword管理器 KeywordsManager.Install(Model.IsIapUser, Model.BLevel); // 启动Keyword管理器
}, ex => }, ex =>
{ {
Debug.LogError($"--- ERROR on Keywords: {ex.Message}"); Debug.LogError($"--- ERROR on Keywords: {ex.Message}");
@ -342,7 +342,7 @@ namespace Guru
LogSDKInitTime((DateTime.Now.ToUniversalTime() - _initTime).TotalSeconds); LogSDKInitTime((DateTime.Now.ToUniversalTime() - _initTime).TotalSeconds);
#if UNITY_ANDROID #if UNITY_ANDROID
LogI($"#5.1 --- Android StartAndroidDebugCmds---"); LogI($"#5.1 --- Android StartAndroidDebug Cmd lines---");
// Android 命令行调试 // Android 命令行调试
StartAndroidDebugCmds(); StartAndroidDebugCmds();
#endif #endif
@ -441,29 +441,29 @@ namespace Guru
#endregion #endregion
#region Logging #region Logging
internal static void LogI(object message) private static void LogI(object message)
{ {
Debug.Log($"{Tag} {message}"); Debug.Log($"{Tag} {message}");
} }
internal static void LogW(object message) private static void LogW(object message)
{ {
Debug.LogWarning($"{Tag} {message}"); Debug.LogWarning($"{Tag} {message}");
} }
internal static void LogE(object message) private static void LogE(object message)
{ {
Debug.LogError($"{Tag} {message}"); Debug.LogError($"{Tag} {message}");
} }
internal static void LogException(string message) private static void LogException(string message)
{ {
LogException( new Exception($"{Tag} {message}")); LogException( new Exception($"{Tag} {message}"));
} }
internal static void LogException(Exception e) private static void LogException(Exception e)
{ {
Debug.LogException(e); Debug.LogException(e);
} }
@ -688,8 +688,6 @@ namespace Guru
{ {
Callbacks.SDK.InvokeDeeplinkCallback(deeplink); // 尝试调用回调 Callbacks.SDK.InvokeDeeplinkCallback(deeplink); // 尝试调用回调
} }
#endregion #endregion
@ -779,7 +777,19 @@ namespace Guru
LogI($"#3.5 --- Call InitRemoteConfig ---"); LogI($"#3.5 --- Call InitRemoteConfig ---");
// 开始Remote Manager初始化 // 开始Remote Manager初始化
RemoteConfigManager.Init(BuildDefaultRemoteData(_initConfig.DefaultRemoteData));
var defaultGuruServiceJson = LoadDefaultGuruServiceJson();
var dict = _initConfig.DefaultRemoteData.ToDictionary(
entry => entry.Key,
entry => entry.Value);
if (!string.IsNullOrEmpty(defaultGuruServiceJson))
{
dict[ServicesConfigKey] = defaultGuruServiceJson;
}
RemoteConfigManager.Init(dict);
RemoteConfigManager.OnFetchCompleted += OnFetchRemoteCallback; RemoteConfigManager.OnFetchCompleted += OnFetchRemoteCallback;
LogI($"#4 --- Apply remote services config ---"); LogI($"#4 --- Apply remote services config ---");