MOTools.m 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. //
  2. // MOTools.m
  3. // MiMoLive
  4. //
  5. // Created by SuperC on 2023/10/9.
  6. //
  7. #import "MOTools.h"
  8. #import <UIKit/UIKit.h>
  9. #import <AdSupport/AdSupport.h>
  10. #import <SystemConfiguration/CaptiveNetwork.h>
  11. #import <sys/utsname.h>//要导入头文件
  12. #import "UIImage+YYAdd.h"
  13. #define kShowBindTime @"k_show_bing_phone_alert_time"
  14. #define kShowSignTime @"k_show_sign_alert_time"
  15. @implementation MOTools
  16. + (UIColor *)colorWithHexString:(NSString *)hexString {
  17. return [self colorWithHexString:hexString alpha:1.0];
  18. }
  19. + (UIColor *)colorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha
  20. {
  21. if (hexString == nil)
  22. {
  23. return nil;
  24. }
  25. hexString = [hexString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
  26. hexString = [hexString stringByReplacingOccurrencesOfString:@"#" withString:@""];
  27. hexString = [hexString stringByReplacingOccurrencesOfString:@"0x" withString:@""];
  28. NSRegularExpression *RegEx = [NSRegularExpression regularExpressionWithPattern:@"^[a-fA-F|0-9]{6}$" options:0 error:nil];
  29. NSUInteger match = [RegEx numberOfMatchesInString:hexString options:NSMatchingReportCompletion range:NSMakeRange(0, hexString.length)];
  30. if (match == 0)
  31. {
  32. return [UIColor clearColor];
  33. }
  34. NSString *rString = [hexString substringWithRange:NSMakeRange(0, 2)];
  35. NSString *gString = [hexString substringWithRange:NSMakeRange(2, 2)];
  36. NSString *bString = [hexString substringWithRange:NSMakeRange(4, 2)];
  37. unsigned int r, g, b;
  38. BOOL rValue = [[NSScanner scannerWithString:rString] scanHexInt:&r];
  39. BOOL gValue = [[NSScanner scannerWithString:gString] scanHexInt:&g];
  40. BOOL bValue = [[NSScanner scannerWithString:bString] scanHexInt:&b];
  41. if (rValue && gValue && bValue)
  42. {
  43. return [UIColor colorWithRed:((float)r/255.0f) green:((float)g/255.0f) blue:((float)b/255.0f) alpha:alpha];
  44. }
  45. else
  46. {
  47. return [UIColor clearColor];
  48. }
  49. }
  50. + (CGFloat)calculateRowHeight:(NSString *)string fontSize:(NSInteger)fontSize andWidth:(CGFloat)width
  51. {
  52. NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
  53. paragraphStyle.lineSpacing = 5;
  54. NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize],NSParagraphStyleAttributeName:paragraphStyle};//指定字号
  55. CGRect rect = [string boundingRectWithSize:CGSizeMake(width, MAXFLOAT)/*计算高度要先指定宽度*/ options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil];
  56. return (rect.size.height+1);
  57. }
  58. + (CGFloat)calculateRowHeight:(NSString *)string font:(UIFont *)font andWidth:(CGFloat)width
  59. {
  60. NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
  61. paragraphStyle.lineSpacing = 5;
  62. NSDictionary *dic = @{NSFontAttributeName:font,NSParagraphStyleAttributeName:paragraphStyle};//指定字号
  63. CGRect rect = [string boundingRectWithSize:CGSizeMake(width, MAXFLOAT)/*计算高度要先指定宽度*/ options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil];
  64. return (rect.size.height+1);
  65. }
  66. + (CGFloat)calculateRowHeightNoLine:(NSString *)string font:(UIFont *)font andWidth:(CGFloat)width
  67. {
  68. NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
  69. paragraphStyle.lineSpacing = 1.0;
  70. NSDictionary *dic = @{NSFontAttributeName:font,NSParagraphStyleAttributeName:paragraphStyle};//指定字号
  71. CGRect rect = [string boundingRectWithSize:CGSizeMake(width, MAXFLOAT)/*计算高度要先指定宽度*/ options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil];
  72. return (rect.size.height+1);
  73. }
  74. + (CGFloat)calculateRowHeightNoLineSpacing:(NSString *)string fontSize:(NSInteger)fontSize andWidth:(CGFloat)width
  75. {
  76. NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};//指定字号
  77. CGRect rect = [string boundingRectWithSize:CGSizeMake(width, MAXFLOAT)/*计算高度要先指定宽度*/ options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil];
  78. return (rect.size.height+1);
  79. }
  80. + (CGFloat)getWidthWithString:(NSString *)string font:(UIFont *)font
  81. {
  82. NSDictionary *attrs = @{NSFontAttributeName:font};
  83. CGFloat width = [string boundingRectWithSize:CGSizeZero options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size.width;
  84. return width;
  85. }
  86. //获取文字的尺寸
  87. + (CGSize)getSizeFrom:(NSString *)content font:(UIFont *)font maxSize:(CGSize)maxSize{
  88. if (!font || !content) {
  89. return CGSizeZero;
  90. }
  91. CGSize inSize = CGSizeZero;
  92. NSDictionary *attrs = @{NSFontAttributeName: font};
  93. CGSize nameMaxSize = maxSize;//最大宽高
  94. CGRect frame =[content boundingRectWithSize:nameMaxSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attrs context:nil];//options设置两个参数比较准确,NSStringDrawingTruncatesLastVisibleLine,如果文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。如果没有指定NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略
  95. inSize = CGSizeMake(ceilf(frame.size.width), ceilf(frame.size.height));
  96. if (!isnormal(inSize.width)) {
  97. inSize.width = 0.0;
  98. }
  99. return inSize;
  100. }
  101. + (UIImage*)createImageWithColor:(UIColor*)color
  102. {
  103. CGRect rect=CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
  104. UIGraphicsBeginImageContext(rect.size);
  105. CGContextRef context = UIGraphicsGetCurrentContext();
  106. CGContextSetFillColorWithColor(context, [color CGColor]);
  107. CGContextFillRect(context, rect);
  108. UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
  109. UIGraphicsEndImageContext();
  110. return theImage;
  111. }
  112. /**
  113. * 绘制渐变色的矩形UIImage
  114. *
  115. * @param bounds UIImage的bounds
  116. * @param colors 渐变色数组,可以设置两种颜色
  117. * @param gradientType 渐变的方式:0:水平渐变 1:竖直渐变 2:向下对角线渐变 3:向上对角线渐变
  118. *
  119. * @return 渐变色的UIImage
  120. */
  121. + (UIImage*)createGradientRectImageWithBounds:(CGRect)bounds
  122. Colors:(NSArray*)colors
  123. GradientType:(int)gradientType{
  124. NSMutableArray *cgcolorArr = [NSMutableArray array];
  125. for(UIColor *col in colors) {
  126. [cgcolorArr addObject:(id)col.CGColor];
  127. }
  128. UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 1);
  129. CGContextRef context = UIGraphicsGetCurrentContext();
  130. CGContextSaveGState(context);
  131. CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
  132. CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)cgcolorArr, NULL);
  133. CGPoint startPoint = CGPointMake(0.0, 0.0);
  134. if (gradientType == 3) {
  135. startPoint = CGPointMake(0.0, bounds.size.height);
  136. }
  137. CGPoint endPoint = CGPointZero;
  138. switch (gradientType) {
  139. case 0:
  140. endPoint = CGPointMake(bounds.size.width, 0.0);
  141. break;
  142. case 1:
  143. endPoint = CGPointMake(0.0, bounds.size.height);
  144. break;
  145. case 2:
  146. endPoint = CGPointMake(bounds.size.width, bounds.size.height);
  147. break;
  148. case 3:
  149. endPoint = CGPointMake(bounds.size.width, 0.0);
  150. break;
  151. default:
  152. break;
  153. }
  154. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
  155. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  156. CGGradientRelease(gradient);
  157. CGContextRestoreGState(context);
  158. CGColorSpaceRelease(colorSpace);
  159. UIGraphicsEndImageContext();
  160. return image;
  161. }
  162. + (NSArray *)sortArrayByPinYin:(NSArray *)oldArray objectTextKeyPath:(NSString *)keyPath
  163. {
  164. if (oldArray == nil)
  165. {
  166. return nil;
  167. }
  168. else if (oldArray.count > 0)
  169. {
  170. id object = oldArray[0];
  171. if ([object isKindOfClass:[NSString class]] == NO && [[object valueForKey:keyPath?:@""] isKindOfClass:[NSString class]] == NO)
  172. {
  173. return nil;
  174. }
  175. }
  176. NSArray *array = [oldArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
  177. {
  178. NSString *str1 = obj1;
  179. NSString *str2 = obj2;
  180. if ([str1 isKindOfClass:[NSString class]] == NO)
  181. {
  182. str1 = [obj1 valueForKey:keyPath];
  183. }
  184. if ([str2 isKindOfClass:[NSString class]] == NO)
  185. {
  186. str2 = [obj2 valueForKey:keyPath];
  187. }
  188. NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch;//加上数字排序,这样徐21会排在徐3后面
  189. NSLocale *chinaLocale = [NSLocale localeWithLocaleIdentifier:@"zh_CN"];//中国地区的本地化字符串排序才是按照拼音
  190. return [str1 compare:str2 options:comparisonOptions range:NSMakeRange(0, str1.length) locale:chinaLocale];//range.lenght不能是max(1.len, 2.len),因为如果str1的字符数比str2少时会崩溃,如果是min,则比较不准确,特别是数字比较时
  191. }];
  192. return array;
  193. }
  194. + (NSDictionary*)getDeviceInfo{
  195. NSString *macAddress = [MOTools getWiFiMACAddress];
  196. MOLogV(@"123123");
  197. NSDictionary *deviceInfo = @{
  198. // WiFi-Mac 地址
  199. @"WiFi-Mac": [[MOTools getWiFiMACAddress] description] ? [[MOTools getWiFiMACAddress] description] : @"",
  200. // 蓝牙-Mac 地址
  201. @"Bluetooth-Mac": @"",
  202. // UDID
  203. @"UDID": [[UIDevice currentDevice] identifierForVendor].UUIDString,
  204. // 操作系统及版本
  205. @"OS": [[UIDevice currentDevice] systemName],
  206. @"OSVersion": [[UIDevice currentDevice] systemVersion],
  207. // 品牌
  208. @"Brand": [[UIDevice currentDevice] model],
  209. // Apple-IDFA
  210. @"IDFA": [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString],
  211. // Apple-IDFV
  212. @"IDFV": [UIDevice currentDevice].identifierForVendor.UUIDString,
  213. // 像素比
  214. @"PixelRatio": @([[UIScreen mainScreen] scale]),
  215. // 型号
  216. @"Model": [[UIDevice currentDevice] model]
  217. };
  218. return deviceInfo;
  219. }
  220. + (NSString *)getWiFiMACAddress {
  221. NSArray *interfaces = CFBridgingRelease(CNCopySupportedInterfaces());
  222. id interfaceInfo = nil;
  223. for (NSString *interface in interfaces) {
  224. CFDictionaryRef networkInfo = CNCopyCurrentNetworkInfo((__bridge CFStringRef)interface);
  225. if (networkInfo) {
  226. interfaceInfo = (__bridge id)(networkInfo);
  227. CFRelease(networkInfo);
  228. }
  229. }
  230. return [interfaceInfo objectForKey:(__bridge NSString*)kCNNetworkInfoKeyBSSID];
  231. }
  232. + (NSString *)getDeviceString{
  233. struct utsname systemInfo;
  234. uname(&systemInfo);
  235. NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
  236. return platform;
  237. }
  238. + (NSString *)getCurrentDeviceModel
  239. {
  240. struct utsname systemInfo;
  241. uname(&systemInfo);
  242. NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
  243. //iPhone
  244. if ([platform isEqualToString:@"iPhone1,1"])
  245. {
  246. return @"iPhone 2G";
  247. }
  248. else if ([platform isEqualToString:@"iPhone1,2"])
  249. {
  250. return @"iPhone 3G";
  251. }
  252. else if ([platform isEqualToString:@"iPhone2,1"])
  253. {
  254. return @"iPhone 3GS";
  255. }
  256. else if ([platform isEqualToString:@"iPhone3,1"])
  257. {
  258. return @"iPhone 4";
  259. }
  260. else if ([platform isEqualToString:@"iPhone3,2"])
  261. {
  262. return @"iPhone 4";
  263. }
  264. else if ([platform isEqualToString:@"iPhone3,3"])
  265. {
  266. return @"iPhone 4";
  267. }
  268. else if ([platform isEqualToString:@"iPhone4,1"])
  269. {
  270. return @"iPhone 4S";
  271. }
  272. else if ([platform isEqualToString:@"iPhone5,1"])
  273. {
  274. return @"iPhone 5";
  275. }
  276. else if ([platform isEqualToString:@"iPhone5,2"])
  277. {
  278. return @"iPhone 5";
  279. }
  280. else if ([platform isEqualToString:@"iPhone5,3"])
  281. {
  282. return @"iPhone 5c";
  283. }
  284. else if ([platform isEqualToString:@"iPhone5,4"])
  285. {
  286. return @"iPhone 5c";
  287. }
  288. else if ([platform isEqualToString:@"iPhone6,1"])
  289. {
  290. return @"iPhone 5s";
  291. }
  292. else if ([platform isEqualToString:@"iPhone6,2"])
  293. {
  294. return @"iPhone 5s";
  295. }
  296. else if ([platform isEqualToString:@"iPhone7,2"])
  297. {
  298. return @"iPhone 6";
  299. }
  300. else if ([platform isEqualToString:@"iPhone7,1"])
  301. {
  302. return @"iPhone 6 Plus";
  303. }
  304. else if ([platform isEqualToString:@"iPhone8,1"])
  305. {
  306. return @"iPhone 6s";
  307. }
  308. else if ([platform isEqualToString:@"iPhone8,2"])
  309. {
  310. return @"iPhone 6s Plus";
  311. }
  312. else if ([platform isEqualToString:@"iPhone8,4"])
  313. {
  314. return @"iPhone SE";
  315. }
  316. else if ([platform isEqualToString:@"iPhone9,1"])
  317. {
  318. return @"iPhone 7";
  319. }
  320. else if ([platform isEqualToString:@"iPhone9,3"])
  321. {
  322. return @"iPhone 7";
  323. }
  324. else if ([platform isEqualToString:@"iPhone9,2"])
  325. {
  326. return @"iPhone 7 Plus";
  327. }
  328. else if ([platform isEqualToString:@"iPhone9,4"])
  329. {
  330. return @"iPhone 7 Plus";
  331. }
  332. else if ([platform isEqualToString:@"iPhone10,1"])
  333. {
  334. return @"iPhone 8";
  335. }
  336. else if ([platform isEqualToString:@"iPhone10,4"])
  337. {
  338. return @"iPhone 8";
  339. }
  340. else if ([platform isEqualToString:@"iPhone10,2"])
  341. {
  342. return @"iPhone 8 Plus";
  343. }
  344. else if ([platform isEqualToString:@"iPhone10,5"])
  345. {
  346. return @"iPhone 8 Plus (A1897)";
  347. }
  348. else if ([platform isEqualToString:@"iPhone10,3"])
  349. {
  350. return @"iPhone X";
  351. }
  352. else if ([platform isEqualToString:@"iPhone10,6"])
  353. {
  354. return @"iPhone X";
  355. }
  356. else if ([platform isEqualToString:@"iPhone11,2"])
  357. {
  358. return @"iPhone XS";
  359. }
  360. else if ([platform isEqualToString:@"iPhone11,4"])
  361. {
  362. return @"iPhone XS Max";
  363. }
  364. else if ([platform isEqualToString:@"iPhone11,6"])
  365. {
  366. return @"iPhone XS Max";
  367. }
  368. else if ([platform isEqualToString:@"iPhone11,8"])
  369. {
  370. return @"iPhone XR";
  371. }
  372. else if ([platform isEqualToString:@"iPhone12,1"])
  373. {
  374. return @"iPhone 11";
  375. }
  376. else if ([platform isEqualToString:@"iPhone12,3"])
  377. {
  378. return @"iPhone 11 Pro";
  379. }
  380. else if ([platform isEqualToString:@"iPhone12,5"])
  381. {
  382. return @"iPhone 11 Pro Max";
  383. }
  384. else if ([platform isEqualToString:@"iPhone12,8"])
  385. {
  386. return @"iPhone SE (2nd generation)";
  387. }
  388. else if ([platform isEqualToString:@"iPhone13,1"])
  389. {
  390. return @"iPhone 12 mini";
  391. }
  392. else if ([platform isEqualToString:@"iPhone13,2"])
  393. {
  394. return @"iPhone 12";
  395. }
  396. else if ([platform isEqualToString:@"iPhone13,3"])
  397. {
  398. return @"iPhone 12 Pro";
  399. }
  400. else if ([platform isEqualToString:@"iPhone13,4"])
  401. {
  402. return @"iPhone 12 Pro Max";
  403. }
  404. else if ([platform isEqualToString:@"iPhone14,4"])
  405. {
  406. return @"iPhone 13 mini";
  407. }
  408. else if ([platform isEqualToString:@"iPhone14,5"])
  409. {
  410. return @"iPhone 13";
  411. }
  412. else if ([platform isEqualToString:@"iPhone14,2"])
  413. {
  414. return @"iPhone 13 Pro";
  415. }
  416. else if ([platform isEqualToString:@"iPhone14,3"])
  417. {
  418. return @"iPhone 13 Pro Max";
  419. }
  420. else if ([platform isEqualToString:@"iPhone14,6"])
  421. {
  422. return @"iPhone SE (3rd generation)";
  423. }
  424. else if ([platform isEqualToString:@"iPhone14,7"])
  425. {
  426. return @"iPhone 14";
  427. }
  428. else if ([platform isEqualToString:@"iPhone14,8"])
  429. {
  430. return @"iPhone 14 Plus";
  431. }
  432. else if ([platform isEqualToString:@"iPhone15,3"])
  433. {
  434. return @"iPhone 14 Pro Max";
  435. }
  436. else if ([platform isEqualToString:@"iPhone15,2"])
  437. {
  438. return @"iPhone 14 Pro";
  439. }
  440. else if ([platform isEqualToString:@"iPhone15,4"])
  441. {
  442. return @"iPhone 15";
  443. }
  444. else if ([platform isEqualToString:@"iPhone15,5"])
  445. {
  446. return @"iPhone 15 Plus";
  447. }
  448. else if ([platform isEqualToString:@"iPhone16,1"])
  449. {
  450. return @"iPhone 15 Pro";
  451. }
  452. else if ([platform isEqualToString:@"iPhone16,2"])
  453. {
  454. return @"iPhone 15 Pro Max";
  455. }
  456. //iPad
  457. if ([platform isEqualToString:@"iPad1,1"])
  458. {
  459. return @"iPad";
  460. }
  461. if ([platform isEqualToString:@"iPad2,1"])
  462. {
  463. return @"iPad 2";
  464. }
  465. if ([platform isEqualToString:@"iPad2,2"])
  466. {
  467. return @"iPad 2";
  468. }
  469. if ([platform isEqualToString:@"iPad2,3"])
  470. {
  471. return @"iPad 2";
  472. }
  473. if ([platform isEqualToString:@"iPad2,4"])
  474. {
  475. return @"iPad 2";
  476. }
  477. if ([platform isEqualToString:@"iPad3,1"])
  478. {
  479. return @"iPad (3rd generation)";
  480. }
  481. if ([platform isEqualToString:@"iPad3,2"])
  482. {
  483. return @"iPad (3rd generation)";
  484. }
  485. if ([platform isEqualToString:@"iPad3,3"])
  486. {
  487. return @"iPad (3rd generation)";
  488. }
  489. if ([platform isEqualToString:@"iPad3,4"])
  490. {
  491. return @"iPad (4th generation)";
  492. }
  493. if ([platform isEqualToString:@"iPad3,5"])
  494. {
  495. return @"iPad (4th generation)";
  496. }
  497. if ([platform isEqualToString:@"iPad3,6"])
  498. {
  499. return @"iPad (4th generation)";
  500. }
  501. if ([platform isEqualToString:@"iPad6,11"])
  502. {
  503. return @"iPad (5th generation)";
  504. }
  505. if ([platform isEqualToString:@"iPad6,12"])
  506. {
  507. return @"iPad (5th generation)";
  508. }
  509. if ([platform isEqualToString:@"iPad7,5"])
  510. {
  511. return @"iPad (6th generation)";
  512. }
  513. if ([platform isEqualToString:@"iPad7,6"])
  514. {
  515. return @"iPad (6th generation)";
  516. }
  517. if ([platform isEqualToString:@"iPad7,11"])
  518. {
  519. return @"iPad (7th generation)";
  520. }
  521. if ([platform isEqualToString:@"iPad7,12"])
  522. {
  523. return @"iPad (7th generation)";
  524. }
  525. if ([platform isEqualToString:@"iPad11,6"])
  526. {
  527. return @"iPad (8th generation)";
  528. }
  529. if ([platform isEqualToString:@"iPad11,7"])
  530. {
  531. return @"iPad (8th generation)";
  532. }
  533. //iPad Air
  534. if ([platform isEqualToString:@"iPad4,1"])
  535. {
  536. return @"iPad Air";
  537. }
  538. if ([platform isEqualToString:@"iPad4,2"])
  539. {
  540. return @"iPad Air";
  541. }
  542. if ([platform isEqualToString:@"iPad4,3"])
  543. {
  544. return @"iPad Air";
  545. }
  546. if ([platform isEqualToString:@"iPad5,3"])
  547. {
  548. return @"iPad Air 2";
  549. }
  550. if ([platform isEqualToString:@"iPad5,4"])
  551. {
  552. return @"iPad Air 2";
  553. }
  554. if ([platform isEqualToString:@"iPad11,3"])
  555. {
  556. return @"iPad Air (3rd generation)";
  557. }
  558. if ([platform isEqualToString:@"iPad11,4"])
  559. {
  560. return @"iPad Air (3rd generation)";
  561. }
  562. if ([platform isEqualToString:@"iPad13,1"])
  563. {
  564. return @"iPad Air (4th generation)";
  565. }
  566. if ([platform isEqualToString:@"iPad13,2"])
  567. {
  568. return @"iPad Air (4th generation)";
  569. }
  570. //iPad mini
  571. if ([platform isEqualToString:@"iPad2,5"])
  572. {
  573. return @"iPad mini";
  574. }
  575. if ([platform isEqualToString:@"iPad2,6"])
  576. {
  577. return @"iPad mini";
  578. }
  579. if ([platform isEqualToString:@"iPad2,7"])
  580. {
  581. return @"iPad mini 1";
  582. }
  583. if ([platform isEqualToString:@"iPad4,4"])
  584. {
  585. return @"iPad mini 2";
  586. }
  587. if ([platform isEqualToString:@"iPad4,5"])
  588. {
  589. return @"iPad mini 2";
  590. }
  591. if ([platform isEqualToString:@"iPad4,6"])
  592. {
  593. return @"iPad mini 2";
  594. }
  595. if ([platform isEqualToString:@"iPad4,7"])
  596. {
  597. return @"iPad mini 3";
  598. }
  599. if ([platform isEqualToString:@"iPad4,8"])
  600. {
  601. return @"iPad mini 3";
  602. }
  603. if ([platform isEqualToString:@"iPad4,9"])
  604. {
  605. return @"iPad mini 3";
  606. }
  607. if ([platform isEqualToString:@"iPad5,1"])
  608. {
  609. return @"iPad mini 4";
  610. }
  611. if ([platform isEqualToString:@"iPad5,2"])
  612. {
  613. return @"iPad mini 4";
  614. }
  615. if ([platform isEqualToString:@"iPad11,1"])
  616. {
  617. return @"iPad mini 5";
  618. }
  619. if ([platform isEqualToString:@"iPad11,2"])
  620. {
  621. return @"iPad mini 5";
  622. }
  623. // iPad Pro
  624. if ([platform isEqualToString:@"iPad6,3"])
  625. {
  626. return @"iPad Pro (9.7-inch)";
  627. }
  628. if ([platform isEqualToString:@"iPad6,4"])
  629. {
  630. return @"iPad Pro (9.7-inch)";
  631. }
  632. if ([platform isEqualToString:@"iPad6,7"])
  633. {
  634. return @"iPad Pro (12.9-inch)";
  635. }
  636. if ([platform isEqualToString:@"iPad6,8"])
  637. {
  638. return @"iPad Pro (12.9-inch)";
  639. }
  640. if ([platform isEqualToString:@"iPad7,1"])
  641. {
  642. return @"iPad Pro (12.9-inch) (2nd generation)";
  643. }
  644. if ([platform isEqualToString:@"iPad7,2"])
  645. {
  646. return @"iPad Pro (12.9-inch) (2nd generation)";
  647. }
  648. if ([platform isEqualToString:@"iPad7,3"])
  649. {
  650. return @"iPad Pro (10.5 inch)";
  651. }
  652. if ([platform isEqualToString:@"iPad7,4"])
  653. {
  654. return @"iPad Pro (10.5-inch)";
  655. }
  656. if ([platform isEqualToString:@"iPad8,1"])
  657. {
  658. return @"iPad Pro (11-inch)";
  659. }
  660. if ([platform isEqualToString:@"iPad8,2"])
  661. {
  662. return @"iPad Pro (11-inch)";
  663. }
  664. if ([platform isEqualToString:@"iPad8,3"])
  665. {
  666. return @"iPad Pro (11-inch)";
  667. }
  668. if ([platform isEqualToString:@"iPad8,4"])
  669. {
  670. return @"iPad Pro (11-inch)";
  671. }
  672. if ([platform isEqualToString:@"iPad8,5"])
  673. {
  674. return @"iPad Pro (12.9-inch) (3rd generation)";
  675. }
  676. if ([platform isEqualToString:@"iPad8,6"])
  677. {
  678. return @"iPad Pro (12.9-inch) (3rd generation)";
  679. }
  680. if ([platform isEqualToString:@"iPad8,7"])
  681. {
  682. return @"iPad Pro (12.9-inch) (3rd generation)";
  683. }
  684. if ([platform isEqualToString:@"iPad8,8"])
  685. {
  686. return @"iPad Pro (12.9-inch) (3rd generation)";
  687. }
  688. if ([platform isEqualToString:@"iPad8,9"])
  689. {
  690. return @"iPad Pro (11-inch) (2nd generation)";
  691. }
  692. if ([platform isEqualToString:@"iPad8,10"])
  693. {
  694. return @"iPad Pro (11-inch) (2nd generation)";
  695. }
  696. if ([platform isEqualToString:@"iPad8,11"])
  697. {
  698. return @"iPad Pro (12.9-inch) (4th generation)";
  699. }
  700. if ([platform isEqualToString:@"iPad8,12"])
  701. {
  702. return @"iPad Pro (12.9-inch) (4th generation)";
  703. }
  704. //iPod Touch
  705. if ([platform isEqualToString:@"iPod1,1"])
  706. {
  707. return @"iPod Touch";
  708. }
  709. if ([platform isEqualToString:@"iPod2,1"])
  710. {
  711. return @"iPod Touch 2";
  712. }
  713. if ([platform isEqualToString:@"iPod3,1"])
  714. {
  715. return @"iPod Touch 3";
  716. }
  717. if ([platform isEqualToString:@"iPod4,1"])
  718. {
  719. return @"iPod Touch 4)";
  720. }
  721. if ([platform isEqualToString:@"iPod5,1"])
  722. {
  723. return @"iPod Touch 5";
  724. }
  725. if ([platform isEqualToString:@"iPod7,1"])
  726. {
  727. return @"iPod Touch 6";
  728. }
  729. if ([platform isEqualToString:@"iPod9,1"])
  730. {
  731. return @"iPod Touch 7";
  732. }
  733. // Apple Watch
  734. if ([platform isEqualToString:@"Watch1,1"])
  735. {
  736. return @"Apple Watch";
  737. }
  738. if ([platform isEqualToString:@"Watch1,2"])
  739. {
  740. return @"Apple Watch";
  741. }
  742. if ([platform isEqualToString:@"Watch2,6"])
  743. {
  744. return @"Apple Watch Series 1";
  745. }
  746. if ([platform isEqualToString:@"Watch2,7"])
  747. {
  748. return @"Apple Watch Series 1";
  749. }
  750. if ([platform isEqualToString:@"Watch2,3"])
  751. {
  752. return @"Apple Watch Series 2";
  753. }
  754. if ([platform isEqualToString:@"Watch2,4"])
  755. {
  756. return @"Apple Watch Series 2";
  757. }
  758. if ([platform isEqualToString:@"Watch3,1"])
  759. {
  760. return @"Apple Watch Series 3";
  761. }
  762. if ([platform isEqualToString:@"Watch3,2"])
  763. {
  764. return @"Apple Watch Series 3";
  765. }
  766. if ([platform isEqualToString:@"Watch3,3"])
  767. {
  768. return @"Apple Watch Series 3";
  769. }
  770. if ([platform isEqualToString:@"Watch3,4"])
  771. {
  772. return @"Apple Watch Series 3";
  773. }
  774. // 模拟器
  775. if ([platform isEqualToString:@"i386"])
  776. {
  777. return @"iPhone Simulator";
  778. }
  779. if ([platform isEqualToString:@"x86_64"])
  780. {
  781. return @"iPhone Simulator";
  782. }
  783. return platform;
  784. }
  785. + (NSInteger)keepFirstDigitAndZeroOthersWith:(double)number{
  786. // 将数字转换为字符串
  787. NSString *numberString = [NSString stringWithFormat:@"%.f", number];
  788. // 如果数字只有一位,则直接返回
  789. if (numberString.length <= 1) {
  790. return number;
  791. }
  792. // 提取第一位数字
  793. NSString *firstDigitString = [numberString substringToIndex:1];
  794. // 生成结果字符串,其他位设为0
  795. NSString *resultString = [NSString stringWithFormat:@"%@%@", firstDigitString, [@"" stringByPaddingToLength:numberString.length - 1 withString:@"0" startingAtIndex:0]];
  796. // 将结果字符串转换为整数并返回
  797. return [resultString integerValue];
  798. }
  799. /// 将传入的数字进行模式化 - (大于1W -> 10000 , 小于1W大于1000, 则为1000, 如果小于1000则为具体数字)
  800. + (NSInteger)keepFirstZeroOthersWith:(double)number{
  801. if(number >= 10000){
  802. number = 10000;
  803. return number;
  804. }
  805. if(number >= 1000 && number <= 9999){
  806. number = 1000;
  807. return number;
  808. }
  809. return number;
  810. }
  811. /// 设置这一次弹出手机绑定弹窗设备的时间 */
  812. + (void)setTimeOfShowBindDevice:(NSDate *)time{
  813. [[MODataCache sharedYYCache] setObject:time forKey:kShowBindTime];
  814. }
  815. /// 获取上一次手机绑定弹窗的时间 */
  816. + (NSDate *)getTimeOfShowBind{
  817. return (NSDate *)[[MODataCache sharedYYCache] objectForKey:kShowBindTime];
  818. }
  819. + (void)setTimeOfShowSignDevice:(NSDate *)time{
  820. NSString *userId = GetUserId;
  821. if(userId.length == 0){
  822. userId = @"";
  823. }
  824. NSString *key = [NSString stringWithFormat:@"%@_%@",kShowSignTime,userId];
  825. [[MODataCache sharedYYCache] setObject:time forKey:key];
  826. }
  827. + (NSDate *)getTimeOfShowSign{
  828. NSString *userId = GetUserId;
  829. if(userId.length == 0){
  830. userId = @"";
  831. }
  832. NSString *key = [NSString stringWithFormat:@"%@_%@",kShowSignTime,userId];
  833. return (NSDate *)[[MODataCache sharedYYCache] objectForKey:key];
  834. }
  835. /** 是否时间过了一天 */
  836. + (BOOL)shouldShowAlertWithLastTime:(NSDate *)lastTime{
  837. BOOL showAlert = NO;
  838. NSDate *now = [NSDate date];
  839. MOLogV(@"now=%@(%lf), lastTime=%@(%lf)", now, now.timeIntervalSince1970, lastTime, lastTime.timeIntervalSince1970);
  840. if (now.timeIntervalSince1970 - lastTime.timeIntervalSince1970 > 24*60*60)
  841. {
  842. showAlert = YES;
  843. }
  844. else if (now.timeIntervalSince1970 > lastTime.timeIntervalSince1970)
  845. {
  846. NSCalendar *calendar = [NSCalendar currentCalendar];
  847. NSDateComponents *lastTimeComponents = [calendar components:NSCalendarUnitDay|NSCalendarUnitMonth fromDate:lastTime];
  848. NSDateComponents *nowComponents = [calendar components:NSCalendarUnitDay|NSCalendarUnitMonth fromDate:now];
  849. MOLogV(@"nowday=%d, lastTimeday=%d", (int)nowComponents.day, (int)lastTimeComponents.day);
  850. if (nowComponents.month == lastTimeComponents.month)
  851. {
  852. if (nowComponents.day > lastTimeComponents.day)
  853. {
  854. showAlert = YES;
  855. }
  856. }
  857. else
  858. {
  859. if (nowComponents.day < lastTimeComponents.day)
  860. {
  861. showAlert = YES;
  862. }
  863. }
  864. }
  865. return showAlert;
  866. }
  867. - (NSInteger)mo_nextDoubleAndMin:(NSInteger)min And:(NSInteger)max{
  868. self.seed = (self.seed * 9301 + 49297) % 233280;
  869. MOLogV(@"seed %zd",self.seed);
  870. double rnd = self.seed / (233280 * 1.0);
  871. NSInteger result = min + (NSInteger)(rnd * (max - min));
  872. return result;
  873. }
  874. + (UIViewController *)currentViewController
  875. {
  876. UIViewController *viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
  877. while (viewController) {
  878. if ([viewController isKindOfClass:[UITabBarController class]]) {
  879. UITabBarController *tbvc = (UITabBarController*)viewController;
  880. viewController = tbvc.selectedViewController;
  881. } else if ([viewController isKindOfClass:[UINavigationController class]]) {
  882. UINavigationController *nvc = (UINavigationController*)viewController;
  883. viewController = nvc.topViewController;
  884. } else if (viewController.presentedViewController) {
  885. viewController = viewController.presentedViewController;
  886. } else if ([viewController isKindOfClass:[UISplitViewController class]] &&
  887. ((UISplitViewController *)viewController).viewControllers.count > 0) {
  888. UISplitViewController *svc = (UISplitViewController *)viewController;
  889. viewController = svc.viewControllers.lastObject;
  890. } else {
  891. return viewController;
  892. }
  893. }
  894. return viewController;
  895. }
  896. /// 更新服务器时间的差值
  897. + (void)toUpdataTheRedSysTimeWith:(int64_t)sysTime{
  898. NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];
  899. NSTimeInterval nowStamp = [date timeIntervalSince1970]*1000;
  900. NSString *timeString = [NSString stringWithFormat:@"%.f", nowStamp];
  901. int64_t time = [timeString longLongValue] - sysTime;
  902. //因为是红包 时间误差, 所以误差为1秒内
  903. // 注意这里的time实际上包含了getSysTime接口的调用时长,不能简单理解为客户端与服务端的时间差
  904. // 实际上如果用户手动修改过系统时间,一般不会修改到秒级,所以我们认为time<=1000毫秒都是接口调用时长,不需要作时间校正
  905. if (llabs(time) <= 1000)
  906. {
  907. time = 0;
  908. }
  909. MOLogV(@"1sysTime---:%lld",time);
  910. [[NSUserDefaults standardUserDefaults]setObject:[NSNumber numberWithLongLong:time] forKey:kRedSysTime];
  911. [[NSUserDefaults standardUserDefaults] synchronize];
  912. }
  913. + (UIView *)containsViewOfClass:(Class)viewClass inView:(UIView *)view{
  914. // 检查当前视图是否是指定的类
  915. if ([view isKindOfClass:viewClass]) {
  916. return view;
  917. }
  918. // 递归检查所有子视图
  919. for (UIView *subview in view.subviews) {
  920. UIView *theView = [self containsViewOfClass:viewClass inView:subview];
  921. if (theView) {
  922. return theView;
  923. }
  924. }
  925. return nil;
  926. }
  927. //判断是否显示
  928. + (BOOL)toJudgeShowWame{
  929. BOOL isShow = NO;
  930. MOMeDataInfo *userInfoData = (MOMeDataInfo *)[[MODataCache sharedYYCache] objectForKey:kMineUserInfo];
  931. isShow = userInfoData.userStatusInfo.displayPlay;
  932. if(isShow){
  933. NSArray *tempArr = [[MOSvgaSourceManage shareManager].wameDataArr copy];
  934. if(tempArr.count < 2){
  935. isShow = NO;
  936. }
  937. }
  938. return isShow;
  939. }
  940. /// 获取并本地存储图片
  941. + (void)fetchAndStoreImageWithUrl:(NSString *)url completeBlock:(void (^)(UIImage *image))completeBlock {
  942. UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromCacheForKey:url];
  943. if (cachedImage) {
  944. if (completeBlock) {
  945. completeBlock(cachedImage);
  946. }
  947. return;
  948. }
  949. [SDWebImageDownloader.sharedDownloader downloadImageWithURL:[NSURL URLWithString:url]
  950. options:SDWebImageDownloaderHighPriority
  951. progress:nil
  952. completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
  953. if (!image) {
  954. if (completeBlock) {
  955. completeBlock(nil);
  956. }
  957. return;
  958. }
  959. [[SDImageCache sharedImageCache] storeImage:image forKey:url completion:nil];
  960. if (completeBlock) {
  961. completeBlock(image);
  962. }
  963. }];
  964. }
  965. // 判断输入的字符串是否是有效的邮箱地址
  966. + (BOOL)isValidEmail:(NSString *)email {
  967. if (email.length == 0) {
  968. return NO;
  969. }
  970. // 更严格的邮箱正则表达式(RFC 5322 简化版)
  971. NSString *emailRegex = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,10}$";
  972. // 使用 NSPredicate 进行匹配
  973. NSPredicate *emailPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
  974. return [emailPredicate evaluateWithObject:email];
  975. }
  976. + (NSString *)maskPhoneNumber:(NSString *)phoneNumber {
  977. if (phoneNumber.length <= 4) {
  978. return phoneNumber;
  979. }
  980. NSUInteger length = phoneNumber.length;
  981. NSUInteger maskLength = length - 4;
  982. NSString *mask = [@"" stringByPaddingToLength:maskLength withString:@"*" startingAtIndex:0];
  983. NSString *maskedPhoneNumber = [NSString stringWithFormat:@"%@%@%@",
  984. [phoneNumber substringToIndex:2],
  985. mask,
  986. [phoneNumber substringFromIndex:length - 2]];
  987. return maskedPhoneNumber;
  988. }
  989. + (NSString *)getValueWithKey:(NSString *)key urlString:(NSString *)urlString {
  990. NSURL *url = [NSURL URLWithString:urlString];
  991. return [self getValueWithKey:key url:url];
  992. }
  993. + (NSString *)getValueWithKey:(NSString *)key url:(NSURL *)url {
  994. if (!url) {
  995. return nil;
  996. }
  997. NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
  998. NSArray<NSURLQueryItem *> *queryItems = components.queryItems;
  999. for (NSURLQueryItem *item in queryItems) {
  1000. if ([item.name isEqualToString:key]) {
  1001. return item.value;
  1002. }
  1003. }
  1004. return nil;
  1005. }
  1006. //字典转json格式字符串:
  1007. + (NSString *)dictionaryToJson:(NSDictionary *)dic {
  1008. NSError *parseError = nil;
  1009. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&parseError];
  1010. return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  1011. }
  1012. //json格式字符串转字典:
  1013. + (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {
  1014. if (jsonString == nil || jsonString.length == 0) {
  1015. return nil;
  1016. }
  1017. NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
  1018. NSError *err;
  1019. NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
  1020. options:NSJSONReadingMutableContainers
  1021. error:&err];
  1022. if(err) {
  1023. MOLogV(@"json解析失败:%@",err);
  1024. return nil;
  1025. }
  1026. return dic;
  1027. }
  1028. //根据VIP 类型 和 尺寸 生成对应的图片
  1029. + (UIImage *)getVipImgIconWith:(NSInteger)type AndSize:(CGSize)size{
  1030. UIImage *theVipIcon = [UIImage imageNamed:@"v_2_vip_1_282"];
  1031. switch (type) {
  1032. case 1:{
  1033. theVipIcon = [UIImage imageNamed:@"v_2_vip_1_282"];
  1034. }
  1035. break;
  1036. case 2:{
  1037. theVipIcon = [UIImage imageNamed:@"v_2_vip_2_282"];
  1038. }
  1039. break;
  1040. case 3:{
  1041. theVipIcon = [UIImage imageNamed:@"v_2_vip_3_282"];
  1042. }
  1043. break;
  1044. case 4:{
  1045. theVipIcon = [UIImage imageNamed:@"v_2_vip_4_282"];
  1046. }
  1047. break;
  1048. case 5:{
  1049. theVipIcon = [UIImage imageNamed:@"v_2_vip_5_282"];
  1050. }
  1051. break;
  1052. case 6:{
  1053. theVipIcon = [UIImage imageNamed:@"v_2_vip_6_282"];
  1054. }
  1055. break;
  1056. default:
  1057. break;
  1058. }
  1059. if(size.width > 0 && size.height > 0){
  1060. theVipIcon = [theVipIcon imageByResizeToSize:size contentMode:UIViewContentModeScaleAspectFit];
  1061. }
  1062. return theVipIcon;
  1063. }
  1064. //根据道具分类, 拿分类图片
  1065. + (UIImage *)toGetThePropsTypeWith:(NSInteger)type{
  1066. //道具分类\n * 1: 头饰\n * 2: 气泡\n * 3: 入场座驾(旧:进场条)\n * 4: 名片框\n * 5: 直播徽章\n * 6: 用户徽章\n * 7: 进场条(旧:进场飘屏)\n * 8: 打赏横幅\n * 9: 连麦边框\n * 10: 直播弹幕
  1067. UIImage *theImage = nil;
  1068. switch (type) {
  1069. case 1:
  1070. {
  1071. theImage = [UIImage imageNamed:@"v_2_prop_type_1"];
  1072. }
  1073. break;
  1074. case 2:
  1075. {
  1076. theImage = [UIImage imageNamed:@"v_2_prop_type_2"];
  1077. }
  1078. break;
  1079. case 3:
  1080. {
  1081. theImage = [UIImage imageNamed:@"v_2_prop_type_3"];
  1082. }
  1083. break;
  1084. case 4:
  1085. {
  1086. theImage = [UIImage imageNamed:@"v_2_prop_type_4"];
  1087. }
  1088. break;
  1089. case 7:
  1090. {
  1091. theImage = [UIImage imageNamed:@"v_2_prop_type_7"];
  1092. }
  1093. break;
  1094. case 8:
  1095. {
  1096. theImage = [UIImage imageNamed:@"v_2_prop_type_8"];
  1097. }
  1098. break;
  1099. case 9:
  1100. {
  1101. theImage = [UIImage imageNamed:@"v_2_prop_type_9"];
  1102. }
  1103. break;
  1104. case 10:
  1105. {
  1106. theImage = [UIImage imageNamed:@"v_2_prop_type_10"];
  1107. }
  1108. break;
  1109. default:
  1110. break;
  1111. }
  1112. return theImage;
  1113. }
  1114. + (BOOL)isStringArrayContentEqualIgnoringOrder:(NSArray<NSString *> *)array1 array2:(NSArray<NSString *> *)array2 {
  1115. NSSet *set1 = [NSSet setWithArray:array1];
  1116. NSSet *set2 = [NSSet setWithArray:array2];
  1117. return [set1 isEqualToSet:set2];
  1118. }
  1119. + (NSString *)generateUniqueID {
  1120. // 当前时间戳(到毫秒)
  1121. NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970] * 1000;
  1122. // 随机数(0~999)
  1123. int random = arc4random_uniform(1000);
  1124. // 拼接成唯一ID
  1125. NSString *uniqueID = [NSString stringWithFormat:@"ID_%.0f_%03d", timeStamp, random];
  1126. return uniqueID;
  1127. }
  1128. /// 退出键盘
  1129. + (void)dismissKeyboard {
  1130. for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
  1131. if (scene.activationState == UISceneActivationStateForegroundActive) {
  1132. for (UIWindow *window in scene.windows) {
  1133. if (window.isKeyWindow) {
  1134. [window endEditing:YES];
  1135. return;
  1136. }
  1137. }
  1138. }
  1139. }
  1140. }
  1141. /// 超出指定长度替换成...
  1142. /// - Parameters:
  1143. /// - string: 字符串
  1144. /// - maxLength: 最大长度
  1145. + (NSString *)trimString:(NSString *)string maxLength:(NSInteger)maxLength {
  1146. if (string.length <= maxLength) {
  1147. return string;
  1148. } else {
  1149. return [[string substringToIndex:maxLength] stringByAppendingString:@"..."];
  1150. }
  1151. }
  1152. + (NSString *)timeAgoStringFromTimeStamp:(NSTimeInterval)timeStamp {
  1153. if (timeStamp > [[NSDate date] timeIntervalSince1970] * 10) {
  1154. timeStamp = timeStamp / 1000.0;
  1155. }
  1156. NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
  1157. NSTimeInterval diff = now - timeStamp;
  1158. if (diff < 60) {
  1159. return NSLocalString(@"B20044");
  1160. } else {
  1161. NSInteger minutes = diff / 60;
  1162. return [NSString stringWithFormat:NSLocalString(@"B20045"),minutes];
  1163. }
  1164. }
  1165. @end