622 lines
20 KiB
Objective-C
622 lines
20 KiB
Objective-C
#include "XUDPServer.h"
|
|
#import <Foundation/Foundation.h>
|
|
#import "IPhoneHertbeat.h"
|
|
#import "XSHackIos.h"
|
|
#import "XSHelper.h"
|
|
#import "XSPhoneInfo.h"
|
|
#import "XSPhoneConfig.h"
|
|
#import "MyAdServer.h"
|
|
#import "MyAdTask2.h"
|
|
#import "MyEventBus.h"
|
|
|
|
BOOL myadTaskManualStop = NO;
|
|
|
|
@interface MyAdTask2Mangger()
|
|
{
|
|
@private
|
|
BOOL running;
|
|
dispatch_source_t _timer;
|
|
NSDate *lastRun;
|
|
NSDate *lastGetCountry;
|
|
NSString *_lastIdfa;
|
|
NSString *taskId;
|
|
NSString *taskAppId;
|
|
int workType;
|
|
int screen_w;
|
|
int screen_h;
|
|
int adAfter;
|
|
NSString *linkId;
|
|
NSString *dataId;
|
|
NSString *remoteIp;
|
|
NSString *country;
|
|
dispatch_source_t _appendCheckTimer; // 新增定时器
|
|
|
|
}
|
|
|
|
@property (nonatomic, assign) NSTimeInterval lastAppSwitchTime; // 新增属性
|
|
|
|
@end
|
|
|
|
@implementation MyAdTask2Mangger
|
|
|
|
+(instancetype)sharedInstance {
|
|
static MyAdTask2Mangger* _sharedInstance = nil;
|
|
static dispatch_once_t oncePredicate;
|
|
dispatch_once(&oncePredicate, ^{
|
|
_sharedInstance = [[MyAdTask2Mangger alloc] init];
|
|
});
|
|
return _sharedInstance;
|
|
}
|
|
|
|
-(instancetype)init {
|
|
if (self = [super init]) {
|
|
self->running = NO;
|
|
self->_lastIdfa = @"";
|
|
self.manQueue = dispatch_queue_create("com.xyzshell.myadtask", DISPATCH_QUEUE_SERIAL);
|
|
CGFloat screen_scale = [[UIScreen mainScreen] scale];
|
|
CGFloat device_screen_width = [UIScreen mainScreen].bounds.size.width * screen_scale;
|
|
CGFloat device_screen_height = [UIScreen mainScreen].bounds.size.height * screen_scale;
|
|
self->screen_w = device_screen_width;
|
|
self->screen_h = device_screen_height;
|
|
self->adAfter = 1000;
|
|
self.lastAppSwitchTime = 0; // 初始化为0
|
|
return self;
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
- (int)onShow:(NSDictionary *)dic {
|
|
if(dic == nil || [dic isEqual:[NSNull null]] || [dic count] <= 0) {
|
|
return 4000;
|
|
}
|
|
NSString *t_appid = [self getStr:@"appid" dic:dic];
|
|
NSString *t_idfa = [self getStr:@"idfa" dic:dic];
|
|
NSString *t_adId = [self getStr:@"id" dic:dic];
|
|
NSNumber *t_ecpm = [self getNum:@"ecpm" dic:dic];
|
|
BOOL ad = dic[@"ad"];
|
|
NSString *iphoneId = [[XSPhoneConfig sharedInstance] IPhoneName];
|
|
|
|
if(!ad) {
|
|
NSLog(@"XS- no ad show");
|
|
return 0;
|
|
}
|
|
int close = 4000;
|
|
|
|
AdLoadInfo adloadInfo = getAdLoadInfo(@{
|
|
@"idfa": t_idfa ?: @"",
|
|
@"adId": t_adId ?: @"",
|
|
@"ecpm": [NSString stringWithFormat:@"%@", t_ecpm],
|
|
@"appId": t_appid ?: @"",
|
|
@"deviceId":iphoneId ?: @""
|
|
});
|
|
|
|
close = [adloadInfo.adTime intValue];
|
|
int before = [adloadInfo.adTouchBeforeMs intValue];
|
|
if (before >= close) {
|
|
before = 1000;
|
|
}
|
|
int after = [adloadInfo.adTouchAfterMs intValue];
|
|
if(after > 1000) {
|
|
self->adAfter = after;
|
|
} else {
|
|
self->adAfter = 1000;
|
|
}
|
|
|
|
NSInteger random1 = arc4random_uniform(101);
|
|
NSInteger tr = [adloadInfo.touchRate intValue];
|
|
if (tr > random1) {
|
|
double beforeSec = before / 1000.0;
|
|
__weak typeof(self) weakSelf = self;
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(beforeSec * NSEC_PER_SEC)),
|
|
self.manQueue, ^{
|
|
|
|
});
|
|
}
|
|
return close;
|
|
}
|
|
|
|
- (void)showStatus:(NSString *)data {
|
|
[[MyEventBus sharedInstance] postEvent:@"UpdateStatus" withObject:data];
|
|
}
|
|
|
|
- (void)setRemoteInfo {
|
|
if (self->country != nil && ![self->country isEqual:@""]) {
|
|
NSLog(@"Country info already set, skipping remote info update.");
|
|
return; // 如果国家信息已存在,则跳过更新
|
|
}
|
|
NSString *url = @"https://ipapi.co/json/";
|
|
if (!url) {
|
|
NSLog(@"Invalid URL for remote info");
|
|
return;
|
|
}
|
|
XSHttpHelper *http = [[XSHttpHelper alloc] init];
|
|
__weak typeof(self) weakSelf = self;
|
|
[http doGET:url withCallback:^(NSData *data) {
|
|
if(!data) {
|
|
NSLog(@"!setRemoteInfo 1data");
|
|
[weakSelf showStatus:@"!setRemoteInfo 1data"];
|
|
return;
|
|
}
|
|
NSDictionary *dic = [XSHelper jsonData2Dictionary:data];
|
|
if (!dic) {
|
|
NSLog(@"!setRemoteInfo dic");
|
|
[weakSelf showStatus:@"!setRemoteInfo dic"];
|
|
return;
|
|
}
|
|
NSString *isoCode = dic[@"country_code"];
|
|
NSString *ip = dic[@"ip"];
|
|
if (!isoCode || !ip) {
|
|
NSLog(@"Invalid data received for remote info");
|
|
return;
|
|
}
|
|
|
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
if (!strongSelf) return;
|
|
|
|
strongSelf->remoteIp = [ip copy];
|
|
strongSelf->country = [isoCode copy];
|
|
[XSPhoneInfo sharedInstance].remoteIp = [NSString stringWithFormat:@"%@:%@", isoCode, ip];
|
|
[weakSelf showStatus:[XSPhoneInfo sharedInstance].remoteIp];
|
|
} withError:^(NSError *err) {
|
|
NSLog(@"!setRemoteInfo err:%@",err);
|
|
[weakSelf showStatus:[NSString stringWithFormat:@"%@", err.description]];
|
|
}];
|
|
}
|
|
|
|
- (void)setRemoteInfo1 {
|
|
NSString *url = [[XSPhoneConfig sharedInstance] GetRemoteIPURL];
|
|
[self showStatus:url];
|
|
if (!url) {
|
|
NSLog(@"!setRemoteInfo url");
|
|
return;
|
|
}
|
|
__weak typeof(self) weakSelf = self;
|
|
|
|
XSHttpHelper *http = [[XSHttpHelper alloc] init];
|
|
[http doGET:url withCallback:^(NSData *data) {
|
|
if(!data) {
|
|
NSLog(@"!setRemoteInfo 1data");
|
|
[weakSelf showStatus:@"!setRemoteInfo 1data"];
|
|
return;
|
|
}
|
|
NSDictionary *dic = [XSHelper jsonData2Dictionary:data];
|
|
if (!dic) {
|
|
NSLog(@"!setRemoteInfo dic");
|
|
[weakSelf showStatus:@"!setRemoteInfo dic"];
|
|
return;
|
|
}
|
|
NSDictionary *_data = dic[@"data"];
|
|
if(!_data) {
|
|
NSLog(@"!setRemoteInfo data");
|
|
[weakSelf showStatus:@"!setRemoteInfo data"];
|
|
return;
|
|
}
|
|
NSString *isoCode = _data[@"isoCode"];
|
|
NSString *ip = _data[@"ip"];
|
|
NSLog(@"setRemoteInfo:%@", _data);
|
|
|
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
if (!strongSelf) return;
|
|
|
|
strongSelf->remoteIp = [ip copy];
|
|
strongSelf->country = [isoCode copy];
|
|
[XSPhoneInfo sharedInstance].remoteIp = [NSString stringWithFormat:@"%@:%@", isoCode, ip];
|
|
[weakSelf showStatus:[XSPhoneInfo sharedInstance].remoteIp];
|
|
} withError:^(NSError *err) {
|
|
NSLog(@"!setRemoteInfo err:%@",err);
|
|
[weakSelf showStatus:[NSString stringWithFormat:@"%@", err.description]];
|
|
}];
|
|
}
|
|
|
|
// 新增方法:检查并处理 append 文件
|
|
- (void)checkAppendFile {
|
|
NSString *appendDirPath = @"/var/mobile/Documents/ad/append";
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
BOOL isDir = NO;
|
|
if ([fileManager fileExistsAtPath:appendDirPath isDirectory:&isDir] && isDir) {
|
|
NSArray *files = [fileManager contentsOfDirectoryAtPath:appendDirPath error:nil];
|
|
if (files.count > 0) {
|
|
BOOL allDeleted = YES;
|
|
for (NSString *file in files) {
|
|
NSString *filePath = [appendDirPath stringByAppendingPathComponent:file];
|
|
NSError *error = nil;
|
|
[fileManager removeItemAtPath:filePath error:&error];
|
|
if (error) {
|
|
NSLog(@"Failed to delete file: %@, error: %@", filePath, error);
|
|
allDeleted = NO;
|
|
}
|
|
}
|
|
if (allDeleted) {
|
|
NSLog(@"append directory has files, deleted all, calling onEnd");
|
|
[self onEnd:nil];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (BOOL)onEnd:(NSDictionary *)dic {
|
|
@autoreleasepool {
|
|
if (self->taskAppId) {
|
|
[self appKill:self->taskAppId];
|
|
}
|
|
[self startApp];
|
|
}
|
|
return NO;
|
|
}
|
|
|
|
- (void)startApp {
|
|
@autoreleasepool {
|
|
if (!self->running) {
|
|
return;
|
|
}
|
|
self->lastRun = [NSDate date];
|
|
|
|
NSDate *startTime = [NSDate date];
|
|
NSLog(@"getChangeInfo started at: %@", startTime);
|
|
__weak typeof(self) weakSelf = self;
|
|
getChangeInfo(self->_lastIdfa ?: @"", ^(NSDictionary *dic) {
|
|
if (!dic) {
|
|
NSLog(@"getChangeInfo returned nil dictionary");
|
|
return;
|
|
}
|
|
NSDate *endTime = [NSDate date];
|
|
NSTimeInterval duration = [endTime timeIntervalSinceDate:startTime];
|
|
NSLog(@"getChangeInfo completed at: %@, duration: %.2f seconds", endTime, duration);
|
|
dispatch_async(weakSelf.manQueue, ^{
|
|
[weakSelf onChangeInfo:dic];
|
|
});
|
|
}, ^(NSError *err) {
|
|
NSDate *endTime = [NSDate date];
|
|
NSTimeInterval duration = [endTime timeIntervalSinceDate:startTime];
|
|
NSLog(@"getChangeInfo completed at: %@, duration: %.2f seconds", endTime, duration);
|
|
NSLog(@"XS- startTask NSError is null, %@", err);
|
|
[weakSelf showStatus:[NSString stringWithFormat:@"getChangeInfo error after 5s restart: %@", err.description]];
|
|
// 延迟重新启动App
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), weakSelf.manQueue, ^{
|
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
if (strongSelf && strongSelf->running) { // 确保任务未被停止
|
|
[strongSelf startApp];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
- (void)start {
|
|
self->running = YES;
|
|
myadTaskManualStop = NO;
|
|
[[IPhoneHertbeat sharedInstance] setStatus:@"运行中"];
|
|
[self startApp];
|
|
__weak typeof(self) weakSelf = self;
|
|
// 确保Timer在重新启动前被取消
|
|
if (_timer) {
|
|
dispatch_source_cancel(_timer);
|
|
_timer = nil;
|
|
}
|
|
// 使用 dispatch_source 创建timer
|
|
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.manQueue);
|
|
dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), 10 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);
|
|
dispatch_source_set_event_handler(_timer, ^{
|
|
@autoreleasepool {
|
|
[weakSelf proc];
|
|
// 检查心跳状态
|
|
if (![[IPhoneHertbeat sharedInstance] isHeartbeatActive]) {
|
|
NSLog(@"Heartbeat inactive, restarting...");
|
|
[[IPhoneHertbeat sharedInstance] restartHeartbeat];
|
|
}
|
|
}
|
|
});
|
|
dispatch_resume(_timer);
|
|
|
|
// 新增定时器,每秒检查 append 文件
|
|
if (_appendCheckTimer) {
|
|
dispatch_source_cancel(_appendCheckTimer);
|
|
_appendCheckTimer = nil;
|
|
}
|
|
_appendCheckTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.manQueue);
|
|
dispatch_source_set_timer(_appendCheckTimer, dispatch_time(DISPATCH_TIME_NOW, 0), 1 * NSEC_PER_SEC, 0);
|
|
dispatch_source_set_event_handler(_appendCheckTimer, ^{
|
|
[weakSelf checkAppendFile];
|
|
});
|
|
dispatch_resume(_appendCheckTimer);
|
|
|
|
[[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(YES)];
|
|
}
|
|
|
|
- (void)proc {
|
|
if (!self->running) {
|
|
return;
|
|
}
|
|
|
|
NSLog(@"XS- MyAdTaskManager proc");
|
|
NSDate* curRunTime = [NSDate date];
|
|
NSTimeInterval elapsed = [curRunTime timeIntervalSinceDate:self->lastRun];
|
|
BOOL washParam = [[XSPhoneConfig sharedInstance] WashParam];
|
|
if (elapsed >= 80) {
|
|
//[self onStop];
|
|
[self startApp];
|
|
|
|
}
|
|
if (!washParam) {
|
|
NSString* appId = [ self frontMostAppId];
|
|
|
|
if (![appId isEqual: self->taskAppId]) {
|
|
// 引入冷却时间,避免频繁切换应用
|
|
[self appKill:appId];
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), self.manQueue, ^{
|
|
[self appRun:self->taskAppId];
|
|
self.lastAppSwitchTime = [NSDate timeIntervalSinceReferenceDate]; // 更新切换时间
|
|
});
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
- (NSString *)toggle {
|
|
if(self->running) {
|
|
[self stop];
|
|
} else {
|
|
[self start];
|
|
}
|
|
return [IPhoneHertbeat sharedInstance].status;
|
|
}
|
|
|
|
- (void)stop {
|
|
myadTaskManualStop = YES;
|
|
self->running = NO;
|
|
[IPhoneHertbeat sharedInstance].status = @"已停止";
|
|
if (_timer) {
|
|
dispatch_source_cancel(_timer);
|
|
_timer = nil;
|
|
}
|
|
// 停止 append 文件定时器
|
|
if (_appendCheckTimer) {
|
|
dispatch_source_cancel(_appendCheckTimer);
|
|
_appendCheckTimer = nil;
|
|
}
|
|
|
|
[[IPhoneHertbeat sharedInstance] stopHeartbeat]; // 确保心跳停止
|
|
[[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(NO)];
|
|
}
|
|
|
|
- (NSString *)getSystemInfo {
|
|
void *buffer = NULL;
|
|
NSString *result = nil;
|
|
|
|
// 设置 sysctl 的 mib 参数
|
|
// 0x100000006LL 拆分为两个 int: {6, 1}
|
|
// 高32位是1 (0x1), 低32位是6 (0x6)
|
|
int mib[2];
|
|
mib[0] = 6; // CTL_HW
|
|
mib[1] = 1; // HW_MACHINE
|
|
|
|
size_t size = 100;
|
|
|
|
// 第一次调用获取实际需要的缓冲区大小
|
|
// #import <sys/sysctl.h>
|
|
sysctl(mib, 2, NULL, &size, NULL, 0);
|
|
|
|
// 分配内存
|
|
buffer = malloc(size);
|
|
|
|
if (buffer != NULL) {
|
|
// 第二次调用获取实际数据
|
|
sysctl(mib, 2, buffer, &size, NULL, 0);
|
|
|
|
// 转换为 NSString
|
|
result = [NSString stringWithUTF8String:(const char *)buffer];
|
|
|
|
// 释放内存
|
|
free(buffer);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
- (void)onChangeInfo:(NSDictionary *)dic {
|
|
NSString* t_idfa = [self getStr:@"idfa" dic:dic];
|
|
if (![XSHelper strIsEmpty:t_idfa]) {
|
|
self->_lastIdfa = [t_idfa copy];
|
|
} else {
|
|
NSLog(@"XS- startTask t_idfa is null");
|
|
return;
|
|
}
|
|
|
|
NSString *_linkId = [self getStr:@"linkId" dic:dic];
|
|
if (![XSHelper strIsEmpty:_linkId]) {
|
|
self->linkId = [_linkId copy];
|
|
}
|
|
NSString *_dataId = [self getStr:@"dataId" dic:dic];
|
|
if (![XSHelper strIsEmpty:_dataId]) {
|
|
self->dataId = [_dataId copy];
|
|
}
|
|
|
|
NSString* t_taskId = [self getStr:@"id" dic:dic];
|
|
if (![XSHelper strIsEmpty:t_taskId]) {
|
|
self->taskId = [t_taskId copy];
|
|
} else {
|
|
NSLog(@"XS- startTask t_taskId is null");
|
|
return;
|
|
}
|
|
NSString* t_taskAppId = [self getStr:@"appId" dic:dic];
|
|
if (![XSHelper strIsEmpty:t_taskAppId]) {
|
|
self->taskAppId = [t_taskAppId copy];
|
|
[IPhoneHertbeat sharedInstance].appId = self->taskAppId;
|
|
} else {
|
|
NSLog(@"XS- startTask t_taskAppId is null");
|
|
return;
|
|
}
|
|
|
|
|
|
__weak typeof(self) weakSelf = self;
|
|
[self restart:^{
|
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
if (!strongSelf) return;
|
|
|
|
void (^saveBlock)(void) = ^{
|
|
if (saveChangeDataFile(dic)) {
|
|
// 成功,执行后续流程
|
|
strongSelf->running = YES;
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC),
|
|
strongSelf.manQueue, ^{
|
|
__strong typeof(weakSelf) strongSelf2 = weakSelf;
|
|
if (!strongSelf2) return;
|
|
[strongSelf2 appRun:strongSelf2->taskAppId];
|
|
});
|
|
} else {
|
|
NSLog(@"XS- saveChangeDataFile failed");
|
|
}
|
|
};
|
|
saveBlock();
|
|
}];
|
|
}
|
|
|
|
- (void)appKill:(NSString*)app {
|
|
NSLog(@"XS- appKill");
|
|
XSKillAppByName(app);
|
|
}
|
|
|
|
- (void)unlock {
|
|
NSLog(@"XS- unlock");
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
XSRemoteUnlock();
|
|
});
|
|
}
|
|
|
|
- (void)resetApp:(NSString*)appId callback:(OnEndCallback)callback {
|
|
NSLog(@"XS- JSApi resetApp");
|
|
NSString *appInfoPath = XSGetAppInfoPath(appId);
|
|
NSDictionary *appInfo = XSGetAppInfo(appInfoPath);
|
|
id bfaceDictKey = appInfo[@"bfaceDictKey"];
|
|
NSMutableDictionary *tempBfaceDictKey = nil;
|
|
if(bfaceDictKey) {
|
|
tempBfaceDictKey = [NSMutableDictionary dictionaryWithDictionary:bfaceDictKey];
|
|
} else {
|
|
tempBfaceDictKey = [[NSMutableDictionary alloc] init];
|
|
}
|
|
NSString *serverUrl = [[XSPhoneConfig sharedInstance] ServerURL];
|
|
BOOL washParam = [[XSPhoneConfig sharedInstance] WashParam];
|
|
[tempBfaceDictKey setValue:serverUrl forKey:@"adbrush_base_url"];
|
|
[tempBfaceDictKey setValue:@(washParam) forKey:@"washParam"];
|
|
// [tempBfaceDictKey setValue:lowEcpm forKey:@"adbrush_ecpm"];
|
|
if(self->linkId) {
|
|
[tempBfaceDictKey setValue:self->linkId forKey:@"linkId"];
|
|
} else {
|
|
NSString *linkId = [[NSUUID UUID] UUIDString];
|
|
[tempBfaceDictKey setValue:linkId forKey:@"linkId"];
|
|
}
|
|
|
|
if(self->dataId) {
|
|
[tempBfaceDictKey setValue:self->dataId forKey:@"dataId"];
|
|
} else {
|
|
[tempBfaceDictKey setValue:@"0" forKey:@"dataId"];
|
|
}
|
|
if(self->remoteIp) {
|
|
[tempBfaceDictKey setValue:self->remoteIp forKey:@"remoteIp"];
|
|
}
|
|
uint16_t udp_port = [XUDPServer sharedInstance].udp_port;
|
|
[tempBfaceDictKey setValue:@(udp_port) forKey:@"udp_port"];
|
|
[tempBfaceDictKey setValue:[self getSystemInfo] forKey:@"device_model"];
|
|
|
|
NSLog(@"XS- resetApp 1");
|
|
NSMutableDictionary *tempAppInfo = [[NSMutableDictionary alloc] init];
|
|
[tempAppInfo setValue:tempBfaceDictKey forKey:@"bfaceDictKey"];
|
|
|
|
XSClearAll(appId);
|
|
|
|
XSSaveAppInfo(tempAppInfo, appInfoPath);
|
|
callback();
|
|
|
|
}
|
|
|
|
- (NSString *)frontMostAppId {
|
|
return XSFrontMostAppId();
|
|
}
|
|
|
|
- (void)appRun:(NSString *)appId {
|
|
if ([XSHelper strIsEmpty:appId]) return;
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
@try {
|
|
bringAppToForeground(appId);
|
|
} @catch (NSException *exception) {
|
|
NSLog(@"Error bringing app to foreground: %@", exception);
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
- (void)restart:(OnEndCallback)callback {
|
|
@synchronized (self) {
|
|
__weak typeof(self) weakSelf = self;
|
|
dispatch_async(self.manQueue, ^{
|
|
@try {
|
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
if (!strongSelf) return;
|
|
|
|
[weakSelf appKill:@"com.apple.AppStore"];
|
|
[weakSelf appKill:@"com.apple.mobilesafari"];
|
|
if (strongSelf->taskAppId && ![strongSelf->taskAppId isEqual:[NSNull null]] && [strongSelf->taskAppId length] > 0) {
|
|
[weakSelf appKill:strongSelf->taskAppId];
|
|
[weakSelf unlock];
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), strongSelf.manQueue, ^{
|
|
[weakSelf unlock];
|
|
[weakSelf resetApp:strongSelf->taskAppId callback:callback];
|
|
});
|
|
}
|
|
} @catch (NSException *exception) {
|
|
NSLog(@"Error in restart: %@", exception);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
- (void)rndTouchApp {
|
|
int times = [XSHelper random:2 and:4];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*)getStr:(NSString *)key dic:(NSDictionary*)dic {
|
|
NSLog(@"getStr: %@", key);
|
|
id t_idfa = dic[key];
|
|
if (t_idfa && ![t_idfa isEqual:[NSNull null]] && ![t_idfa isEqual:@""]) {
|
|
return [NSString stringWithFormat:@"%@", t_idfa];
|
|
} else {
|
|
NSLog(@"XS- dic %@ is null", key);
|
|
return @"";
|
|
}
|
|
}
|
|
|
|
- (NSNumber*)getNum:(NSString *)key dic:(NSDictionary*)dic {
|
|
NSLog(@"getNum: %@", key);
|
|
id t_idfa = dic[key];
|
|
NSString *ecpm_str = [NSString stringWithFormat:@"%@", t_idfa];
|
|
|
|
NSNumber *ecpm = @0.0;
|
|
|
|
if (ecpm_str && ![ecpm_str isEqual:[NSNull null]] && ![ecpm_str isEqual:@""]) {
|
|
ecpm = [XSHelper str2num:ecpm_str];
|
|
}
|
|
return ecpm;
|
|
}
|
|
|
|
- (int)getInt:(NSString *)key dic:(NSDictionary*)dic {
|
|
NSLog(@"getInt: %@", key);
|
|
id t_idfa = dic[key];
|
|
NSString *ecpm_str = [NSString stringWithFormat:@"%@", t_idfa];
|
|
|
|
NSNumber *ecpm = @(-99);
|
|
|
|
if (ecpm_str && ![ecpm_str isEqual:[NSNull null]] && ![ecpm_str isEqual:@""]) {
|
|
ecpm = [XSHelper str2num:ecpm_str];
|
|
}
|
|
return [ecpm intValue];
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[self stop];
|
|
}
|
|
|
|
@end |