upm-guru-sdk-analytics/Plugins/iOS/U3DAnalytics.mm

295 lines
9.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// ==============================================
// U3DConsent.mm
// UnityFramework
//
// Created by EricHu on 2022/11/17.
// Copyright © 2022 guru. All rights reserved.
// ==============================================
#import <Foundation/Foundation.h>
#import "UnityAppController+UnityInterface.h"
#import <GuruAnalyticsLib/GuruAnalyticsLib-Swift.h>
@interface U3DAnalytics : NSObject
//+ (void)requestGDPR: (NSString *)deviceId :(int) debugGeo;
//+ (UIViewController *) getUnityViewController;
@end
static NSString *gameobjectName;
static NSString *callbackName;
static GuruAnalytics *_analytics;
@implementation U3DAnalytics
// Const value define
NSString * const Version = @"1.8.1";
static const double kUploadPeriodInSecond = 60.0;
static const int kBatchLimit = 15;
static const double kEventExpiredSeconds = 7 * 24 * 60 * 60;
static const double kInitializeTimeout = 5.0;
static double tch001MaxValue = 0.01;
static double tch02MaxValue = 0.2;
NSString * const TchAdRevRoas001 = @"tch_ad_rev_roas_001";
NSString * const TchAdRevRoas02 = @"tch_ad_rev_roas_02";
NSString * const TchError = @"tch_error";
+(UnityAppController *)GetAppController {
return (UnityAppController*)[UIApplication sharedApplication].delegate;
}
+(UIViewController *) getUnityViewController {
return UnityGetGLViewController();
}
// 字符串转换
+(const char*) stringToChar: (NSString *) str{
return [str cStringUsingEncoding:NSASCIIStringEncoding];
}
+(NSString *) charToString: (const char *) c{
return [[NSString alloc] initWithUTF8String:c];
}
// 获取最终字符串
+(char*) finalChar: (NSString *) string
{
const char *tmpChar = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (string == NULL)
return NULL;
char* res = (char*)malloc(strlen(tmpChar) + 1);
strcpy(res, tmpChar);
return res;
}
// 设置太极02的预设值
+(void) setTch02MaxValue: (const double) value{
tch02MaxValue = value;
}
// 构建数据
//+(NSString *) buildDataString: (int)status andMessage: (NSString *)msg{
//
// NSString *jsonString = [NSString stringWithFormat: @"{\"action\":\"gdpr\",\"data\":{\"status\":%d,\"msg\":\"%@\"}}", status, msg];
// return jsonString;
//}
// 构建数据字典
+(NSDictionary<NSString*, id> *) buildDataDict: (NSString *) str{
NSArray *raw = [str componentsSeparatedByString:@","];
if( raw == nil || raw.count == 0) return nil;
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init]; //must init before using
for(NSString *s in raw ){
NSArray *kvp = [s componentsSeparatedByString:@":"];
if(kvp == nil || kvp.count < 2){
continue;
}
NSString *k = kvp[0];
NSString *t = [kvp[1] substringToIndex:1];
NSString *v = [kvp[1] substringFromIndex:1];
// NSLog(@"---[iOS] parse kvp key:%@ type:%@ value:%@", k, t, v);
//TODO 解析字符值
if([t isEqual: @"i"]){
// int
[dict setValue:@([v integerValue]) forKey:k];
}else if([t isEqual: @"d"]){
// double
[dict setValue:@([v doubleValue]) forKey:k];
} else {
// String
[dict setValue:v forKey:k];
}
}
return dict;
}
// 构建Json格式的数据字典
+(NSMutableDictionary *) buildDataWithJson: (NSString *) json andKey: (NSString *) key{
if( json == nil || json.length == 0) return nil;
NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&err];
if(err || dict == nil)
{
NSLog(@"json解析失败%@",err);
[U3DAnalytics onTchErrorEvent:@"json_error" andRaw:json andOther:@""];
return nil;
}
// ---------- 太极数据校验 -------------
if(key == TchAdRevRoas001){
// tch 001 参数修复
[U3DAnalytics fixTchParams: dict andJson:json andMaxValue:tch001MaxValue];
} else if(key == TchAdRevRoas02){
// tch 02 参数修复
[U3DAnalytics fixTchParams: dict andJson:json andMaxValue:tch02MaxValue];
}
return dict;
}
// 修复自打点数据
+(void) fixTchParams: (NSMutableDictionary *)dict andJson: (NSString *)json andMaxValue: (double) targetValue {
// --- 保存 raw数据 ---
[dict setValue: json forKey:@"raw"];
id _platform = [dict objectForKey:@"ad_platform"];
id _value = [dict objectForKey:@"value"];
if([U3DAnalytics isNullObject: _platform]) {
// 不存在 ad_paltform
[U3DAnalytics onTchErrorEvent:@"no_ad_platform" andRaw:json andOther:@""];
} else {
// 非IAP订单
if(![[_platform stringValue] isEqual:@"appstore"] )
{
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:@"value_error"
andRaw:json andOther: [_value stringValue]];
}
}
}
}
}
// 上报 tch_error 事件
+(void) onTchErrorEvent:(NSString *) evtName andRaw: (NSString *)raw andOther: (NSString *) other{
NSString *json = [NSString stringWithFormat:@"{\"event\":\"%@\", \"raw\":\"%@\", \"other\":\"%@\"}", evtName, raw, other];
[GuruAnalytics logEvent:TchError
parameters:[U3DAnalytics buildDataWithJson:json andKey:evtName]];
}
// 对象判空
+ (BOOL)isNullObject:(__kindof id) obj{
if(!obj){
return YES;
}
if(obj == NULL){
return YES;
}
if([obj isEqual:[NSNull null]]){
return YES;
}
return NO;
}
@end
//============================ UNITY PUBLIC API ============================
extern "C" {
// 请求GDPR
void unityInitAnalytics(const char *appId, const char *deviceInfo, bool isDebug)
{
// NSLog(@"--- [iOS] init Analytics libs");
[GuruAnalytics initializeLibWithUploadPeriodInSecond:kUploadPeriodInSecond
batchLimit:kBatchLimit
eventExpiredSeconds:kEventExpiredSeconds
initializeTimeout:kInitializeTimeout
saasXAPPID:[U3DAnalytics charToString:appId]
saasXDEVICEINFO:[U3DAnalytics charToString:deviceInfo]
loggerDebug:isDebug];
}
// 设置用户ID
void unitySetUserID(const char *uid){
[GuruAnalytics setUserID:[U3DAnalytics charToString:uid]];
}
// 设置用户ID
void unitySetScreen(const char *screenName){
[GuruAnalytics setScreen:[U3DAnalytics charToString:screenName]];
}
// 设置用户ADID
void unitySetAdId(const char *adId){
[GuruAnalytics setAdId:[U3DAnalytics charToString:adId]];
}
// 设置用户AdjustID
void unitySetAdjustID(const char *adjustId){
[GuruAnalytics setAdjustId:[U3DAnalytics charToString:adjustId]];
}
// 设置用户FirebaseID
void unitySetFirebaseId(const char *firebaseId){
[GuruAnalytics setFirebaseId:[U3DAnalytics charToString:firebaseId]];
}
// 设置用户设备ID
void unitySetDeviceId(const char *did){
[GuruAnalytics setDeviceId:[U3DAnalytics charToString:did]];
}
// 设置用户属性
void unitySetUserProperty(const char *key, const char *value){
[GuruAnalytics setUserProperty:[U3DAnalytics charToString:value]
forName:[U3DAnalytics charToString:key]];
}
// 上报事件
void unityLogEvent(const char *key, const char *data){
NSString *evtName = [U3DAnalytics charToString:key];
NSString *json = [U3DAnalytics charToString:data];
[GuruAnalytics logEvent: evtName
parameters:[U3DAnalytics buildDataWithJson:json andKey:evtName]]; // JSON转换
}
// 上报事件
void unitySetTch02Value(const double value){
[U3DAnalytics setTch02MaxValue:value];
}
// 打点事件成功率
void unityReportEventRate(void){
[GuruAnalytics debug_eventsStatistics:^(NSInteger uploadedEventsCount, NSInteger loggedEventsCount) {
// 上报事件总量
[GuruAnalytics setUserProperty:[NSString stringWithFormat:@"%ld", loggedEventsCount]
forName:@"lgd"];
// 上报成功数量
[GuruAnalytics setUserProperty:[NSString stringWithFormat:@"%ld", uploadedEventsCount]
forName:@"uld"];
}];
}
}