RAUtils.m 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129
  1. //
  2. // RAUtils.m
  3. // RedAnt ERP Mobile
  4. //
  5. // Created by Ray on 9/17/15.
  6. // Copyright (c) 2015 United Software Applications, Inc. All rights reserved.
  7. //
  8. #import "RAUtils.h"
  9. #import "const.h"
  10. //#import "LoginViewController.h"
  11. //#import "MainViewController.h"
  12. #import <sys/param.h>
  13. #import <sys/mount.h>
  14. //#import "const.h"
  15. #import "AppDelegate.h"
  16. //#import "Singleton.h"
  17. #include <CommonCrypto/CommonDigest.h>
  18. //#import "ZipArchive.h"
  19. #define FileHashDefaultChunkSizeForReadingData 1024*8
  20. @implementation RAUtils
  21. +(int)getRandomNumber:(int)from to:(int)to
  22. {
  23. return (int)(from + (arc4random() % (to-from + 1)));
  24. }
  25. //+(float)randomf
  26. //{
  27. //
  28. // int irandom = [self getRandomNumber:0 to:5];
  29. // return irandom / 100.0;
  30. //}
  31. //+(NSString*) getdbzip:(NSString*)dbname
  32. //{
  33. //
  34. //
  35. // NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
  36. // NSString *documents = /*[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];*/[paths objectAtIndex:0];
  37. // NSString *database_path = [documents stringByAppendingPathComponent:dbname];
  38. //
  39. //
  40. // NSString* temp = NSTemporaryDirectory();
  41. //
  42. // NSString* uuid=[[NSUUID UUID] UUIDString];
  43. //
  44. // NSString *tempfile = [temp stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip",uuid]];
  45. //
  46. // ZipArchive* zip = [[ZipArchive alloc] init];
  47. //
  48. //
  49. // BOOL result = [zip CreateZipFile2:tempfile Password:@"usai2010"];
  50. //
  51. //
  52. // result = [zip addFileToZip:database_path newname:[database_path lastPathComponent]];
  53. // return tempfile;
  54. //
  55. //
  56. //
  57. //}
  58. +(NSData*) getdbfile:(NSString*)dbname
  59. {
  60. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
  61. NSString *documents = /*[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];*/[paths objectAtIndex:0];
  62. NSString *database_path = [documents stringByAppendingPathComponent:dbname];
  63. return [NSData dataWithContentsOfFile:database_path];
  64. }
  65. +(NSDictionary*) dictfromfile:(NSString*) path
  66. {
  67. NSData *filedata = [NSData dataWithContentsOfFile:path];
  68. NSError *error = nil;
  69. NSDictionary *string2dic = [NSJSONSerialization JSONObjectWithData: filedata
  70. options: NSJSONReadingMutableContainers
  71. error: &error];
  72. // DebugLog(@"%@",string2dic);
  73. return string2dic;
  74. }
  75. + (NSArray*) allFilesAtPath:(NSString*) dirString
  76. {
  77. NSMutableArray* array = [NSMutableArray arrayWithCapacity:10];
  78. NSFileManager* fileMgr = [NSFileManager defaultManager];
  79. NSArray* tempArray = [fileMgr contentsOfDirectoryAtPath:dirString error:nil];
  80. for (NSString* fileName in tempArray) {
  81. BOOL flag = YES;
  82. NSString* fullPath = [dirString stringByAppendingPathComponent:fileName];
  83. if ([fileMgr fileExistsAtPath:fullPath isDirectory:&flag]) {
  84. if (!flag) {
  85. [array addObject:fullPath];
  86. }
  87. }
  88. }
  89. return array;
  90. }
  91. + (bool)mergeContentsOfPath:(NSString *)srcDir intoPath:(NSString *)dstDir error:(NSError**)err {
  92. DebugLog(@"- mergeContentsOfPath: %@\n intoPath: %@", srcDir, dstDir);
  93. NSFileManager *fm = [NSFileManager defaultManager];
  94. NSDirectoryEnumerator *srcDirEnum = [fm enumeratorAtPath:srcDir];
  95. NSString *subPath;
  96. while ((subPath = [srcDirEnum nextObject])) {
  97. DebugLog(@" subPath: %@", subPath);
  98. NSString *srcFullPath = [srcDir stringByAppendingPathComponent:subPath];
  99. NSString *potentialDstPath = [dstDir stringByAppendingPathComponent:subPath];
  100. // Need to also check if file exists because if it doesn't, value of `isDirectory` is undefined.
  101. BOOL isDirectory = ([[NSFileManager defaultManager] fileExistsAtPath:srcFullPath isDirectory:&isDirectory] && isDirectory);
  102. // Create directory, or delete existing file and move file to destination
  103. if (isDirectory) {
  104. DebugLog(@" create directory");
  105. [fm createDirectoryAtPath:potentialDstPath withIntermediateDirectories:YES attributes:nil error:err];
  106. if (err && *err) {
  107. DebugLog(@"ERROR: %@", *err);
  108. return false;
  109. }
  110. }
  111. else {
  112. if ([fm fileExistsAtPath:potentialDstPath]) {
  113. DebugLog(@" removeItemAtPath");
  114. [fm removeItemAtPath:potentialDstPath error:err];
  115. if (err && *err) {
  116. DebugLog(@"ERROR: %@", *err);
  117. return false;
  118. }
  119. }
  120. DebugLog(@" moveItemAtPath");
  121. [fm moveItemAtPath:srcFullPath toPath:potentialDstPath error:err];
  122. if (err && *err) {
  123. DebugLog(@"ERROR: %@", *err);
  124. return false;
  125. }
  126. }
  127. }
  128. [fm removeItemAtPath:srcDir error:err];
  129. if (err && *err) {
  130. DebugLog(@"ERROR: %@", *err);
  131. return false;
  132. }
  133. return true;
  134. }
  135. //+(void) enum_font
  136. //{
  137. // return;
  138. // NSArray *familys = [UIFont familyNames];
  139. //
  140. // for (int i = 0; i < familys.count; i++)
  141. // {
  142. // NSString *family = [familys objectAtIndex:i];
  143. // DebugLog(@"=====Fontfamily:%@", family);
  144. // NSArray *fonts = [UIFont fontNamesForFamilyName:family];
  145. // for(int j = 0; j < fonts.count; j++)
  146. // {
  147. // DebugLog(@"***FontName:%@", [fonts objectAtIndex:j]);
  148. // }
  149. // }
  150. //}
  151. //+(NSTextCheckingResult*) expression_findfistMatch:(NSString*)content regex:(NSString*) pattern
  152. //{
  153. // NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil];
  154. //
  155. // NSTextCheckingResult *match = [regex firstMatchInString:content options:0 range:NSMakeRange(0, content.length)];
  156. // return match;
  157. //// if (matches) {
  158. //// for (NSTextCheckingResult *match in matches) {
  159. //// for (int i = 0; i < match.numberOfRanges; ++i) {
  160. //// DebugLog(@"-> %@", [content substringWithRange:[match rangeAtIndex:i]]);
  161. //// }
  162. //// }
  163. //// }
  164. //// return matches;
  165. //}
  166. //+(NSArray*) expression_varable:(NSString*)content regex:(NSString*) pattern
  167. //{
  168. //
  169. // if(content==nil)
  170. // return nil;
  171. //
  172. //
  173. // NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil];
  174. //
  175. // NSArray *matches = [regex matchesInString:content options:0 range:NSMakeRange(0, content.length)];
  176. //
  177. // if (matches) {
  178. // for (NSTextCheckingResult *match in matches) {
  179. // for (int i = 0; i < match.numberOfRanges; ++i) {
  180. // DebugLog(@"-> %@", [content substringWithRange:[match rangeAtIndex:i]]);
  181. // }
  182. // }
  183. // }
  184. // return matches;
  185. //}
  186. + (CGRect)rectAlign:(CGRect )parent rect:(CGRect)rect hAlign:(NSString*)hAlign vAlign:(NSString*)vAlign
  187. {
  188. // double cx=parent.origin.x+parent.size.width/2;
  189. // double cy=parent.origin.y+parent.size.height/2;
  190. CGPoint centerpoint= CGPointMake(parent.origin.x+parent.size.width/2,parent.origin.y+parent.size.height/2);
  191. if([hAlign.lowercaseString isEqualToString:@"center"])
  192. {
  193. rect=CGRectMake(centerpoint.x-rect.size.width/2, rect.origin.y, rect.size.width, rect.size.height);
  194. }
  195. else
  196. if([hAlign.lowercaseString isEqualToString:@"left"])
  197. {
  198. rect=CGRectMake(parent.origin.x, rect.origin.y, rect.size.width, rect.size.height);
  199. }
  200. else
  201. if([hAlign.lowercaseString isEqualToString:@"right"])
  202. {
  203. rect=CGRectMake(parent.origin.x+parent.size.width-rect.size.width, rect.origin.y, rect.size.width, rect.size.height);
  204. }
  205. if([vAlign.lowercaseString isEqualToString:@"middle"])
  206. {
  207. rect=CGRectMake(rect.origin.x, centerpoint.y-rect.size.height/2, rect.size.width, rect.size.height);
  208. }
  209. return rect;
  210. }
  211. +(NSString*) get_config_path
  212. {
  213. NSString *default_path = [[NSBundle mainBundle] pathForResource:@"config" ofType:@"plist"];
  214. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
  215. NSString *cache_folder=[paths objectAtIndex:0];
  216. NSString* ver=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
  217. NSString *config_path = [cache_folder stringByAppendingPathComponent:[NSString stringWithFormat: @"config_%@.plist",ver]];
  218. BOOL bdir=NO;
  219. NSFileManager* fileManager = [NSFileManager defaultManager];
  220. if(! [fileManager fileExistsAtPath:config_path isDirectory:&bdir])
  221. {
  222. NSError * error=nil;
  223. if(![fileManager copyItemAtPath:default_path toPath:config_path error:&error])
  224. {
  225. return nil;
  226. }
  227. }
  228. return config_path;
  229. }
  230. + (CGRect)rectVAlign:(CGRect )parent rect:(CGRect)rect vAlign:(NSString*)vAlign
  231. {
  232. // double cx=parent.origin.x+parent.size.width/2;
  233. // double cy=parent.origin.y+parent.size.height/2;
  234. CGPoint centerpoint= CGPointMake(parent.origin.x+parent.size.width/2,parent.origin.y+parent.size.height/2);
  235. if([vAlign.lowercaseString isEqualToString:@"middle"])
  236. {
  237. rect=CGRectMake(rect.origin.x, centerpoint.y-rect.size.height/2, rect.size.width, rect.size.height);
  238. }
  239. return rect;
  240. }
  241. + (CGRect)scaleToSize:(CGRect )from to:(CGSize)to
  242. {
  243. if(from.size.width/from.size.height>to.width/to.height)
  244. {
  245. return CGRectMake(from.origin.x, from.origin.y, to.width, to.width*from.size.height/from.size.width);
  246. }
  247. else
  248. {
  249. return CGRectMake(from.origin.x, from.origin.y, to.height*from.size.width/from.size.height, to.height);
  250. }
  251. // // 创建一个bitmap的context
  252. // // 并把它设置成为当前正在使用的context
  253. // UIGraphicsBeginImageContext(size);
  254. // // 绘制改变大小的图片
  255. // [img drawInRect:CGRectMake(0, 0, size.width, size.height)];
  256. // // 从当前context中创建一个改变大小后的图片
  257. // UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
  258. // // 使当前的context出堆栈
  259. // UIGraphicsEndImageContext();
  260. // // 返回新的改变大小后的图片
  261. //
  262. // // NSData *imageData=UIImageJPEGRepresentation(scaledImage, 1.f);
  263. // return scaledImage;
  264. }
  265. + (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{
  266. // 创建一个bitmap的context
  267. // 并把它设置成为当前正在使用的context
  268. UIGraphicsBeginImageContext(size);
  269. // 绘制改变大小的图片
  270. [img drawInRect:CGRectMake(0, 0, size.width, size.height)];
  271. // 从当前context中创建一个改变大小后的图片
  272. UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
  273. // 使当前的context出堆栈
  274. UIGraphicsEndImageContext();
  275. // 返回新的改变大小后的图片
  276. // NSData *imageData=UIImageJPEGRepresentation(scaledImage, 1.f);
  277. return scaledImage;
  278. }
  279. +(UIImage*)img_compress:(UIImage*)image kbsize:(float) size
  280. {
  281. //UIImage *image=[UIImage imageNamed:@"xxoo.jpeg"];
  282. NSData *imageData=UIImageJPEGRepresentation(image, 1.f);
  283. if(size>imageData.length/1024)
  284. return image;
  285. // CGFloat size=40.f;// kb
  286. CGFloat scale=size/(imageData.length/1024);
  287. scale = sqrt (scale);
  288. CGSize newsize=image.size;
  289. newsize.height = newsize.height*scale;
  290. newsize.width = newsize.width*scale;
  291. return [RAUtils scaleToSize:image size:newsize];
  292. // NSData *newData=UIImageJPEGRepresentation(image, scale);
  293. // UIImage* ret= [[UIImage alloc] initWithData:newData];
  294. //
  295. // return ret;
  296. }
  297. +(NSString*) FloatFormat:(float)value
  298. {
  299. if (fmodf(value, 1)==0)
  300. {
  301. return [NSString stringWithFormat:@"%.0f",value];
  302. } else if (fmodf(value*10, 1)==0)
  303. {
  304. return [NSString stringWithFormat:@"%.1f",value];
  305. }
  306. else if (fmodf(value*100, 1)==0)
  307. {
  308. return [NSString stringWithFormat:@"%.2f",value];
  309. }
  310. else if (fmodf(value*1000, 1)==0)
  311. {
  312. return [NSString stringWithFormat:@"%.3f",value];
  313. }
  314. else
  315. {
  316. return [NSString stringWithFormat:@"%.4f",value];
  317. }
  318. return nil;
  319. }
  320. +(UIViewController*) getViewController:(UIView*) view
  321. {
  322. for (UIView* next = [view superview]; next; next = next.superview) {
  323. UIResponder* nextResponder = [next nextResponder];
  324. if ([nextResponder isKindOfClass:[UIViewController class]]) {
  325. return (UIViewController*)nextResponder;
  326. }
  327. }
  328. return nil;
  329. }
  330. + (float)fileSizeForDir:(NSString*)path//计算文件夹下文件的总大小
  331. {
  332. NSFileManager *fileManager = [[NSFileManager alloc] init];
  333. float size =0;
  334. NSArray* array = [fileManager contentsOfDirectoryAtPath:path error:nil];
  335. for(int i = 0; i<[array count]; i++)
  336. {
  337. NSString *fullPath = [path stringByAppendingPathComponent:[array objectAtIndex:i]];
  338. BOOL isDir;
  339. if ( !([fileManager fileExistsAtPath:fullPath isDirectory:&isDir] && isDir) )
  340. {
  341. NSDictionary *fileAttributeDic=[fileManager attributesOfItemAtPath:fullPath error:nil];
  342. size+= fileAttributeDic.fileSize/ 1024.0/1024.0;
  343. }
  344. else
  345. {
  346. size+=[self fileSizeForDir:fullPath];
  347. }
  348. }
  349. return size;
  350. }
  351. /*创建错误信息字典*/
  352. +(NSDictionary*) error_dict:(NSError*)error
  353. {
  354. if(error==nil)
  355. return nil;
  356. NSMutableDictionary* ret = [[NSMutableDictionary alloc] init];
  357. [ret setValue:[NSString stringWithFormat:@"%ld",(long)error.code] forKey:@"error_code"];
  358. [ret setValue:error.domain forKey:@"err_domain"];
  359. [ret setValue:[error localizedDescription] forKey:@"err_message"];
  360. // [ret setObject:error.userInfo forKey:@"user_info"];
  361. return ret;
  362. }
  363. +(NSString*) current_date
  364. {
  365. NSDate * date = [NSDate date];
  366. NSTimeInterval sec = [date timeIntervalSinceNow];
  367. NSDate * currentDate = [[NSDate alloc] initWithTimeIntervalSinceNow:sec];
  368. NSDateFormatter * df = [[NSDateFormatter alloc] init ];
  369. [df setDateFormat:@"MM/dd/yyyy HH:mm:ss"];
  370. NSString * na = [df stringFromDate:currentDate];
  371. return na;
  372. }
  373. +(NSString*) current_date_time
  374. {
  375. NSDate * date = [NSDate date];
  376. NSTimeInterval sec = [date timeIntervalSinceNow];
  377. NSDate * currentDate = [[NSDate alloc] initWithTimeIntervalSinceNow:sec];
  378. NSDateFormatter * df = [[NSDateFormatter alloc] init ];
  379. [df setDateFormat:@"MM/dd/yyyy HH:mm:ss"];
  380. NSString * na = [df stringFromDate:currentDate];
  381. return na;
  382. }
  383. +(NSString*) current_date_forfile
  384. {
  385. NSDate * date = [NSDate date];
  386. NSTimeInterval sec = [date timeIntervalSinceNow];
  387. NSDate * currentDate = [[NSDate alloc] initWithTimeIntervalSinceNow:sec];
  388. NSDateFormatter * df = [[NSDateFormatter alloc] init ];
  389. [df setDateFormat:@"MM_dd_yyyy_HH_mm_ss"];
  390. NSString * na = [df stringFromDate:currentDate];
  391. return na;
  392. }
  393. //+(void) message_alert :(NSString*) msg title:(NSString*) title controller:(UIViewController*) vc
  394. //{
  395. // if(title==nil)
  396. // title = @"Message";
  397. // if ([title isEqualToString:@"Add To Cart"]) {
  398. // if ([msg hasPrefix:@"Out of Stock.\n"]) {
  399. // title = @"Add To Cart: Out of Stock";
  400. // msg = [msg substringFromIndex:[@"Out of Stock.\n" length]];
  401. // }
  402. // }
  403. //
  404. //
  405. //
  406. // return [self alert_view:msg title:title];
  407. ////
  408. ////
  409. //// UIAlertController *alertControl = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert];
  410. //// //block代码块取代了delegate
  411. ////
  412. ////
  413. //// // [alertControl addTextFieldWithConfigurationHandler:^(UITextField *textField) {
  414. //// // textField.text = self.save_name;
  415. //// //
  416. //// //
  417. //// // }];
  418. ////
  419. //// // UIAlertAction *actionOne = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
  420. //// //
  421. //// // UIAlertController * waitalert = [RAUtils waiting_alert:self title:@"Delete Order"];
  422. //// // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  423. //// //
  424. //// // NSDictionary* return_json = [iSalesNetwork delete_Order:orderid];
  425. //// //
  426. //// // dispatch_async(dispatch_get_main_queue(), ^{
  427. //// // [waitalert dismissViewControllerAnimated:YES completion:nil];
  428. //// //
  429. //// //
  430. //// // if([[return_json valueForKey:@"result"] intValue]==2)
  431. //// // {
  432. //// //
  433. //// // [RAUtils error_alert:nil title:@"Order Delete"] ;
  434. //// // }
  435. //// // else
  436. //// // {
  437. //// // [RAUtils error_alert:[return_json valueForKey:@"err_msg"] title:@"Delete Order Failed."] ;
  438. //// // }
  439. //// //
  440. //// //
  441. //// //
  442. //// //
  443. //// // });
  444. //// // });
  445. //// //
  446. //// //
  447. //// // }];
  448. ////
  449. //// UIAlertAction *alertthree = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
  450. //// //DebugLog(@"Cancel");
  451. //// }];
  452. //// // [alertControl addAction:actionOne];
  453. ////
  454. //// [alertControl addAction:alertthree];
  455. ////
  456. ////
  457. //// UIAlertAction *alertcancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
  458. //// }];
  459. //// [alertControl addAction:alertcancel];
  460. //// //UIAlertControllerStyle类型为UIAlertControllerStyleAlert可以添加addTextFieldWithConfigurationHandler:^(UITextField *textField)
  461. ////
  462. ////
  463. ////
  464. ////
  465. //// [vc presentViewController:alertControl animated:YES completion:nil];
  466. ////
  467. ////
  468. ////
  469. //// return;
  470. ////
  471. ////
  472. //
  473. //
  474. //}
  475. //+(void) alert_view :(NSString*) msg title:(NSString*) title
  476. //{
  477. // if(title==nil)
  478. // title = NSLocalizedString(@"Message", @"Message");
  479. // if(msg.length>0)
  480. // {
  481. // title=[NSString stringWithFormat:@"%@\n\n%@",title,msg];
  482. // }
  483. // UIAlertView * alert = [[UIAlertView alloc] initWithTitle: title message:nil delegate:nil cancelButtonTitle:NSLocalizedString(@"Ok", @"Ok") otherButtonTitles:nil, nil];
  484. // [alert show];
  485. //}
  486. + (long long) freeDiskSpaceInMegaBytes{
  487. struct statfs buf;
  488. long long freespace = -1;
  489. if(statfs("/var", &buf) >= 0){
  490. freespace = (long long)(buf.f_bsize * buf.f_bfree);
  491. }
  492. DebugLog(@"手机剩余存储空间为:%qi MB" ,freespace/1024/1024);
  493. return freespace/1024/1024;
  494. }
  495. //+(UIAlertController*) waiting_alert:(UIViewController*)parent title:(NSString*) title
  496. //{
  497. // UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:@"Please wait..." preferredStyle:UIAlertControllerStyleAlert];
  498. //
  499. //// [parent presentModalViewController:alertController animated:YES];
  500. // [parent presentViewController:alertController animated:YES completion:nil];
  501. // return alertController;
  502. //
  503. //}
  504. +(UIAlertController*) waiting_alert:(UIViewController*)parent title:(NSString*) title completion:(void (^ __nullable)(void))completion
  505. {
  506. return [self waiting_alert:parent message:@"Please wait..." title:title completion:completion];
  507. // UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:@"Please wait..." preferredStyle:UIAlertControllerStyleAlert];
  508. //
  509. // [parent presentViewController:alertController animated:YES completion:completion];
  510. // return alertController;
  511. }
  512. //+(UIAlertController*) waiting_alert:(UIViewController*)parent message:(NSString*)msg title:(NSString*) title
  513. //{
  514. // UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
  515. // [parent presentViewController:alertController animated:YES completion:nil];
  516. // return alertController;
  517. //
  518. //}
  519. +(UIAlertController*) waiting_alert:(UIViewController*)parent message:(NSString*)msg title:(NSString*) title completion:(void (^ __nullable)(void))completion
  520. {
  521. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
  522. [parent presentViewController:alertController animated:YES completion:completion];
  523. NSLog(@"show waiting alert %p",alertController);
  524. return alertController;
  525. }
  526. +(UIAlertController*) message_alert :(NSString*) msg title:(NSString*) title controller:(UIViewController*) vc
  527. {
  528. if(title==nil)
  529. title = @"Message";
  530. if ([title isEqualToString:@"Add To Cart"]) {
  531. if ([msg hasPrefix:@"Out of Stock.\n"]) {
  532. title = @"Add To Cart: Out of Stock";
  533. msg = [msg substringFromIndex:[@"Out of Stock.\n" length]];
  534. }
  535. }
  536. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
  537. UIAlertAction *action_0 = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
  538. [alertController addAction:action_0];
  539. [vc presentViewController:alertController animated:YES completion:nil];
  540. NSLog(@"show message alert %p",alertController);
  541. return alertController;
  542. }
  543. +(UIAlertController*) message_alert :(NSString*) msg title:(NSString*) title controller:(UIViewController*) vc action_handler:(void (^ __nullable)(UIAlertAction *action))action_handler completion:(void (^ __nullable)(void))completion
  544. {
  545. if(title==nil)
  546. title = @"Message";
  547. if ([title isEqualToString:@"Add To Cart"]) {
  548. if ([msg hasPrefix:@"Out of Stock.\n"]) {
  549. title = @"Add To Cart: Out of Stock";
  550. msg = [msg substringFromIndex:[@"Out of Stock.\n" length]];
  551. }
  552. }
  553. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
  554. UIAlertAction *action_0 = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:action_handler];
  555. [alertController addAction:action_0];
  556. [vc presentViewController:alertController animated:YES completion:completion];
  557. NSLog(@"show message alert %p",alertController);
  558. return alertController;
  559. }
  560. //+(UIAlertView * ) waiting_alert :(NSString*) msg title:(NSString*) title
  561. //{
  562. // if(title==nil)
  563. // title = @"Please Wait";
  564. // if(msg==nil)
  565. // msg= @"Waiting...";
  566. // NSAssert(msg!=nil, @"error message from json is nil");
  567. // UIAlertView * alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil];
  568. // [alert show];
  569. // //
  570. // //
  571. // // UIActivityIndicatorView *aiView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(125.0, 80.0, 30.0, 30.0)];
  572. // // aiView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
  573. // // // check if os version is 7 or above. ios7.0及以上UIAlertView弃用了addSubview方法
  574. // //// if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending) {
  575. // //// [alert setValue:aiView forKey:@"accessoryView"];
  576. // //// }else{
  577. // //// [alert addSubview:aiView];
  578. // //// }
  579. // //
  580. // // aiView.hidden = false;
  581. // // aiView.hidesWhenStopped = false;
  582. // // [aiView startAnimating];
  583. // //
  584. // //[alert addSubview:aiView];
  585. //
  586. // return alert;
  587. // //return nil;
  588. // // return alert;
  589. // // UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Error!" message:@"User&Password can not be empty!" delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", nil) , nil];
  590. // //[alert show];
  591. //}
  592. +(NSDictionary*) device_info
  593. {
  594. NSDictionary* infoDict =[[NSBundle mainBundle] infoDictionary];
  595. NSString* build =[infoDict objectForKey:@"CFBundleVersion"];
  596. NSString* version =[infoDict objectForKey:@"CFBundleShortVersionString"];
  597. NSString* versionNum = [NSString stringWithFormat:@"Version: %@ Build %@",version,build];
  598. NSMutableDictionary * info = [[NSMutableDictionary alloc]init];
  599. [info setValue:[[UIDevice currentDevice] name] forKey:@"name"];
  600. [info setValue:[[UIDevice currentDevice] systemVersion] forKey:@"systemVersion"];
  601. [info setValue:[[UIDevice currentDevice] model] forKey:@"model"];
  602. [info setValue:versionNum forKey:@"ver"];
  603. [info setValue:[[UIDevice currentDevice] localizedModel] forKey:@"localizedModel"];
  604. return info;
  605. // [info setValue:[[UIDevice currentDevice] name] forKey:@"name"];
  606. // [info setValue:[[UIDevice currentDevice] name] forKey:@"name"];
  607. // [info setValue:[[UIDevice currentDevice] name] forKey:@"name"];
  608. }
  609. + (NSString *)deviceID {
  610. UIDevice * dev = [UIDevice currentDevice];
  611. NSUUID* uuid =dev.identifierForVendor;
  612. return uuid.UUIDString;
  613. }
  614. //+(NSArray*) string2arr:(NSString*) string separator:(NSString*)separator
  615. //{
  616. // NSArray *stringArray = [string componentsSeparatedByString:separator];
  617. //
  618. // return stringArray;
  619. //}
  620. +(NSDictionary*) string2dict:(NSString*) str
  621. {
  622. if(str==nil)
  623. return nil;
  624. NSError *error = nil;
  625. NSDictionary *string2dic = [NSJSONSerialization JSONObjectWithData: [str dataUsingEncoding:NSUTF8StringEncoding]
  626. options: NSJSONReadingMutableContainers
  627. error: &error];
  628. DebugLog(@"%@",string2dic);
  629. return string2dic;
  630. }
  631. +(UIColor*) strColor:(NSString*) color
  632. {
  633. if([color.lowercaseString isEqualToString:@"red"])
  634. return [UIColor redColor];
  635. return [UIColor blackColor];
  636. }
  637. +(NSString*) base64en:(NSString*) string
  638. {
  639. if(string == nil)
  640. return nil;
  641. NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
  642. NSString *stringBase64 = [data base64EncodedStringWithOptions:0]; // base64格式的字符串
  643. return stringBase64;
  644. }
  645. +(NSString*) base64de:(NSString*) stringBase64
  646. {
  647. if(stringBase64==nil)
  648. return nil;
  649. NSData *data = [[NSData alloc] initWithBase64EncodedString:stringBase64 options:NSDataBase64DecodingIgnoreUnknownCharacters];
  650. NSString *string =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  651. return string;
  652. }
  653. +(void) deletefiles :(NSString*) path
  654. {
  655. // NSString *extension = @"m4r";
  656. NSFileManager *fileManager = [NSFileManager defaultManager];
  657. // NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  658. // NSString *documentsDirectory = [paths objectAtIndex:0];
  659. NSArray *contents = [fileManager contentsOfDirectoryAtPath:path error:NULL];
  660. NSEnumerator *e = [contents objectEnumerator];
  661. NSString *filename;
  662. while ((filename = [e nextObject])) {
  663. bool result= [fileManager removeItemAtPath:[path stringByAppendingPathComponent:filename] error:NULL];
  664. if(!result)
  665. DebugLog(@"delete file failed %@------%@",path,filename);
  666. }
  667. }
  668. +(NSMutableArray*)dictionary2array:(NSDictionary*)json count_fields:(NSString*) count_fields item_mark:(NSString*) item_mark items_mark:(NSString* )items_mark
  669. {
  670. if(json==nil)
  671. return nil;
  672. NSMutableArray* ret = [[NSMutableArray alloc] init];
  673. int count = [[json valueForKey:count_fields] intValue];
  674. NSDictionary* items = nil;
  675. if(items_mark==nil)
  676. items = json;
  677. else
  678. items = [json objectForKey:items_mark];
  679. for(int i=0;i<count;i++)
  680. {
  681. NSDictionary* obj = [items objectForKey:[NSString stringWithFormat:@"%@%d",item_mark,i]];
  682. [ret addObject:obj];
  683. }
  684. return ret;
  685. }
  686. +(NSDictionary*) error_json :(int)code err_msg:(NSString*)msg
  687. {
  688. NSMutableDictionary* ret = [[NSMutableDictionary alloc] init];
  689. //#define RESULT_FALSE 0
  690. //#define RESULT_TRUE 2
  691. //#define RESULT_NET_ERROR -3
  692. //#define RESULT_NET_NOTAVAILABLE -4
  693. //#define RESULT_ERROR -5
  694. //#define RESULT_LOCALFILE_ERROR -7
  695. //#define RESULT_USERAUTH_ERROR -9
  696. //#define RESULT_UPDATE_USERAUTH_ERROR -11
  697. //#define RESULT_SESSION_EXPIRED -13
  698. //#define RESULT_VER_LOW
  699. if(msg.length<=0)
  700. {
  701. switch (code) {
  702. case RESULT_NET_NOTAVAILABLE:
  703. msg= MSG_NET_NOTAVAILABLE;
  704. break;
  705. default:
  706. // assert(@"UNDEFINE ERROR CODE!");
  707. break;
  708. }
  709. }
  710. // if(code==RESULT_NET_NOTAVAILABLE)
  711. // [ret setValue:[NSString stringWithFormat:@"%d",RESULT_NET_ERROR] forKey:@"result"];
  712. // else
  713. [ret setValue:[NSString stringWithFormat:@"%d",code] forKey:@"result"];
  714. [ret setValue:msg forKey:@"err_msg"];
  715. // NSData *jsonData = [NSJSONSerialization dataWithJSONObject:ret
  716. // options:0
  717. // error:nil];
  718. return ret;
  719. }
  720. + (BOOL)isNumeric:(NSString*)string{
  721. NSScanner* scan = [NSScanner scannerWithString:string];
  722. int val;
  723. return[scan scanInt:&val] && [scan isAtEnd];
  724. }
  725. + (CGRect)relativeFrame:(CGRect) frame FromView:(UIView *)v toView:(UIView*)tv
  726. {
  727. return [v convertRect: frame toView:tv];
  728. }
  729. + (CGRect)relativeFrameForScreenWithView:(UIView *)v
  730. {
  731. UIWindow * window=[[[UIApplication sharedApplication] delegate] window];
  732. CGRect rect=[v convertRect: v.bounds toView:window];
  733. return rect;
  734. // BOOL iOS7 = [[[UIDevice currentDevice] systemVersion] floatValue] >= 7;
  735. //
  736. // CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
  737. // if (!iOS7) {
  738. // screenHeight -= 20;
  739. // }
  740. // UIView *view = v;
  741. // CGFloat x = .0;
  742. // CGFloat y = .0;
  743. // while (view.frame.size.width != 320 || view.frame.size.height != screenHeight) {
  744. // x += view.frame.origin.x;
  745. // y += view.frame.origin.y;
  746. // view = view.superview;
  747. // if ([view isKindOfClass:[UIScrollView class]]) {
  748. // x -= ((UIScrollView *) view).contentOffset.x;
  749. // y -= ((UIScrollView *) view).contentOffset.y;
  750. // }
  751. // }
  752. // return CGRectMake(x, y, v.frame.size.width, v.frame.size.height);
  753. }
  754. + (BOOL)saveData:(NSData *)data toPath:(NSString *)path {
  755. // NSString *directory = [path stringByDeletingLastPathComponent];
  756. NSFileManager *manager = [NSFileManager defaultManager];
  757. NSString *dir = [path stringByDeletingLastPathComponent];
  758. BOOL create = [manager createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
  759. if (create) {
  760. BOOL save = [manager createFileAtPath:path contents:data attributes:nil];
  761. if (save) {
  762. return YES;
  763. }
  764. return NO;
  765. }
  766. return NO;
  767. }
  768. + (void)removeFileAtPath:(NSString *)path {
  769. if (!path.length) {
  770. return;
  771. }
  772. NSFileManager *manager = [NSFileManager defaultManager];
  773. [manager removeItemAtPath:path error:nil];
  774. }
  775. + (NSString *)appCacheDirectory {
  776. return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
  777. }
  778. +(NSString*)md5WithFile:(NSString*)path
  779. {
  780. return (__bridge_transfer NSString *)FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
  781. }
  782. CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath,size_t chunkSizeForReadingData) {
  783. // Declare needed variables
  784. CFStringRef result = NULL;
  785. CFReadStreamRef readStream = NULL;
  786. // Get the file URL
  787. CFURLRef fileURL =
  788. CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
  789. (CFStringRef)filePath,
  790. kCFURLPOSIXPathStyle,
  791. (Boolean)false);
  792. if (!fileURL) goto done;
  793. // Create and open the read stream
  794. readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault,
  795. (CFURLRef)fileURL);
  796. if (!readStream) goto done;
  797. bool didSucceed = (bool)CFReadStreamOpen(readStream);
  798. if (!didSucceed) goto done;
  799. // Initialize the hash object
  800. CC_MD5_CTX hashObject;
  801. CC_MD5_Init(&hashObject);
  802. // Make sure chunkSizeForReadingData is valid
  803. if (!chunkSizeForReadingData) {
  804. chunkSizeForReadingData = FileHashDefaultChunkSizeForReadingData;
  805. }
  806. // Feed the data to the hash object
  807. bool hasMoreData = true;
  808. while (hasMoreData) {
  809. uint8_t buffer[chunkSizeForReadingData];
  810. CFIndex readBytesCount = CFReadStreamRead(readStream,(UInt8 *)buffer,(CFIndex)sizeof(buffer));
  811. if (readBytesCount == -1) break;
  812. if (readBytesCount == 0) {
  813. hasMoreData = false;
  814. continue;
  815. }
  816. CC_MD5_Update(&hashObject,(const void *)buffer,(CC_LONG)readBytesCount);
  817. }
  818. // Check if the read operation succeeded
  819. didSucceed = !hasMoreData;
  820. // Compute the hash digest
  821. unsigned char digest[CC_MD5_DIGEST_LENGTH];
  822. CC_MD5_Final(digest, &hashObject);
  823. // Abort if the read operation failed
  824. if (!didSucceed) goto done;
  825. // Compute the string result
  826. char hash[2 * sizeof(digest) + 1];
  827. for (size_t i = 0; i < sizeof(digest); ++i) {
  828. snprintf(hash + (2 * i), 3, "%02x", (int)(digest[i]));
  829. }
  830. result = CFStringCreateWithCString(kCFAllocatorDefault,(const char *)hash,kCFStringEncodingUTF8);
  831. done:
  832. if (readStream) {
  833. CFReadStreamClose(readStream);
  834. CFRelease(readStream);
  835. }
  836. if (fileURL) {
  837. CFRelease(fileURL);
  838. }
  839. return result;
  840. }
  841. + (BOOL)fileExistsAtPath:(NSString *)path {
  842. NSFileManager *fm = [NSFileManager defaultManager];
  843. return [fm fileExistsAtPath:path];
  844. return NO;
  845. }
  846. + (NSString *)htmlForVideo:(NSString*) iframeCode template:(NSString*) path
  847. {
  848. if(path==nil)
  849. path=[[NSBundle mainBundle] pathForResource:@"photostack_video" ofType:@"html"];
  850. NSString* tempate = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
  851. if(tempate==nil)
  852. return @"";
  853. // NSData *imageData = UIImageJPEGRepresentation(image,1.0);
  854. // NSString *imageSource = [NSString stringWithFormat:@"data:image/jpg;base64,%@",[imageData base64Encoding]];
  855. // imageSource=[NSString stringWithFormat:@"<img src = \"%@\" />", imageSource];
  856. tempate= [tempate stringByReplacingOccurrencesOfString:@"##replacement##" withString:iframeCode];
  857. return tempate;
  858. }
  859. + (NSString *)htmlForImage:(UIImage *)image template:(NSString*) path
  860. {
  861. if(path==nil)
  862. path=[[NSBundle mainBundle] pathForResource:@"photostack_image" ofType:@"html"];
  863. NSString* tempate = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
  864. if(tempate==nil)
  865. return @"";
  866. NSData *imageData = UIImageJPEGRepresentation(image,1.0);
  867. // NSString *imageSource = [NSString stringWithFormat:@"data:image/jpg;base64,%@",[imageData base64Encoding]];
  868. NSString *imageSource = [NSString stringWithFormat:@"data:image/jpg;base64,%@",[imageData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]];
  869. imageSource=[NSString stringWithFormat:@"<img src = \"%@\" />", imageSource];
  870. tempate= [tempate stringByReplacingOccurrencesOfString:@"##replacement##" withString:imageSource];
  871. return tempate;
  872. }
  873. + (nullable NSString *)md5:(nullable NSString *)str {
  874. if (!str) return nil;
  875. const char *cStr = str.UTF8String;
  876. unsigned char result[CC_MD5_DIGEST_LENGTH];
  877. CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
  878. NSMutableString *md5Str = [NSMutableString string];
  879. for (int i = 0; i < CC_MD5_DIGEST_LENGTH; ++i) {
  880. [md5Str appendFormat:@"%02x", result[i]];
  881. }
  882. return md5Str;
  883. }
  884. + (void)ra_showAlertTitle:(NSString *)title message:(NSString *)msg withViewController:(UIViewController *)vc {
  885. if (vc) {
  886. UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
  887. UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  888. }];
  889. [alertVC addAction:okAction];
  890. [vc presentViewController:alertVC animated:YES completion:nil];
  891. NSLog(@"show alerttitle alert %p",alertVC);
  892. }
  893. }
  894. + (CGSize)sizeWithFont:(NSString*)string font:(UIFont *)font constrainedToSize:(CGSize)maxsize lineBreakMode:(NSLineBreakMode)lineBreakMode
  895. {
  896. if(string.length==0)
  897. return CGSizeZero;
  898. // Let's make an NSAttributedString first
  899. NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];
  900. //Add LineBreakMode
  901. NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
  902. [paragraphStyle setLineBreakMode:lineBreakMode];
  903. [attributedString setAttributes:@{NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, attributedString.length)];
  904. // Add Font
  905. [attributedString setAttributes:@{NSFontAttributeName:font} range:NSMakeRange(0, attributedString.length)];
  906. //Now let's make the Bounding Rect
  907. CGSize expectedSize = [attributedString boundingRectWithSize:maxsize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
  908. return expectedSize;
  909. }
  910. + (BOOL) validateEmail:(NSString *)email
  911. {
  912. NSString *regex1 = @"\\A[a-z0-9]+([-._][a-z0-9]+)*@([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,4}\\z";
  913. NSString *regex2 = @"^(?=.{1,64}@.{4,64}$)(?=.{6,100}$).*";
  914. NSPredicate *test1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex1];
  915. NSPredicate *test2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex2];
  916. return [test1 evaluateWithObject:email] && [test2 evaluateWithObject:email];
  917. }
  918. + (BOOL)checkPassword:(NSString *) password
  919. {
  920. NSString *pattern = @"^(?![0-9]+$)(?![a-zA-Z]+$)[a-zA-Z0-9]{8,16}";
  921. // NSString *pattern1 = @"^(?=.*)(?=.*[a-z])(?=.*[~!@#$%^&*:;,.=?$\x22]).{8,16}$";
  922. NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
  923. // NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern1];
  924. BOOL isMatch = [pred evaluateWithObject:password];//||[pred evaluateWithObject:password];
  925. return isMatch;
  926. }
  927. + (UIViewController *)getCurrentVC
  928. {
  929. UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
  930. UIViewController *currentVC = [self getCurrentVCFrom:rootViewController];
  931. return currentVC;
  932. }
  933. + (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC
  934. {
  935. UIViewController *currentVC;
  936. if ([rootVC presentedViewController]) {
  937. // 视图是被presented出来的
  938. rootVC = [rootVC presentedViewController];
  939. }
  940. if ([rootVC isKindOfClass:[UITabBarController class]]) {
  941. // 根视图为UITabBarController
  942. currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
  943. } else if ([rootVC isKindOfClass:[UINavigationController class]]){
  944. // 根视图为UINavigationController
  945. currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
  946. } else {
  947. // 根视图为非导航类
  948. currentVC = rootVC;
  949. }
  950. return currentVC;
  951. }
  952. @end