update: 修复自打点属性重复上报问题, 调整了 iOS 桥接 NULL 判定, 尽量对齐 Flutter 项目还原 Android 项目的上报事件逻辑

Signed-off-by: huyufei <yufei.hu@castbox.fm>
胡宇飞 2024-08-08 20:06:20 +08:00
parent b186489a54
commit cc5d36fea6
10 changed files with 261 additions and 159 deletions

View File

@ -451,7 +451,7 @@ namespace Guru.Editor
string strMon = nowDate.Month.ToString("00");
string strDay = nowDate.Day.ToString("00");
string strQuarter = ((nowDate.Hour * 60 + nowDate.Minute) / 15).ToString("00");
// 2024-08-01 08:00:00 to version string: 240801
// 2024-08-01 08:00:00 to version string: 24080130
string strBuildNumber = $"{strYear}{strMon}{strDay}{strQuarter}";
return strBuildNumber;
}
@ -539,7 +539,7 @@ namespace Guru.Editor
string strMon = nowDate.Month.ToString("00");
string strDay = nowDate.Day.ToString("00");
string strQuarter = ((nowDate.Hour * 60 + nowDate.Minute) / 15).ToString("00");
// 2024-08-01 08:00:00 to version string: 240801
// 2024-08-01 00:00:00 to version string: 24080100
string strBuildNumber = $"{strYear}{strMon}{strDay}{strQuarter}";
Debug.Log($"Get BuildVersion Code: {strBuildNumber}");
}

View File

@ -1,7 +1,7 @@
// ==============================================
// U3DAnalytics 1.12.0
// Native Framework Version 0.3.6
// update date: 2024-08-06 -- by HuYufei
// update date: 2024-08-08 -- by HuYufei
//
// Created by HuYufei on 2022/11/17.
// Copyright © 2022 guru. All rights reserved.
@ -68,11 +68,15 @@ NSString * const TchError = @"tch_error";
// 获取最终字符串
+(char*) finalChar: (NSString *) string
{
const char *tmpChar = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (string == NULL)
if(string == NULL){
return NULL;
}
const char *tmpChar = [string cStringUsingEncoding:NSASCIIStringEncoding];
if(tmpChar == NULL){
return NULL;
}
char* res = (char*)malloc(strlen(tmpChar) + 1);
strcpy(res, tmpChar);
@ -86,15 +90,16 @@ NSString * const TchError = @"tch_error";
// 设置是否启用日志错误上报
+(void) setEnableErrorLog: (bool) value{
if(enableErrorLog == false && value){
enableErrorLog = value;
if(value){
// 注册事件
enableErrorLog = true;
[GuruAnalytics registerInternalEventObserverWithReportCallback:^(NSInteger code, NSString * info){
[U3DAnalytics onEventCallback:code andInfo:info];
}];
return;
}
// 否则只赋值
enableErrorLog = value;
}
@ -108,29 +113,33 @@ NSString * const TchError = @"tch_error";
}];
}
// 设置 BaseUrl
+(void) setBaseUrl: (const char *) baseUrl{
if (baseUrl != nullptr && strlen(baseUrl) == 0) {
return; // baseUrl 为空
}
[GuruAnalytics setEventsUploadEndPointWithHost:[U3DAnalytics charToString:baseUrl]];
}
// 事件上报回调
+(void) onEventCallback: (NSInteger)code andInfo:(NSString *) info{
[U3DAnalytics sendMessage: [U3DAnalytics buildLogEventString: code andMessage:info]];
+(void) onEventCallback: (NSInteger)code andInfo:(NSString *) info {
if(enableErrorLog == false) {
return; // 开关关闭不报
}
if(info == nil){
return; // 空字符串不报
}
NSString *msg = [U3DAnalytics buildLogEventString: code andMessage:info];
if(msg != NULL){
return;
}
[U3DAnalytics sendMessageToUnity: msg];
}
// 构建数据
+(NSString *) buildLogEventString: (NSInteger)status andMessage: (NSString *)msg{
NSString *jsonString = [NSString stringWithFormat: @"{\"action\":\"logger_error\",\"data\":{\"code\":%d,\"msg\":\"%@\"}}", (int)status, msg];
NSLog(@"[ANI][Error]: %@", jsonString);
return jsonString;
}
@ -158,7 +167,7 @@ NSString * const TchError = @"tch_error";
if([t isEqual: @"i"]){
// int
[dict setValue:@([v integerValue]) forKey:k];
}else if([t isEqual: @"d"]){
} else if ([t isEqual: @"d"]){
// double
[dict setValue:@([v doubleValue]) forKey:k];
} else {
@ -211,26 +220,31 @@ NSString * const TchError = @"tch_error";
// 不存在 ad_paltform
[U3DAnalytics onTchErrorEvent:@"no_ad_platform" andRaw:json andOther:@""];
} else {
if(![[_platform stringValue] isEqual:@"appstore"]){
return;
}
// 非IAP订单
if(![[_platform stringValue] isEqual:@"appstore"] )
{
if([U3DAnalytics isNullObject: _value] ){
if([U3DAnalytics isNullObject: _value] ){
[dict setValue: [NSNumber numberWithDouble: targetValue] forKey:@"value"];
[U3DAnalytics onTchErrorEvent:@"no_value" andRaw:json andOther:@""];
} else {
if([_value doubleValue] < targetValue){
[dict setValue: [NSNumber numberWithDouble: targetValue] forKey:@"value"];
[U3DAnalytics onTchErrorEvent:@"no_value" andRaw:json andOther:@""];
} else {
if([_value doubleValue] < targetValue){
[dict setValue: [NSNumber numberWithDouble: targetValue] forKey:@"value"];
[U3DAnalytics onTchErrorEvent:@"value_error"
andRaw:json andOther: [_value stringValue]];
}
[U3DAnalytics onTchErrorEvent:@"value_error"
andRaw:json andOther: [_value stringValue]];
}
}
}
}
// 向Unity发送数据
+(void) sendMessage: (NSString *)msg
+(void) sendMessageToUnity: (NSString *)msg
{
if (msg == NULL) {
return;
}
// NSLog(@"--- unityInitSDK222: %@:%@", gameObjectName, callbackName);
if(gameObjectName != nil && callbackName != nil){
char *t1 = [U3DAnalytics finalChar: gameObjectName];
@ -277,7 +291,7 @@ NSString * const TchError = @"tch_error";
extern "C" {
// 请求GDPR
// 初始化自打点
void unityInitAnalytics(const char *appId, const char *deviceInfo, bool isDebug, const char *baseUrl, const char *uploadIpAddressStr)
{
// NSLog(@"--- [iOS] init Analytics libs");
@ -296,7 +310,8 @@ extern "C" {
// 设置 uploadIpAddress
// TODO: 当前的版本并不支持 uploadIpAddress, 后面的版本将 uploadIpAddressStr 转化为 Array<NSString> 传入接口
}
// 初始化回调对象和参数
void unityInitCallback(const char *gameObject, const char *method){
// NSLog(@"--- unityInitSDK111: %s:%s", gameObject, method);
gameObjectName = [NSString stringWithUTF8String:gameObject];
@ -308,7 +323,7 @@ extern "C" {
[GuruAnalytics setUserID:[U3DAnalytics charToString:uid]];
}
// 设置用户ID
// 设置Screen
void unitySetScreen(const char *screenName){
[GuruAnalytics setScreen:[U3DAnalytics charToString:screenName]];
}
@ -349,7 +364,7 @@ extern "C" {
parameters:[U3DAnalytics buildDataWithJson:json andKey:evtName]]; // JSON转换
}
// 上报事件
// 设置 Tch02 的上限值(即将废弃)
void unitySetTch02Value(const double value){
[U3DAnalytics setTch02MaxValue:value];
}

View File

@ -1,3 +1,4 @@
// ReSharper disable ReplaceSubstringWithRangeIndexer
namespace Guru
{
using System;
@ -78,14 +79,11 @@ namespace Guru
}
}
/// <summary>
/// 错误 code 表
/// </summary>
private readonly List<int> _errorCodeList = new List<int>();
private bool _enableErrorLog;
private string _experimentGroupId;
public string ExperimentGroupId => _experimentGroupId;
private DateTime _lastReportTime;
/// <summary>
/// 启动日志错误上报
@ -144,7 +142,8 @@ namespace Guru
// 初始化参数
Agent.Init(appId, deviceInfo, baseUrl, uploadIpAddress, onInitComplete, isDebug);
_lastReportTime = new DateTime(1970, 1, 1);
_isReady = true;
Debug.Log($"{Tag} --- Guru Analytics [{Version}] initialized.");
Debug.Log($"{Tag} --- GroupId: {groupId}");
@ -403,7 +402,7 @@ namespace Guru
{
if (string.IsNullOrEmpty(raw)) return;
if (!raw.Contains($"\"{ActionName}\"")) return; // 不对其他行为的日志进行过滤
ParseWithJson(raw);
ParseJsonAndSendEvent(raw);
}
/// <summary>
@ -411,72 +410,64 @@ namespace Guru
/// </summary>
/// <param name="code"></param>
/// <param name="errorInfo"></param>
private void OnLoggerErrorEvent(int code, string errorInfo = "")
/// <param name="category"></param>
/// <param name="extra"></param>
private void ReportDevAuditEvent(int code, string errorInfo = "", string category = "", Dictionary<string, object> extra = null)
{
// Debug.Log($"{Tag} --- OnLoggerErrorEvent: code:{code}\t info:{errorInfo}");
var codeString = ((AnalyticsCode)code).ToString();
if (string.IsNullOrEmpty(codeString) || codeString == AnalyticsCode.Unknown.ToString()) codeString = $"ErrorCode:{code}";
if (string.IsNullOrEmpty(codeString)) codeString = $"ErrorCode:{code}";
if (string.IsNullOrEmpty(errorInfo)) errorInfo = "Empty";
Dictionary<string, dynamic> parameters = new Dictionary<string, dynamic>()
var parameters = new Dictionary<string, dynamic>()
{
{"item_category", "error_event"},
{"item_name", codeString},
{"country", IPMConfig.IPM_COUNTRY_CODE},
{"network", Application.internetReachability.ToString()},
{"exp", _experimentGroupId}
};
if (!string.IsNullOrEmpty(category))
{
parameters[Analytics.ParameterItemCategory] = category;
}
int len = 96;
if (errorInfo.Length > len)
errorInfo = errorInfo.TrimStart().Substring(0, len);
if (!string.IsNullOrEmpty(errorInfo))
parameters["err"] = errorInfo;
if (extra != null)
{
// if (errorInfo.Contains("\"")) errorInfo = errorInfo.Replace("\"", "\\\"");
int len = 96;
if (errorInfo.Length > len) errorInfo = errorInfo.TrimStart().Substring(0, len);
foreach (var kvp in extra)
{
parameters[kvp.Key] = kvp.Value;
}
}
else
{
errorInfo = "empty error info";
}
parameters["err"] = errorInfo;
Debug.Log($"{Tag} ------ ErrorLogInfo:: code:{codeString}\tinfo:{errorInfo}");
// Only for firebase GA
Analytics.TrackEvent("dev_audit", parameters, new Analytics.EventSetting() { EnableFirebaseAnalytics = true });
}
private void ParseWithJson(string json)
private void ParseJsonAndSendEvent(string json)
{
Debug.Log($"{Tag} ------ ParseWithJson: json:\n{json}");
int code = (int)AnalyticsCode.Unknown;
int code = (int)AnalyticsCode.UNITY_INTERNAL_ERROR;
string info = json;
try
{
var dict = JsonConvert.DeserializeObject<JObject>(json);
if(dict != null && dict.TryGetValue("data", out var jData))
{
var j = jData.Value<JObject>();
if (j != null && j.TryGetValue("code", out var jCode))
{
code = jCode.Value<int>();
if (j.TryGetValue("msg", out var jMsg))
{
info = jMsg.Value<string>();
}
else
{
info = $"wrong msg format: {json}";
}
}
}
else
{
info = "no data property";
}
ReportCodeInfo(code, info);
if (dict == null || !dict.TryGetValue("data", out var jData)) return;
var j = jData.Value<JObject>();
if (j == null || !j.TryGetValue("code", out var jCode)) return;
code = jCode.Value<int>();
if (!j.TryGetValue("msg", out var jMsg)) return;
info = jMsg.Value<string>();
ReportWithCodeAndInfo(code, info);
}
catch (Exception)
{
@ -487,85 +478,141 @@ namespace Guru
// Debug.Log($"{Tag} --- {info}");
Analytics.LogCrashlytics(json, false);
Analytics.LogCrashlytics(info);
ReportCodeInfo(code, info);
ReportWithCodeAndInfo(code, info);
}
}
private void ReportCodeInfo(int code, string info)
/// <summary>
/// 上报异常
/// 上报条件:上报总数 > 30 条, 上报成功率小于 0.7, 且间隔 5 分钟
/// Native 已经处理数量和成功率判断
/// </summary>
/// <param name="code"></param>
/// <param name="info"></param>
private void ReportWithCodeAndInfo(int code, string info)
{
if (Agent == null) return;
if (Application.internetReachability == NetworkReachability.NotReachable) return; // 网络不可用时不上报
ReportAnalyticsAudit(); // 上报
// 源码https://github.com/castbox/flutter_jigsort/blob/3.2.0V2/lib/data/jigsort_compliance_protocol.dart
var ac = (AnalyticsCode)code;
Debug.Log($"{Tag} ------ Get Code And Info: code:{code}[{ac}] \tinfo:{info}");
bool canCatch = false;
switch (ac)
{
case AnalyticsCode.Unknown:
case AnalyticsCode.DELETE_EXPIRED:
case AnalyticsCode.UPLOAD_FAIL:
case AnalyticsCode.NETWORK_LOST:
case AnalyticsCode.CRONET_INIT_FAIL:
case AnalyticsCode.CRONET_INIT_EXCEPTION:
case AnalyticsCode.ERROR_API:
case AnalyticsCode.ERROR_RESPONSE:
case AnalyticsCode.ERROR_CACHE_CONTROL:
case AnalyticsCode.ERROR_DELETE_EXPIRED:
case AnalyticsCode.ERROR_LOAD_MARK:
case AnalyticsCode.ERROR_DNS:
case AnalyticsCode.ERROR_ZIP:
case AnalyticsCode.ERROR_DNS_CACHE:
case AnalyticsCode.CRONET_INTERCEPTOR:
case AnalyticsCode.EVENT_LOOKUP:
case AnalyticsCode.EVENT_SESSION_ACTIVE:
canCatch = true;
case AnalyticsCode.UNITY_INTERNAL_ERROR: // -1
ReportUnityErrorEvent(code, info);
break;
// case AnalyticsCode.DELETE_EXPIRED:
case AnalyticsCode.UPLOAD_FAIL: //14
ReportUploadFailEvent(code, info);
break;
// case AnalyticsCode.NETWORK_LOST:
// case AnalyticsCode.CRONET_INIT_FAIL:
// case AnalyticsCode.CRONET_INIT_EXCEPTION:
// case AnalyticsCode.ERROR_API:
// case AnalyticsCode.ERROR_RESPONSE:
// case AnalyticsCode.ERROR_CACHE_CONTROL:
// case AnalyticsCode.ERROR_DELETE_EXPIRED:
case AnalyticsCode.ERROR_LOAD_MARK: // 105
ReportRuntimeErrorEvent(code, info);
break;
// case AnalyticsCode.ERROR_DNS:
// case AnalyticsCode.ERROR_ZIP:
// case AnalyticsCode.ERROR_DNS_CACHE:
// case AnalyticsCode.CRONET_INTERCEPTOR:
// case AnalyticsCode.ERROR_SESSION_START_ERROR:
case AnalyticsCode.EVENT_LOOKUP: // 1003
ReportDNSErrorEvent(code, info);
break;
case AnalyticsCode.EVENT_SESSION_ACTIVE: // 1004
ReportSessionActiveErrorEvent(code, info);
break;
}
if (!canCatch && code is > 100 and <= 200)
{
// 100 < code <= 200
canCatch = true;
}
}
private int _reportUploadFailCount = 0;
/// <summary>
/// 上报失败事件 (14)
/// </summary>
/// <param name="code"></param>
/// <param name="info"></param>
private void ReportUploadFailEvent(int code, string info)
{
if (Agent.GetEventCountTotal() < 50) return; // 数量太少不报
if ((float)Agent.GetEventCountUploaded() / Agent.GetEventCountTotal() > 0.6f) return; // 成功率太高也不报
if (_reportUploadFailCount >= 5) return; // N 次之后不再上报
ReportDevAuditEvent(code, info);
_reportUploadFailCount++;
}
if (_errorCodeList != null && _errorCodeList.Count > 0)
{
if (_errorCodeList[0] == -1)
{
canCatch = true;
}
else
{
canCatch = _errorCodeList.Contains(code);
}
}
private int _reportRuntimeExceptionTimes = 0;
// 105
private void ReportRuntimeErrorEvent(int code, string info)
{
if (_reportRuntimeExceptionTimes >= 5) return; // N 次之后不再上报
ReportDevAuditEvent(code, info);
_reportRuntimeExceptionTimes++;
}
// 1003
private void ReportDNSErrorEvent(int code, string info)
{
ReportDevAuditEvent(code, info, "ga_dns");
}
// 1004
private void ReportSessionActiveErrorEvent(int code, string info)
{
ReportDevAuditEvent(code, info, "session_active");
}
// -1
private void ReportUnityErrorEvent(int code, string info)
{
ReportDevAuditEvent(code, info, "unity");
}
if(canCatch) OnLoggerErrorEvent(code, info);
// 上报 Snapshot 数据
private void ReportAnalyticsAudit()
{
if(DateTime.UtcNow - _lastReportTime < TimeSpan.FromMinutes(5)) // 5 分钟内只上报一次
return;
var snapshot = Agent.GetAuditSnapshot();
if (string.IsNullOrEmpty(snapshot)) return; // 空字段不报
var data = JsonParser.ToObject<Dictionary<string, object>>(snapshot);
if (data == null) return; // 解析失败不报
// 上报事件
ReportDevAuditEvent(0, "","analytics_audit", data);
_lastReportTime = DateTime.UtcNow;
}
#endregion
#region UNIT_TEST
#if UNITY_EDITOR
public static void TestOnCallback(string msg)
{
Instance.OnSDKCallback(msg);
}
#endif
#endregion
}
/// <summary>
/// 网络状态枚举
/// 详见 guru_analytics 库 guru.core.analytics.handler.AnalyticsCode 类
/// </summary>
public enum AnalyticsCode
{
Unknown = -1,
UNITY_INTERNAL_ERROR = -1, // unity 内部错误
DELETE_EXPIRED = 12, // 删除过期事件
UPLOAD_FAIL = 14, // 上报事件失败
@ -582,6 +629,7 @@ namespace Guru
ERROR_ZIP = 107, // zip 错误
ERROR_DNS_CACHE = 108, // zip 错误
CRONET_INTERCEPTOR = 109, // cronet拦截器
ERROR_SESSION_START_ERROR = 110,
EVENT_LOOKUP = 1003,
EVENT_SESSION_ACTIVE = 1004,

View File

@ -69,6 +69,7 @@ namespace Guru
/// <summary>
/// 默认的本地配置
/// 2024-08-08 经后台确认,只保留 B 组C 组已经被废弃
/// </summary>
private const string DEFAULT_GURU_ANALYTICS_EXP = @"{
""enable"": true,
@ -76,12 +77,7 @@ namespace Guru
""groupId"": ""B"",
""baseUrl"": ""https://collect.saas.castbox.fm"",
""uploadIpAddress"": [""13.248.248.135"", ""3.33.195.44""],
""enableErrorLog"": true
}, {
""groupId"": ""C"",
""baseUrl"": ""https://collect3.saas.castbox.fm"",
""uploadIpAddress"": [""34.107.185.54""],
""enableErrorLog"": true
""enableErrorLog"": false
}]
}";

View File

@ -21,5 +21,8 @@ namespace Guru
void ReportEventSuccessRate(); // 上报任务成功率
void SetTch02Value(double value); // 设置太极02数值
void InitCallback(string objName, string method); // 设置回调对象参数
int GetEventCountTotal(); // 获取事件总数
int GetEventCountUploaded(); // 获取成功上报的事件数量
string GetAuditSnapshot(); // 获取 AuditSnapshot 字段
}
}

View File

@ -14,7 +14,6 @@ namespace Guru
#endif
private static bool _isDebug = false;
public static string BaseUrl = "";
#region 工具方法
@ -171,6 +170,11 @@ namespace Guru
CallStatic("setEnableErrorLog", _enableErrorLog);
}
}
public int GetEventCountTotal() => CallStatic<int>("getEventCountAll");
public int GetEventCountUploaded() => CallStatic<int>("getEventCountUploaded");
public string GetAuditSnapshot() => CallStatic<string>("getAuditSnapshot");
#endregion
}

View File

@ -29,6 +29,8 @@ namespace Guru
[DllImport(K_INTERNAL)] private static extern void unitySetTch02Value(double value);
[DllImport(K_INTERNAL)] private static extern void unitySetEnableErrorLog(bool value);
[DllImport(K_INTERNAL)] private static extern void unityInitCallback(string objName, string method);
[DllImport(K_INTERNAL)] private static extern int unityGetEventsCountAll();
[DllImport(K_INTERNAL)] private static extern int unityGetEventsCountUploaded();
#endif
private static bool _isDebug = false;
@ -162,7 +164,30 @@ namespace Guru
// iOS 测试用事件
public static void TestCrashEvent()=> unityTestUnrecognizedSelectorCrash();
#endif
public int GetEventCountTotal()
{
#if UNITY_IOS
return unityGetEventsCountAll();
#endif
return 1;
}
public int GetEventCountUploaded()
{
#if UNITY_IOS
return unityGetEventsCountUploaded();
#endif
return 0;
}
public string GetAuditSnapshot()
{
// TODOiOS 原生类并未实现此接口
return "";
}
#endregion
}

View File

@ -24,9 +24,12 @@ namespace Guru
Debug.Log($"{TAG} EnableErrorLog:<color=orange>{value}</color>");
_enableErrorLog = value;
}
}
private int _eventTotalCount = 0;
private int _eventSuccessCount = 0;
public void Init(string appId, string deviceInfo, string baseUrl, string[] uploadIpAddress, Action onInitComplete, bool isDebug = false)
{
#if UNITY_EDITOR
@ -148,6 +151,12 @@ namespace Guru
Debug.Log($"{TAG} LogEvent: GuruAnalytics:<color=orange>{eventName} ({priority})</color> Properties:\n{sb.ToString()}");
}
}
_eventTotalCount++;
if (UnityEngine.Random.Range(0, 10) < 8)
{
_eventSuccessCount++;
}
}
public void ReportEventSuccessRate()
@ -160,13 +169,16 @@ namespace Guru
Debug.Log($"{TAG} Tch02MaxValue: {value}");
}
public int GetEventCountTotal() => _eventTotalCount;
public int GetEventCountUploaded() => _eventSuccessCount;
public string GetAuditSnapshot() => "";
#region Editor Test API
#endregion
}
}

View File

@ -542,114 +542,113 @@ namespace Guru
*/
//-------------------- 设置所有的属性 -----------------------
public void ReportUid(string uid)
{
var prop = new MidWarePropertyUid(uid);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportBLevel(string bLevel)
{
var prop = new MidWarePropertyBLevel(bLevel);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportBPlay(string bPlay)
{
var prop = new MidWarePropertyBPlay(bPlay);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportAnalyticsExperimentGroup(string groupName)
{
var prop = new MidWarePropertyAnalyticsExperimentGroup(groupName);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportSignUpMethod(string methodName)
{
var prop = new MidWarePropertySignUpMethod(methodName);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportDeviceId(string deviceId)
{
var prop = new MidWarePropertyDeviceId(deviceId);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportFirstOpenTime(string firstOpenTime)
{
var prop = new MidWarePropertyFirstOpenTime(firstOpenTime);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportIsIapUser(bool isIapUser)
{
var prop = new MidWarePropertyIsIapUser(isIapUser);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportNetworkStatus(string networkStatus)
{
var prop = new MidWarePropertyNetwork(networkStatus);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportAdjustId(string adjustId)
{
var prop = new MidWarePropertyAdjustId(adjustId);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportAttStatus(string attStatus)
{
var prop = new MidWarePropertyAttStatus(attStatus);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportNotiPerm(string notiPerm)
{
var prop = new MidWarePropertyNotiPerm(notiPerm);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportAndroidId(string androidId)
{
var prop = new MidWarePropertyAndroidId(androidId);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportGoogleAdId(string googleAdId)
{
var prop = new MidWarePropertyGoogleAdId(googleAdId);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportIDFV(string idfv)
{
var prop = new MidWarePropertyIDFV(idfv);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}
public void ReportIDFA(string idfa)
{
var prop = new MidWarePropertyIDFA(idfa);
_propertyMap.TryAdd(prop.key, prop);
_propertyMap[prop.key] = prop;
prop.Report();
}