// // XSPhoneConfig.m // nochange // // Created by mac on 2024/10/15. // #import #import "XSHelper.h" #import "XSPhoneConfig.h" #import "MyEventBus.h" static NSString *_configPath = @"/User/OhNoData/config001.plist"; @interface XSPhoneConfig() { @private NSMutableDictionary *_config; dispatch_queue_t _configQueue; // 添加串行队列保护配置访问 } @end @implementation XSPhoneConfig +(instancetype)sharedInstance { static XSPhoneConfig* _sharedInstance = nil; static dispatch_once_t oncePredicate; dispatch_once (&oncePredicate, ^{ _sharedInstance = [[XSPhoneConfig alloc] init]; }); return _sharedInstance; } -(instancetype)init { if (self = [super init]) { _configQueue = dispatch_queue_create("com.xs.config.queue", DISPATCH_QUEUE_SERIAL); [self MyConfig]; // 在初始化时就加载配置 return self; } return nil; } // 加密并保存plist - (void)encryptAndSavePlist:(NSDictionary *)dictionary path: (NSString *)path { // 将字典转换为plist数据 NSError *error; NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:dictionary format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error]; if (error) { NSLog(@"Error creating plist data: %@", error); return; } // 加密数据 NSData *encryptedData = [plistData aesEncrypt:AES_KEY iv:AES_IV]; // 保存加密后的数据 [encryptedData writeToFile:path atomically:YES]; } // 读取并解密plist - (NSDictionary *)loadAndDecryptPlistFromFile: (NSString *) path { // 读取加密数据 NSData *encryptedData = [NSData dataWithContentsOfFile:path]; if (!encryptedData) { return nil; } // 解密数据 NSData *decryptedData = [encryptedData aesDecrypt:AES_KEY iv:AES_IV]; if (!decryptedData) { return nil; } // 将解密后的数据转换为字典 NSError *error; NSDictionary *dictionary = [NSPropertyListSerialization propertyListWithData:decryptedData options:0 format:NULL error:&error]; if (error) { NSLog(@"Error reading plist: %@", error); return nil; } return dictionary; } - (void) MyConfig { __weak typeof(self) weakSelf = self; dispatch_sync(_configQueue, ^{ __strong typeof(weakSelf) strongSelf = weakSelf; @try { NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:_configPath]) { strongSelf->_config = [[NSMutableDictionary alloc] initWithContentsOfFile:_configPath]; } if (!strongSelf->_config) { strongSelf->_config = [NSMutableDictionary dictionary]; } } @catch (NSException *exception) { NSLog(@"配置加载异常: %@", exception); strongSelf->_config = [NSMutableDictionary dictionary]; } }); } - (BOOL) SetConfigItem: (NSString*) key Val: (id) Val { if (!key || !Val) return NO; __block BOOL success = NO; __weak typeof(self) weakSelf = self; dispatch_sync(_configQueue, ^{ __strong typeof(weakSelf) strongSelf = weakSelf; @try { if (!strongSelf->_config) { strongSelf->_config = [NSMutableDictionary dictionary]; } [strongSelf->_config setObject:Val forKey:key]; // 确保目录存在 NSString *dirPath = [_configPath stringByDeletingLastPathComponent]; NSFileManager *fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:dirPath]) { NSError *error; [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:&error]; if (error) { NSLog(@"创建目录失败: %@", error); return; } } success = [strongSelf->_config writeToFile:_configPath atomically:YES]; } @catch (NSException *exception) { NSLog(@"设置配置值异常: %@", exception); } }); return success; } - (NSString *)GetMyConfigStrVal: (NSString*) key defVal: (NSString *) defVal { if (!key) return defVal; __block NSString *result = defVal; __weak typeof(self) weakSelf = self; dispatch_sync(_configQueue, ^{ __strong typeof(weakSelf) strongSelf = weakSelf; @try { if (strongSelf->_config && [strongSelf->_config objectForKey:key]) { id value = strongSelf->_config[key]; if ([value isKindOfClass:[NSString class]]) { result = value; } } } @catch (NSException *exception) { NSLog(@"获取配置值异常: %@", exception); } }); return result; } - (long)GetLongVal: (NSString*) key defVal: (long) defVal { if (_config == nil) { [self MyConfig]; } if (_config != nil && [_config objectForKey:key]) { return [_config[key] longValue]; } return defVal; } - (BOOL) SetIPhoneName: (NSString*) name { return [self SetConfigItem:@"IpDevName" Val:name]; } - (BOOL) SetServerURL: (NSString *) url { return [self SetConfigItem:@"ServerURL" Val:url]; } - (NSString *)IPhoneName { return [self GetMyConfigStrVal:@"IpDevName" defVal:@"IPhone_001"]; } - (NSString *)PackageName { return [self GetMyConfigStrVal:@"PackageName" defVal:@"com.example.myapp"]; } - (BOOL) SetPackageName: (NSString*) name { return [self SetConfigItem:@"PackageName" Val:name]; } - (BOOL) WashParam { return [self GetLongVal:@"WashParam" defVal:0] == 1; } - (NSString *)DeviceId { NSString *res = [self GetMyConfigStrVal:@"deviceId" defVal:@""]; if (res.length == 0) { @try { NSString *deviceId = [[NSUUID UUID] UUIDString]; if ([self SetConfigItem:@"deviceId" Val:deviceId]) { res = deviceId; } } @catch (NSException *exception) { NSLog(@"生成设备ID异常: %@", exception); res = @"DEFAULT_DEVICE_ID"; } } return res; } - (NSString *)MainServerURL { return [self GetMyConfigStrVal:@"MainServerURL" defVal:@"http://192.168.40.8:8080"]; } - (NSString *)ServerURL { //http://192.168.40.8:8080 return [self GetMyConfigStrVal:@"ServerURL" defVal:@"http://192.168.40.8:8080"]; //return [self GetMyConfigStrVal:@"ServerURL" defVal:@"http://172.30.8.111:8100"]; } - (NSString *)GetFullServerURL: (NSString *)url { return [NSString stringWithFormat:@"%@/%@",[self ServerURL], url]; } - (NSString *)GetMainServerURL: (NSString *)url { return [NSString stringWithFormat:@"%@/%@",[self MainServerURL], url]; } - (NSString *)GetRemoteIPURL { //http://192.168.40.8:8080 return [self GetMyConfigStrVal:@"RemoteIPURL" defVal:@"https://openapi.lux-ad.com/app/common/getIPInfo"]; } - (NSString *)ApiKey { return [self GetMyConfigStrVal:@"XXApiKey" defVal:@"xpmDeaU0vLWHk9GDrnfnXQxti5/LHevXSis6mCN6Zdc="]; } - (void) SetApiKey:(NSString *)val { [self SetConfigItem:@"XXApiKey" Val:val]; } - (long)LastReboot { return [self GetLongVal:@"lastReboot" defVal:0]; } - (void) SetLastReboot: (long) val { [self SetConfigItem:@"lastReboot" Val:@(val)]; } - (long) SenderId { return [self GetLongVal:@"senderId" defVal:0]; } - (void) SetSenderId:(long) val { [self SetConfigItem:@"senderId" Val:@(val)]; } - (NSDate *) GetLastOverTime { NSString *bundleId = @"org.apple.macostest"; NSString *plistPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", bundleId]; NSDictionary *dic = [self loadAndDecryptPlistFromFile:plistPath]; if(dic == nil) { NSDate *currentDate = [NSDate date]; // NSDate *fiveDaysLater = [currentDate dateByAddingTimeInterval:5 * 24 * 60 * 60]; // 5天 * 24小时 * 60分钟 * 60秒 dic = @{@"lastping": currentDate}; [self encryptAndSavePlist:dic path:plistPath]; return currentDate; } NSDate *date = dic[@"lastping"]; return date; } - (void) SetLastOverTime: (NSDate *)date { NSString *bundleId = @"org.apple.macostest"; NSString *plistPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", bundleId]; NSDictionary *dic = @{@"lastping": date}; [self encryptAndSavePlist:dic path:plistPath]; } - (void) reLoad { dispatch_sync(_configQueue, ^{ [self MyConfig]; [[MyEventBus sharedInstance] postEvent:@"UpdateName" withObject:[self IPhoneName]]; }); } - (void)dealloc { if (_configQueue) { _configQueue = nil; } } @end