AppDelegate.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. //
  2. // AppDelegate.m
  3. // AntsContract
  4. //
  5. // Created by Ray on 12/16/16.
  6. // Copyright © 2016 United Software Applications, Inc. All rights reserved.
  7. //
  8. #import "AppDelegate.h"
  9. #import "ACNetwork.h"
  10. #import "TextUtils.h"
  11. #import "PDFUtils.h"
  12. #import "RAUtils.h"
  13. #import "AddExtDocumentViewController.h"
  14. #import "LoginViewController.h"
  15. #import "RootViewController.h"
  16. //#import "AFHTTPSessionManager.h"
  17. @interface AppDelegate ()
  18. @property (nonatomic,strong) NSTimer *heartBeat;
  19. @end
  20. @implementation AppDelegate
  21. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  22. // Override point for customization after application launch.
  23. self.accessMode = AppAccessModeOnline;
  24. self.bEnable_Cache = true;
  25. [self function_test];
  26. return YES;
  27. }
  28. -(NSString*) filetype:(NSString*)filePath
  29. {
  30. NSString *suffix = [filePath pathExtension];
  31. if([suffix.lowercaseString isEqualToString:@"jpg"]||[suffix.lowercaseString isEqualToString:@"png"]||[suffix.lowercaseString isEqualToString:@"bmp"]||[suffix.lowercaseString isEqualToString:@"gif"])
  32. return @"image";
  33. else
  34. return @"file";
  35. }
  36. - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options
  37. {
  38. NSLog(@"URL:%@, OPTIONS:%@",[url absoluteString],[RAUtils dict2string:options]);
  39. NSMutableDictionary* item = [[NSMutableDictionary alloc] init];
  40. item[@"type"]=[self filetype:url.absoluteString];
  41. item[@"url"]= [url path];
  42. item[@"file_name"] = [url.absoluteString lastPathComponent];
  43. if(self.bLogin)
  44. {
  45. [self checkSelfWindowIsKeyWindow];
  46. UINavigationController *rootVC = (UINavigationController *)application.keyWindow.rootViewController;
  47. UIViewController* presentVC=rootVC.presentedViewController;
  48. AddExtDocumentViewController * addVC;
  49. if([presentVC isKindOfClass:[UINavigationController class]])
  50. {
  51. //如果当前已有模态对话框,则关闭当前的模态框,否则无法弹出上传框。
  52. UIViewController* topvc= ((UINavigationController*)presentVC).topViewController;
  53. if([topvc isKindOfClass:[AddExtDocumentViewController class]])
  54. {
  55. addVC = (AddExtDocumentViewController*)topvc;
  56. if(addVC.arr_documents==nil)
  57. addVC.arr_documents = [NSMutableArray arrayWithObjects:item, nil];
  58. else
  59. [addVC.arr_documents addObject:item];
  60. [addVC refresh_table];
  61. }
  62. else
  63. [presentVC dismissViewControllerAnimated:false completion:nil];
  64. }
  65. else
  66. {
  67. addVC = [ [UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"AddExtDocumentViewController"];
  68. addVC.is_present = true;
  69. addVC.doc_number = nil;
  70. addVC.arr_documents = [NSMutableArray arrayWithObjects:item, nil];
  71. UINavigationController* navi = [[UINavigationController alloc] initWithRootViewController:addVC] ;
  72. navi.modalPresentationStyle = UIModalPresentationFormSheet;//有三种状态,自己看看是哪种
  73. [rootVC presentViewController:navi animated:YES completion:^{
  74. // navi.view.superview.bounds = CGRectMake(0, 0, 480, 320);
  75. DebugLog(@"filter present.........");
  76. // self.btop = false;
  77. // <#code#>
  78. }];
  79. }
  80. }
  81. else
  82. {
  83. self.shareFile = item;
  84. [self checkSelfWindowIsKeyWindow];
  85. UINavigationController *rootVC = (UINavigationController *)application.keyWindow.rootViewController;
  86. RootViewController* topvc= (RootViewController*)rootVC.topViewController;
  87. UIViewController* presentVC=rootVC.presentedViewController;
  88. // AddExtDocumentViewController * addVC;
  89. if(!presentVC)//([presentVC isKindOfClass:[UINavigationController class]])
  90. {
  91. //未弹出login 框
  92. [topvc presentLogin:topvc.ibSignin];
  93. }
  94. }
  95. // [ pushViewController:addVC animated:false];
  96. // return YES;
  97. return YES;
  98. }
  99. -(void)function_test
  100. {
  101. return;
  102. printf("function test======================");
  103. // NSString* pdffile = [PDFUtils SavePDF:nil source:nil window_rect:CGRectMake(0, 0, 768, 960)];
  104. // [PDFUtils leak_test];
  105. // 获取路径
  106. NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);//坐标
  107. NSString *saveDirectory=[paths objectAtIndex:0];
  108. NSString *saveFileName=[NSString stringWithFormat:@"%@.pdf",[[NSUUID UUID ] UUIDString] ] ;;
  109. NSString *newFilePath=[saveDirectory stringByAppendingPathComponent:saveFileName];
  110. const char *filename=[newFilePath UTF8String];
  111. NSLog(@"%@",newFilePath);
  112. //设置页面大小 Letter纸
  113. CFStringRef path;
  114. CFURLRef url;
  115. path=CFStringCreateWithCString(NULL, filename, kCFStringEncodingUTF8);
  116. url=CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0);
  117. CFRelease(path);
  118. // CGPDFCONTEXTCREATE
  119. CGContextRef pdfContext;
  120. CGRect docsize = CGRectMake(0, 0, 612, 1008);
  121. CFMutableDictionaryRef myDictionary = NULL;
  122. myDictionary= CFDictionaryCreateMutable(NULL,
  123. 0,
  124. NULL,
  125. NULL);
  126. CFDictionarySetValue(myDictionary, kCGPDFContextOwnerPassword, CFSTR("usai2010"));
  127. CFDictionarySetValue(myDictionary, kCGPDFContextAllowsPrinting, kCFBooleanTrue);
  128. CFDictionarySetValue(myDictionary, kCGPDFContextAllowsCopying, kCFBooleanFalse);
  129. pdfContext=CGPDFContextCreateWithURL(url, &docsize,myDictionary);
  130. CFRelease(myDictionary);
  131. CFRelease(url);
  132. CGContextBeginPage(pdfContext, &docsize);
  133. // cgpdfpage
  134. CGContextEndPage(pdfContext);
  135. CGPDFContextClose(pdfContext);
  136. CGContextRelease(pdfContext);
  137. return ;
  138. }
  139. - (void)applicationWillResignActive:(UIApplication *)application {
  140. // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
  141. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
  142. }
  143. - (void)applicationDidEnterBackground:(UIApplication *)application {
  144. // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
  145. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
  146. [self stopHeartBeat];
  147. }
  148. - (void)applicationWillEnterForeground:(UIApplication *)application {
  149. // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
  150. }
  151. - (void)applicationDidBecomeActive:(UIApplication *)application {
  152. // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
  153. if (self.bLogin && !self.heartBeat) {
  154. [self startHeartBeat];
  155. }
  156. }
  157. - (void)applicationWillTerminate:(UIApplication *)application {
  158. // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
  159. }
  160. -(void) Login:(NSString* )user pwd:(NSString*) pwd canModify:(bool) canModify offPrefix:(NSString*) offPrefix
  161. {
  162. // self.bCanModify = canModify;
  163. // self.offPrefix = offPrefix;
  164. self.user = user;
  165. self.password = pwd;
  166. self.bLogin = true;
  167. self.accessMode = AppAccessModeOnline;
  168. // 延迟1s启动心跳,以避免在登录框还在Dismiss动画过程中再次调用Dismiss
  169. __weak typeof(self) weakself = self;
  170. dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
  171. dispatch_after(time, dispatch_get_main_queue(), ^{
  172. [weakself heartBeatRightNow:YES];
  173. });
  174. }
  175. -(void) SwitchToOffline:(NSString* )user
  176. {
  177. self.accessMode = AppAccessModeOffline;
  178. // self.bCanModify = false;
  179. //self.offPrefix = offPrefix;
  180. self.user = user;
  181. self.password = user;
  182. self.bLogin = true;
  183. }
  184. -(void) Logout
  185. {
  186. // MainViewController * main_vc= (MainViewController*)self.main_vc;
  187. // [main_vc logoutOrder];
  188. //
  189. //
  190. // [main_vc hideMenu];
  191. // [main_vc switchToHome];
  192. self.user = nil;
  193. // self.bCanModify = false;
  194. // self.offPrefix = nil;
  195. self.password=nil;
  196. self.bLogin = false;
  197. [self stopHeartBeat];
  198. // self.user_icon=nil;
  199. // self.user_type = USER_ROLE_UNKNOWN;
  200. // self.bLogin = false;
  201. // self.contact_id=nil;
  202. // self.customerInfo = nil;
  203. // self.order_code = nil;
  204. //
  205. // [self.recent_model removeAllObjects];
  206. //
  207. // [self SetMode:nil];
  208. }
  209. #pragma mark - HeartBeat
  210. - (void)markHeartBeatTime {
  211. NSDate *date = [NSDate date];
  212. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  213. [userDefaults setValue:date forKey:@"heartBeatTime"];
  214. [userDefaults synchronize];
  215. }
  216. - (BOOL)checkHearBeatTimeOut {
  217. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  218. // 前一次成功心跳的时间
  219. NSDate *preTime = [userDefaults valueForKey:@"heartBeatTime"];
  220. if (preTime) {
  221. NSDate *curTime = [NSDate date];
  222. NSTimeInterval timeInterval = [curTime timeIntervalSinceDate:preTime];
  223. NSTimeInterval timeOutInterval = 1 * 60 * 60;
  224. #ifdef DEBUG
  225. timeOutInterval = 1 * 60;
  226. #endif
  227. if (timeInterval > timeOutInterval) {
  228. return YES;
  229. }
  230. }
  231. return NO;
  232. }
  233. - (void)heartBeatRightNow:(BOOL)rightNow {
  234. if (rightNow) {
  235. [self heartBeatAction:nil];
  236. }
  237. // if(self.heartBeat) {
  238. // self.heartBeat.fireDate = [NSDate distantPast];
  239. // return;
  240. // }
  241. NSTimeInterval heartBeatTimeInterval = 3 * 60;
  242. #ifdef DEBUG
  243. heartBeatTimeInterval = 30;
  244. #endif
  245. __weak typeof(self) weakself = self;
  246. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  247. if (weakself.heartBeat) {
  248. [weakself.heartBeat invalidate];
  249. weakself.heartBeat = nil;
  250. }
  251. weakself.heartBeat = [NSTimer scheduledTimerWithTimeInterval:heartBeatTimeInterval target:weakself selector:@selector(heartBeatAction:) userInfo:nil repeats:YES];
  252. [[NSRunLoop currentRunLoop] addTimer:weakself.heartBeat forMode:NSDefaultRunLoopMode];
  253. [[NSRunLoop currentRunLoop] run];
  254. });
  255. }
  256. - (void)startHeartBeat {
  257. [self heartBeatRightNow:YES];
  258. }
  259. - (void)stopHeartBeat {
  260. if (self.heartBeat) {
  261. // self.heartBeat.fireDate = [NSDate distantFuture];
  262. [self.heartBeat invalidate];
  263. self.heartBeat = nil;
  264. }
  265. }
  266. - (void)checkSelfWindowIsKeyWindow {
  267. UIApplication *application = [UIApplication sharedApplication];
  268. if (![self.window isEqual:application.keyWindow]) {
  269. UIWindow *window = application.keyWindow;
  270. [window resignKeyWindow];
  271. if (window.superview) {
  272. [window removeFromSuperview];
  273. }
  274. window.hidden = YES;
  275. window = nil;
  276. [self.window makeKeyWindow];
  277. }
  278. }
  279. - (void)heartBeatTimeout {
  280. __weak typeof(self) weakself = self;
  281. dispatch_async(dispatch_get_main_queue(), ^{
  282. UIApplication *application = [UIApplication sharedApplication];
  283. // 超时登出,登出中停止心跳
  284. [weakself Logout];
  285. if (![weakself.window isEqual:application.keyWindow]) {
  286. UIWindow *window = application.keyWindow;
  287. [window resignKeyWindow];
  288. if (window.superview) {
  289. [window removeFromSuperview];
  290. }
  291. window.hidden = YES;
  292. window = nil;
  293. [weakself.window makeKeyWindow];
  294. }
  295. UINavigationController *rootVC = (UINavigationController *)application.keyWindow.rootViewController;
  296. // 提示登录
  297. UIViewController* presentVC=rootVC.presentedViewController;
  298. if (presentVC && ![presentVC isKindOfClass:[LoginViewController class]]) { //如果当前已有非Login模态对话框,则关闭当前的模态框
  299. [presentVC dismissViewControllerAnimated:NO completion:^{
  300. // 退回到初始视图
  301. // [rootVC popToRootViewControllerAnimated:NO];
  302. // RootViewController* topvc= (RootViewController*)rootVC.topViewController;
  303. // [topvc dealWithUILogout];
  304. // // viewDidAppear会自动Present
  305. //// dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 0.25 * NSEC_PER_SEC);
  306. //// dispatch_after(time, dispatch_get_main_queue(), ^{
  307. //// [topvc presentLogin:topvc.ibSignin];
  308. //// });
  309. // 递归解决多重Present后,dimiss不完全。
  310. [weakself heartBeatTimeout];
  311. }];
  312. } else {
  313. if (rootVC.viewControllers.count > 1) {
  314. // 退回到初始视图
  315. [rootVC popToRootViewControllerAnimated:NO];
  316. }
  317. RootViewController* topvc= (RootViewController*)rootVC.topViewController;
  318. [topvc dealWithUILogout];
  319. dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 0.25 * NSEC_PER_SEC);
  320. dispatch_after(time, dispatch_get_main_queue(), ^{
  321. [topvc presentLogin:topvc.ibSignin];
  322. });
  323. }
  324. });
  325. }
  326. - (void)heartBeatAction:(NSTimer *)timer {
  327. // 离线状态下不发心跳包
  328. if (self.accessMode == AppAccessModeOffline) return;
  329. __weak typeof(self) weakself = self;
  330. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  331. int result = [ACNetwork heartBeat];
  332. // int result = 2;
  333. if (result == 2) {
  334. // 心跳成功才处理计时
  335. [self markHeartBeatTime];
  336. } else if (result == 4) { // 心跳超时
  337. [weakself heartBeatTimeout];
  338. } else if ([weakself checkHearBeatTimeOut]) {// 本地检查超时(上一次成功心跳距现在的间隔时间超出1h)
  339. // 本地不检查超时!!!不能知道后台设置的超时时长
  340. // [weakself heartBeatTimeout];
  341. }
  342. NSLog(@"heart beat result %d",result);
  343. });
  344. }
  345. - (void)dealloc {
  346. [self stopHeartBeat];
  347. }
  348. @end