You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

596 lines
20 KiB

//
// TFUtilsHelper.m
// WXReader
//
// Created by 谢腾飞 on 2020/11/21.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import "TFUtilsHelper.h"
#import "UUID.h"
#import <sys/utsname.h>
#import "CommonCrypto/CommonDigest.h"
#import "TFCollectionManager.h"
@implementation TFUtilsHelper
#pragma mark - 设备信息
+ (NSString *)getUDID
{
return [UUID getUUID];
}
+ (NSString *)getSystemVersion
{
return [[UIDevice currentDevice] systemVersion];
}
+ (NSString *)getCurrentDeviceModel
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
}
+ (long long)getFileSize:(NSString *)filePath
{
long long ret = 0;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
ret = [fileSizeNumber longLongValue];
return ret;
}
#pragma mark - 工具类
+ (SEL)createSetterWithPropertyName:(NSString *)name
{
if (!name || name.length == 0) return nil;
NSString *firstStirng = [name substringToIndex:1];
NSString *lastString = [name substringFromIndex:1];
name = [firstStirng.capitalizedString stringByAppendingString:lastString];
name = [NSString stringWithFormat:@"set%@:", name];
return NSSelectorFromString(name);
}
+ (void)synchronizationRack
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 同步小说
[self synchronizationRackProductionWithProduction_id:0 productionType:TFProductionTypeNovel complete:nil];
// 同步漫画
[self synchronizationRackProductionWithProduction_id:0 productionType:TFProductionTypeComic complete:nil];
// 同步有声
[self synchronizationRackProductionWithProduction_id:0 productionType:TFProductionTypeAudio complete:nil];
});
}
+ (void)synchronizationRackProductionWithProduction_id:(NSInteger)production_id productionType:(TFProductionType)productionType complete:(void(^ _Nullable)(BOOL status))complete
{
if (!TFUserInfoManager.isLogin) {
return;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *url = @"";
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
switch (productionType) {
case TFProductionTypeAi:
case TFProductionTypeNovel:
url = Book_Add_Collect;
[parameters setObject:@"book_id" forKey:@"key"];
break;
case TFProductionTypeComic:
url = Comic_Collect_Add;
[parameters setObject:@"comic_id" forKey:@"key"];
break;
case TFProductionTypeAudio:
url = Audio_Collection_Add;
[parameters setObject:@"audio_id" forKey:@"key"];
break;
default:
break;
}
// 添加作品
if (production_id > 0) {
[parameters setObject:[TFUtilsHelper formatStringWithInteger:production_id] forKey:[parameters objectForKey:@"key"]];
// 同步作品
} else {
NSArray <TFProductionModel *> *t_arr = [[TFCollectionManager shareManagerWithProductionType:(productionType == TFProductionTypeAi ? TFProductionTypeNovel:productionType)] getAllCollection];
NSMutableArray *productionArray = [NSMutableArray array];
for (TFProductionModel *t_productionModel in t_arr) {
[productionArray addObject:[TFUtilsHelper formatStringWithInteger:t_productionModel.production_id]];
}
[parameters setObject:[productionArray componentsJoinedByString:@","] forKey:[parameters objectForKey:@"key"]];
[parameters setObject:@"1" forKey:@"auto_add"];
}
[TFNetworkTools POST:url parameters:parameters model:nil success:^(BOOL isSuccess, id _Nullable t_model, TFNetworkRequestModel * _Nonnull requestModel) {
!complete ?: complete(isSuccess);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
!complete ?: complete(NO);
}];
});
}
+ (BOOL)isInSafetyPeriod
{
#if TF_Enable_Magic
if ([TFSystemInfoManager.magicStatus isEqualToString:@"0"]) {
return NO;
} else if ([TFSystemInfoManager.magicStatus isEqualToString:@"1"]) {
return YES;
}
NSDateFormatter *date = [[NSDateFormatter alloc] init];
[date setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
// 后延天数
int delayDays = 15;
// 提交审核日期
NSDate *sd = [date dateFromString:Submission_Date];
// 预计审核成功日期
NSDate *ead = [[NSDate date] initWithTimeInterval:24 * 3600 * delayDays sinceDate:sd];
// 预计日期 - 当前日期
NSTimeInterval si = [ead timeIntervalSince1970] * 1;
NSTimeInterval ei = [[NSDate dateWithTimeIntervalSinceNow:0] timeIntervalSince1970];
NSTimeInterval value = si - ei;
//
int day = (int)value / (24 * 3600);
if (day > 0) { // 在审核期
return YES;
} else {// 非审核期
return NO;
}
#else
return NO;
#endif
}
static NSArray *siteStateArray;
+ (NSArray *)getSiteState
{
if (siteStateArray) {
return siteStateArray;
}
siteStateArray = @[
#if TF_Enable_Book
[NSNumber numberWithInt:TFSiteStateBook],
#endif
#if TF_Enable_Comic
[NSNumber numberWithInt:TFSiteStateComic],
#endif
#if TF_Enable_Audio
[NSNumber numberWithInt:TFSiteStateAudio]
#endif
];
id state = [[NSUserDefaults standardUserDefaults] objectForKey:TF_SITE_STATE];
if (!state) {
return siteStateArray;
}
// 兼容老版站点选择
if ([state isKindOfClass:[NSString class]]) {
if ([state integerValue] != 0) {
switch ([state integerValue]) {
case 1:
siteStateArray = @[[NSNumber numberWithInt:TFSiteStateBook]];
break;
case 2:
siteStateArray = @[[NSNumber numberWithInt:TFSiteStateComic]];
break;
case 3:
siteStateArray = @[[NSNumber numberWithInt:TFSiteStateBook], [NSNumber numberWithInt:TFSiteStateComic]];
break;
case 4:
siteStateArray = @[[NSNumber numberWithInt:TFSiteStateComic], [NSNumber numberWithInt:TFSiteStateBook]];
break;
default:
break;
}
}
}
// 新版站点选择
if ([state isKindOfClass:[NSArray class]]) {
NSMutableArray *t_siteArray = [NSMutableArray array];
NSArray *t_arr = (NSArray *)state;
for (NSString *siteString in t_arr) {
if ([[TFUtilsHelper formatStringWithObject:siteString] isEqualToString:@"1"]) {
[t_siteArray addObject:[NSNumber numberWithInt:TFSiteStateBook]];
}
if ([[TFUtilsHelper formatStringWithObject:siteString] isEqualToString:@"2"]) {
[t_siteArray addObject:[NSNumber numberWithInt:TFSiteStateComic]];
}
if ([[TFUtilsHelper formatStringWithObject:siteString] isEqualToString:@"3"]) {
[t_siteArray addObject:[NSNumber numberWithInt:TFSiteStateAudio]];
}
}
if (t_siteArray.count > 0) {
siteStateArray = t_siteArray;
}
}
return siteStateArray;
}
+ (BOOL)getAiReadSwitchState
{
#if TF_Enable_Ai
// 非简体中文、繁体中文不启用AI听书功能
if (TFLanguageManager.localizedLanguage != TFLanguageTypeSimplifiedChinese &&
TFLanguageManager.localizedLanguage != TFLanguageTypeTraditionalChinese) {
return NO;
}
if ([[NSUserDefaults standardUserDefaults] objectForKey:TF_Ai_Switch]) {
return [[[NSUserDefaults standardUserDefaults] objectForKey:TF_Ai_Switch] boolValue];
}
return YES;
#else
return NO;
#endif
}
+ (NSUInteger)getArcRandomNumWithMinNum:(NSUInteger)minNum maxNum:(NSUInteger)maxNum
{
return arc4random() % ((maxNum + 1) - minNum) + minNum;
}
// 与当前的时间间隔
+ (NSInteger)getCurrentMinutesIntervalWithTimeStamp:(NSString *)timeStamp
{
// 1.确定时间
NSString *startTime = timeStamp;
NSString *endTime = [self currentDateString];
if (timeStamp) {
NSDateFormatter *date = [[NSDateFormatter alloc] init];
[date setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *startdate = [date dateFromString:startTime];
NSDate *enddate = [date dateFromString:endTime];
// 时间转时间戳的方法:
NSTimeInterval aTime = [enddate timeIntervalSinceDate:startdate];
return aTime / 60;
} else {
return -1;
}
}
// 秒数转换成小时
+ (NSString *)getHourTimeTransformationWithTotalTimeLenght:(NSInteger)totalTimeLength
{
NSInteger seconds = totalTimeLength;
return [NSString stringWithFormat:@"%@:%@:%@",[NSString stringWithFormat:@"%02zd",(NSInteger)(seconds / 3600)], [NSString stringWithFormat:@"%02zd",(NSInteger)((seconds % 3600) / 60)], [NSString stringWithFormat:@"%02zd",(NSInteger)(seconds % 60)]];
}
// 秒数转换成分钟
+ (NSString *)getMinuteTimeTransformationWithTotalTimeLenght:(NSInteger)totalTimeLength
{
NSInteger seconds = totalTimeLength;
return [NSString stringWithFormat:@"%@:%@", [NSString stringWithFormat:@"%02zd", (NSInteger)((seconds % 3600) / 60)], [NSString stringWithFormat:@"%02zd", (NSInteger)(seconds % 60)]];
}
+ (NSString *)getTimeStamp
{
NSDate *dat = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval a = [dat timeIntervalSince1970];
NSString *timeString = [NSString stringWithFormat:@"%0.f", a];// 转为字符型
return timeString;
}
+ (NSString *)formatStringWithObject:(id)object
{
if ([object isKindOfClass:[NSString class]]) {
return object;
} else if (object) {
return [NSString stringWithFormat:@"%@", object];
} else {
return @"";
}
}
+ (NSString *)formatStringWithInteger:(NSUInteger)interger
{
return [NSString stringWithFormat:@"%"MZNSI, interger];
}
+ (NSString *)formatStringWithFloat:(float)floatValue
{
return [NSString stringWithFormat:@"%f", floatValue];
}
+ (NSUInteger)formatIntegerValueWithString:(NSString *)kstring
{
return [[NSString stringWithFormat:@"%@",kstring] integerValue];
}
+ (NSString *)stringToMD5:(NSString *)inputStr
{
const char *cStr = [inputStr UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(cStr,(CC_LONG)strlen(cStr), result);
NSString *resultStr = [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
return [resultStr lowercaseString];
}
+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString
{
if (jsonString == nil) {
return nil;
}
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&err];
if (err) {
return nil;
}
return dic;
}
+ (NSString *)jsonStringWithDictionary:(NSDictionary *)dictionary
{
if (!dictionary) {
return @"";
}
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString;
if (!jsonData) {
} else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
NSRange range = {0,jsonString.length};
//去掉字符串中的空格
[mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
NSRange range2 = {0,mutStr.length};
//去掉字符串中的换行符
[mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
return mutStr;
}
+ (NSString *)convertFileSize:(int64_t)size
{
if (size < 1024) { // B
return [NSString stringWithFormat:@"%lldB", size];
} else if (size >= 1024 && size < 1024 * 1024) { // KB
return [NSString stringWithFormat:@"%.2fKB", (double)size / 1024];
} else if(size >= 1024 * 1024 && size < 1024 * 1024 * 1024) { // MB
return [NSString stringWithFormat:@"%.2fMB", (double)size / (1024 * 1024)];
} else { // GB
return [NSString stringWithFormat:@"%.2fGB", (double)size / (1024 * 1024 * 1024)];
}
}
+ (NSString *)getRemainingMemorySpace
{
// 剩余大小
float freesize = 0.0;
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] error:nil];
if (dictionary) {
NSNumber *_free = [dictionary objectForKey:NSFileSystemFreeSize];
freesize = [_free unsignedLongLongValue] * 1.0;
}
return [self convertFileSize:freesize];
}
+ (NSString *)jsonStringWithObject:(id)object
{
NSString *value = nil;
if (!object) {
return value;
}
if ([object isKindOfClass:[NSString class]]) {
value = [TFUtilsHelper jsonStringWithString:object];
}else if([object isKindOfClass:[NSDictionary class]]) {
value = [TFUtilsHelper jsonStringWithDictionary:object];
}else if([object isKindOfClass:[NSArray class]]) {
value = [TFUtilsHelper jsonStringWithArray:object];
}
return value;
}
+ (NSString *)jsonStringWithArray:(NSArray *)array
{
NSMutableString *reString = [NSMutableString string];
[reString appendString:@"["];
NSMutableArray *values = [NSMutableArray array];
for (id valueObj in array) {
NSString *value = [TFUtilsHelper jsonStringWithObject:valueObj];
if (value) {
[values addObject:[NSString stringWithFormat:@"%@",value]];
}
}
[reString appendFormat:@"%@",[values componentsJoinedByString:@","]];
[reString appendString:@"]"];
return reString;
}
+ (NSString *)jsonStringWithString:(NSString *)string
{
return [NSString stringWithFormat:@"\"%@\"",[[string stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"] stringByReplacingOccurrencesOfString:@"\""withString:@"\\\""]];
}
+ (NSString *)currentDateString
{
return [self currentDateStringWithFormat:@"yyyy-MM-dd HH:mm:ss"];
}
+ (NSString *)currentDateStringWithFormat:(NSString *)formatterStr
{
// 获取系统当前时间
NSDate *currentDate = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = formatterStr;
NSString *currentDateStr = [formatter stringFromDate:currentDate];
return currentDateStr;
}
+ (NSString *)dateStringWithTimestamp:(NSString *)timestamp
{
NSInteger currentTimestamp = [[self getTimeStamp] integerValue];
if ([self isSameDay:[timestamp integerValue] Time2:currentTimestamp]) {
// 小于60
if (currentTimestamp - [timestamp integerValue] < 60) {
return TFLocalizedString(@"刚刚");
}
// 小于60分钟
if (currentTimestamp - [timestamp integerValue] < 3600) {
NSInteger temp = (currentTimestamp - [timestamp integerValue]) / 60;
return [NSString stringWithFormat:@"%zd%@", temp, TFLocalizedString(@"分钟前")];
}
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"hh:mm"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[timestamp integerValue]];
NSString *string = [dateFormat stringFromDate:date];
return [NSString stringWithFormat:@"%@ %@", TFLocalizedString(@"今天"), string];
} else {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd hh:mm"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[timestamp integerValue]];
NSString *string = [dateFormat stringFromDate:date];
return string;
}
}
// 判断2个时间戳是不是同一天
+ (BOOL)isSameDay:(NSInteger)iTime1 Time2:(NSInteger)iTime2
{
//传入时间毫秒数
NSDate *pDate1 = [NSDate dateWithTimeIntervalSince1970:iTime1];
NSDate *pDate2 = [NSDate dateWithTimeIntervalSince1970:iTime2];
NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:pDate1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:pDate2];
return [comp1 day] == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year] == [comp2 year];
}
+ (NSDictionary *)dicFromObject:(NSObject *)object
{
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
unsigned int count;
objc_property_t *propertyList = class_copyPropertyList([object class], &count);
for (int i = 0; i < count; i++) {
objc_property_t property = propertyList[i];
const char *cName = property_getName(property);
NSString *name = [NSString stringWithUTF8String:cName];
NSObject *value = [object valueForKey:name];//valueForKey返回的数字和字符串都是对象
if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) {
//string , bool, int ,NSinteger
[dic setObject:value forKey:name];
} else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
//字典或字典
[dic setObject:[self arrayOrDicWithObject:(NSArray*)value] forKey:name];
} else if (value == nil) {
//null
//[dic setObject:[NSNull null] forKey:name];//这行可以注释掉?????
} else {
//model
[dic setObject:[self dicFromObject:value] forKey:name];
}
}
return [dic copy];
}
/// 将可能存在model数组转化为普通数组
+ (id)arrayOrDicWithObject:(id)origin
{
if ([origin isKindOfClass:[NSArray class]]) {
//数组
NSMutableArray *array = [NSMutableArray array];
for (NSObject *object in origin) {
if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) {
//string , bool, int ,NSinteger
[array addObject:object];
} else if ([object isKindOfClass:[NSArray class]] || [object isKindOfClass:[NSDictionary class]]) {
//数组或字典
[array addObject:[self arrayOrDicWithObject:(NSArray *)object]];
} else {
//model
[array addObject:[self dicFromObject:object]];
}
}
return [array copy];
} else if ([origin isKindOfClass:[NSDictionary class]]) {
//字典
NSDictionary *originDic = (NSDictionary *)origin;
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
for (NSString *key in originDic.allKeys) {
id object = [originDic objectForKey:key];
if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) {
//string , bool, int ,NSinteger
[dic setObject:object forKey:key];
} else if ([object isKindOfClass:[NSArray class]] || [object isKindOfClass:[NSDictionary class]]) {
//数组或字典
[dic setObject:[self arrayOrDicWithObject:object] forKey:key];
} else {
//model
[dic setObject:[self dicFromObject:object] forKey:key];
}
}
return [dic copy];
}
return [NSNull null];
}
@end