// // AppDelegate.m // watch // // Created by xTT on 2017/7/3. // Copyright © 2017年 xTT. All rights reserved. // #import "AppDelegate.h" #import #import "CallViewController.h" //微信SDK头文件 #import //#import "WXApiObject.h" #import "IQKeyboardManager.h" #import "SVProgressHUD.h" #import "User.h" //用于消息震动 #import #import #import "ChatViewController.h" #import "MessageViewController.h" #import "RemoteCameraViewController.h" #import #import #import "NdUncaughtExceptionHandler.h" #import "Bluetooth.h" #import "MyTabBarViewController.h" #import "LoginViewController.h" // VoIP 推送 #import #import "GCDTimerManager.h" #import "WCUpVersionView.h" #define kMusicTime 20 #define videoTimerCount 3 @interface AppDelegate () @property (nonatomic, strong) CLLocationManager *locationManager; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //MARK: 标记APP 的状态是活着 NSUserDefaults* userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.tongxin"]; [userDefault setValue:@"童信APP活着的状态" forKey:@"APPStatus"]; self.window.backgroundColor = [UIColor whiteColor]; // Override point for customization after application launch. //NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 repeats:NO block:^(NSTimer * _Nonnull timer) { // application.statusBarHidden = NO; //}]; //[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; // MARK: add by lsz 2021-06-29 dispatch_time_t timer = dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC); dispatch_after(timer, dispatch_get_main_queue(), ^{ application.statusBarHidden = NO; }); self.isTouch = YES; //初始化微信 [[APHandleManager sharedManager] registerHandle]; //异常信息处理捕获 //[NdUncaughtExceptionHandler setDefaultHandler]; //@try { // NSArray *array = [NSArray arrayWithObject:@"there is only one objective in this arary,call index one, app will crash and throw an exception!"]; // NSLog(@"%@", [array objectAtIndex:1]); //} @catch (NSException *exception) { // //} //高德 poi 搜索 [AMapServices sharedServices].apiKey = AMapKey; // [MAMapView updatePrivacyShow:AMapPrivacyShowStatusDidShow privacyInfo:AMapPrivacyInfoStatusDidContain]; // [MAMapView updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree]; // [AMapSearchAPI updatePrivacyShow:(AMapPrivacyShowStatusDidShow) privacyInfo:(AMapPrivacyInfoStatusDidContain)]; [self initIQKeyBorard];//键盘自动调整 if(CurrentSystemVersion.doubleValue < 13.0){ //ios 13.0 以下的系统注册 VOIP [self initPushKit]; } [self registerForRemoteNotification]; // [Bugly startWithAppId:@"27da47f2de"]; //1.设置状态栏隐藏(YES)或显示(NO) // [[UIApplication sharedApplication] setStatusBarHidden:NO]; //2.设置状态栏字体颜色 //UIStatusBarStyleDefault,黑色(默认) //UIStatusBarStyleLightContent,白色 // [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; // 并在 info.plist文件里 设置 View controller-based status bar appearance = NO ,以APPlication 设置的为准. NSString *str = [userDefault objectForKey:@"YINSI"]; if (![str isEqualToString:@"YINSI"]) { AfterDispatch(0.2, ^{ WEAKSELF CommonPopView *popView = [CommonPopView new]; [popView diyicipopView:^{ // [weakSelf upding]; [userDefault setObject:@"YINSI" forKey:@"YINSI"]; }]; }); } [User loadFormFile]; // [[UINavigationBar appearance] setBarTintColor:KKWhiteColorColor]; // [[UINavigationBar appearance] setTitleTextAttributes:@{ // NSForegroundColorAttributeName:[UIColor blackColor], // // NSFontAttributeName:[UIFont boldSystemFontOfSize:20 * FIX_SCREEN] // }]; // [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]]; // [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:mainColor} // forState:UIControlStateSelected]; // [[UITabBar appearance] setTintColor:mainColor]; // add by lsz 2022-5-20 if (@available(iOS 15.0,*)) { [UITableView appearance].sectionHeaderTopPadding = 0; [[UITableView appearance] setPrefetchingEnabled:NO]; } // 创建NSTimer对象 // NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(action:) userInfo:nil repeats:YES]; // // 加入RunLoop中 // [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; //[launchOptions mj_JSONString] if(launchOptions){ NSDictionary * userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; @try { if(userInfo) { //点击远程推送进来的,如果是视频的话,不加载广告 NSDictionary *dataDic =[userInfo objectForKey:@"data"]; id NotificationType = dataDic[@"message"][@"type"]; if ([[NSString stringWithFormat:@"%@",NotificationType] isEqualToString:@"video"]) { self.isNOLoadSplashAD = YES; } } } @catch (NSException *exception) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [UICommon MessageErrorText:[NSString stringWithFormat:@"error : %@", exception.description]]; }); } @finally { return YES; } } //MARK:消除APP角标 [UIApplication sharedApplication].applicationIconBadgeNumber = 0; // if (Bluetooth.shareInstance.currenModel != nil) // { // if (!Bluetooth.shareInstance.isConnected) // [Bluetooth.shareInstance connectPeripheralWithUUID]; // } [self showRootViewController]; [self.window makeKeyAndVisible]; return YES; } - (void)showRootViewController { NSLog(@"登录信息==%@",cUser); if (cUser) { self.window.rootViewController = [MyTabBarViewController new]; } else { // UIStoryboard *storyboard = self.window.rootViewController.storyboard; // LoginViewController *rootViewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil]; UIStoryboard *sb = [UIStoryboard storyboardWithName:@"LoginStoryboard" bundle:nil]; LoginViewController *vc = [sb instantiateViewControllerWithIdentifier:@"LoginViewController"]; ZXNavigationBarNavigationController *nav = [[ZXNavigationBarNavigationController alloc]initWithRootViewController:vc]; self.window.rootViewController = nav; } } /** MARK: 推送注册 PushKit */ - (void)initPushKit{ if (CurrentSystemVersion.floatValue >= 8.0) { UIUserNotificationSettings *userNotifiSetting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:userNotifiSetting]; PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:nil]; pushRegistry.delegate = self; pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP]; } } /** MARK: -----注册获取设备 PushKit 唯一 token 这个代理方法是获取了设备的唯一tokenStr,是要给服务器的 */ - (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)pushCredentials forType:(PKPushType)type{ _deviceVoIPTokenData = pushCredentials.token; uint8_t* tokenBytes = (uint8_t*)pushCredentials.token.bytes; NSMutableString* output = [NSMutableString stringWithCapacity:pushCredentials.token.length * 2]; for(int i = 0; i < pushCredentials.token.length; i++) { [output appendFormat:@"%02x", tokenBytes[i]]; } _deviceVoIPTokenStr = [output copy]; xLog(@"PushKit 注册的 VoIP token: %@",_deviceVoIPTokenStr); if(_deviceTokenStr && _deviceVoIPTokenStr){ [User setDeviceToken:_deviceTokenStr AndVoIPToken:_deviceVoIPTokenStr]; } } /** MARK:程序杀掉进程,重启,退到后台,服务器推送过来的消息都会走 这里 @param registry <#registry description#> @param payload <#payload description#> @param type <#type description#> */ - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type { //提示的文字 alert NSString * alertStr = [[payload.dictionaryPayload objectForKey:@"aps"] objectForKey:@"alert"]; NSDictionary *dataDic =[payload.dictionaryPayload objectForKey:@"data"]; NSString *NotificationType = dataDic[@"message"][@"type"]; int video_type = [dataDic[@"message"][@"video_type"] intValue]; if ([NotificationType isEqualToString:@"video"]) { NSMutableDictionary *mDic = [NSMutableDictionary dictionaryWithDictionary:payload.dictionaryPayload]; [mDic setValue:alertStr forKey:@"alertStr"]; [self setNotificationData:mDic]; } else if([NotificationType isEqualToString:@"unbind"]) { [self setNotificationData:payload.dictionaryPayload]; } else { xLog(@"其他VOIP推送的消息: %@",payload.dictionaryPayload); // [UICommon MessageUpload:@""WithStatus:[NSString stringWithFormat:@"其他VOIP推送的消息: %@", payload.dictionaryPayload]]; AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);//执行震动 } } -(void)generateLocalNotificationsWithAlertStr:(NSString*)alertStr AndDataInfo:(NSDictionary*)dataInfo{ self.alertNotificationCount = 0; [[JX_GCDTimerManager sharedInstance] cancelTimerWithName:VideoTimerIdentify]; [[JX_GCDTimerManager sharedInstance] cancelTimerWithName:PlayVibrationIdentify]; [[JX_GCDTimerManager sharedInstance] scheduledDispatchTimerWithName:VideoTimerIdentify timeInterval:kMusicTime queue:dispatch_get_main_queue() repeats:YES fireInstantly:YES action:^ { self.alertNotificationCount += 1; if(self.alertNotificationCount < videoTimerCount){ //取消掉之前的本地通知,然后重新弄一个 [self setAlertStr:alertStr WithNotificationDate:dataInfo]; }else{ [[JX_GCDTimerManager sharedInstance] cancelTimerWithName:VideoTimerIdentify]; [[JX_GCDTimerManager sharedInstance] cancelTimerWithName:PlayVibrationIdentify]; self.stopVibration = YES; [self cleanVideoNotification]; } }]; [self playVibration]; } -(void)cleanVideoNotification{ if(self.backgroudMsg){ // 使用 UNUserNotificationCenter 来管理通知 UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; NSString * videoIdentifier = @"VideoLocationNotificationRequest"; [center removePendingNotificationRequestsWithIdentifiers:@[videoIdentifier]]; } } -(void)setAlertStr:(NSString *)alertStr WithNotificationDate:(NSDictionary*)dataDic { @try { NSString * videoIdentifier = @"VideoLocationNotificationRequest"; //使用 UNNotification 本地通知 // 使用 UNUserNotificationCenter 来管理通知 UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; if(self.backgroudMsg){ [center removePendingNotificationRequestsWithIdentifiers:@[videoIdentifier]]; self.backgroudMsg = nil; } //需创建一个包含待通知内容的 UNMutableNotificationContent 对象,注意不是 UNNotificationContent ,此对象为不可变对象。 self.backgroudMsg = [[UNMutableNotificationContent alloc] init]; // self.backgroudMsg.title = alertStr; self.backgroudMsg.body = alertStr; self.backgroudMsg.userInfo = dataDic; self.backgroudMsg.sound = [UNNotificationSound soundNamed:@"videoring.caf"]; self.backgroudMsg.categoryIdentifier = videoIdentifier; // 在 1s 后推送本地推送 , nil 是立刻的意思 // UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:YES]; UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:videoIdentifier content:self.backgroudMsg trigger:nil]; //添加查看按钮 UNNotificationAction *action = [UNNotificationAction actionWithIdentifier:@"enterApp" title:@"查看" options:UNNotificationActionOptionForeground]; UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"VideoLocationNotificationCategory" actions:@[action] intentIdentifiers:@[videoIdentifier] options:UNNotificationCategoryOptionNone]; [center setNotificationCategories:[NSSet setWithObject:category]]; //添加推送成功后的处理! [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if(error){ xLog(@"====视频通话本地推送添加成功===="); } }]; } @catch (NSException *exception) { xLog(@"exception: %@",exception.description); } @finally { } } /** MARK: 创建一个平常的本地通知 @param alertStr */ -(void)setNormallyAlertStr:(NSString *)alertStr UserInfo:(NSDictionary*)userinfo{ NSString * locNot = @"NormallyLocationNotificationRequest"; //使用 UNNotification 本地通知 // 使用 UNUserNotificationCenter 来管理通知 UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; if(self.backgroudMsg){ [center removePendingNotificationRequestsWithIdentifiers:@[locNot]]; self.backgroudMsg = nil; } //需创建一个包含待通知内容的 UNMutableNotificationContent 对象,注意不是 UNNotificationContent ,此对象为不可变对象。 self.backgroudMsg = [[UNMutableNotificationContent alloc] init]; self.backgroudMsg.body = alertStr; self.backgroudMsg.userInfo = userinfo; self.backgroudMsg.sound = [UNNotificationSound defaultSound]; UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:locNot content:self.backgroudMsg trigger:nil]; //添加查看按钮 UNNotificationAction *action = [UNNotificationAction actionWithIdentifier:@"NOEnterApp" title:@"好的" options:UNNotificationActionOptionDestructive]; UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"NormallyLocationNotificationCategory" actions:@[action] intentIdentifiers:@[locNot] options:UNNotificationCategoryOptionNone]; [center setNotificationCategories:[NSSet setWithObject:category]]; //添加推送成功后的处理! [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if(error){ xLog(@"====\"普通的\"本地推送添加成功===="); } }]; } -(void)playVibration{ [[JX_GCDTimerManager sharedInstance] scheduledDispatchTimerWithName:PlayVibrationIdentify timeInterval:1.5 queue:dispatch_get_main_queue() repeats:YES fireInstantly:YES action:^{ AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);//执行震动 }]; } #pragma 后台 - (void)beingBackgroundUpdateTask { taskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ [self endBackgroundUpdateTask]; }]; } - (void)endBackgroundUpdateTask { if (taskIdentifier != UIBackgroundTaskInvalid) { [[UIApplication sharedApplication] endBackgroundTask:taskIdentifier]; taskIdentifier = UIBackgroundTaskInvalid; } } #pragma mark ---注册 获取到 APNS 的 DeviceToken - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{ NSLog(@"deviceToken = %@",deviceToken); uint8_t* tokenBytes = (uint8_t*)deviceToken.bytes; NSMutableString* output = [NSMutableString stringWithCapacity:deviceToken.length * 2]; for(int i = 0; i < deviceToken.length; i++) { [output appendFormat:@"%02x", tokenBytes[i]]; } _deviceTokenStr = [output copy]; NSLog(@"_deviceTokenStr=%@", _deviceTokenStr); if(_deviceTokenStr){ [User setDeviceToken:_deviceTokenStr AndVoIPToken:_deviceVoIPTokenStr]; } } // 收到推送的时候触发的 -(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { xLog(@"userinfo:%@",userInfo); if(application.applicationState == UIApplicationStateBackground){ // //如果是 iOS 10 系列的 // if([[[UIDevice currentDevice] systemVersion] doubleValue] >= 10.0 && [[[UIDevice currentDevice] systemVersion] doubleValue] < 11.0){ // return; // } } [self setNotificationData:userInfo]; completionHandler(UIBackgroundFetchResultNewData); } -(void) setNotificationData:(NSDictionary*)userInfo { if(!userInfo){return;} NSDictionary *dict = userInfo[@"data"]; if (userInfo[@"aps"]) { if([dict[@"type"] isEqualToString: @"chatGroupMessage"] || [dict[@"type"] isEqualToString: @"singleMessage"]) { //群聊消息推送的问题 if(cUser.openid != nil ) { if ([cUser.openid isEqualToString:dict[@"message"][@"senderID"]]) { //如果是自己的消息静默处理 } else { [[NSNotificationCenter defaultCenter] postNotificationName:dict[@"type"] object:dict]; //不是自己的消息 //首先先判断不在聊天界面 Circle* currentCircle = [cUser getCircleWithImei:cUser.cDevice.imei]; if(!currentCircle) { //清空推送角标 // [UIApplication sharedApplication].applicationIconBadgeNumber = 0; return; } //是否 同一个 群组id if([dict[@"groupid"] isEqualToString:currentCircle.groupid]) { UITabBarController *tabBarVC = (UITabBarController*)self.window.rootViewController; UINavigationController *navVC = (UINavigationController*)tabBarVC.selectedViewController; if(navVC){ if(![navVC.visibleViewController isKindOfClass:[ChatViewController class]]){ AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); } } } else { AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); } } } } else if([dict[@"type"] isEqualToString: @"accountMessage"]) { xLog(@"收到消息中心的消息推送"); //消息中心的数据 [[NSNotificationCenter defaultCenter] postNotificationName:AccountMessageNotification object:dict userInfo:dict]; }else{ //其他的消息 , 比如 主动定位推送的消息,群解散 等 的f [[NSNotificationCenter defaultCenter] postNotificationName:dict[@"type"] object:dict]; } } } /** MARK: APP 挂后台的情况下 点击 通知栏跳转到响应页面 @param response 收到的 推送消息内容 response.notification.request.content.userInfo */ - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler{ WEAKSELF //MARK: 点击推送跳转对应的页面 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [weakSelf handlePushMsg:response.notification.request.content.userInfo]; }); } - (void)handlePushMsg:(NSDictionary *)infoData { xLog(@"Userinfo %@",infoData); if(infoData.count == 0){ return; } //判断消息类型 跳转到对应的页面 NSDictionary *dict = infoData[@"data"]; if(!dict){ return; } UITabBarController *tabBarVC = (UITabBarController*)self.window.rootViewController; UINavigationController *navVC = (UINavigationController*)tabBarVC.selectedViewController; if([dict[@"type"] isEqualToString:@"chatGroupMessage"] || [dict[@"type"] isEqualToString: @"singleMessage"]) { //聊天消息 //判断imei 设置 主 device 并且 跳转到 对应的聊天界面 if(cUser.openid != nil ) { //senderID 不同 震动 if (![cUser.openid isEqualToString:dict[@"message"][@"senderID"]]) { //不同账号的微聊消息,且不在聊天页面,手机震动 if(![navVC.visibleViewController isKindOfClass:[ChatViewController class]]){ AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); } AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); if([dict[@"type"] isEqualToString:@"chatGroupMessage"]) { NSString *groupid = dict[@"groupid"]; //不是同一群组 找到同一个群组并设置 主设备 for (Device* tempDevice in cUser.myDevices) { //获取当前圈子 Circle* currentCircle = [cUser getCircleWithImei:tempDevice.imei]; if(!currentCircle){ return; } //是否 同一个 群组id if([groupid isEqualToString:currentCircle.groupid]){ //同一个群组 cUser.cDevice = tempDevice; break; //跳出循环 } } } // 跳转 聊天页面 if(navVC) { if(![navVC.visibleViewController isKindOfClass:[ChatViewController class]]) { ChatViewController *vc = [[ChatViewController alloc] init]; //vc.zx_navTitle = [dict[@"type"] isEqualToString:@"chatGroupMessage"] ? @"家庭群聊" : @""; vc.chatType = [dict[@"type"] isEqualToString:@"chatGroupMessage"] ? 222: 111; if ([dict[@"type"] isEqualToString:@"chatGroupMessage"]) { Circle *infoCircle = [[Circle alloc] init]; infoCircle.groupid = dict[@"groupid"]; vc.infoCircle = infoCircle; } else { Circle *infoCircle = [[Circle alloc] init]; if (dict[@"imei"]) vc.imei = dict[@"imei"]; vc.infoCircle = infoCircle; for (Device *model in cUser.myDevices) { if ([model.imei isEqualToString:dict[@"message"][@"senderID"]]) vc.zx_navTitle = model.name; } } [[UICommon currentVC].navigationController pushViewController:vc animated:YES]; } } } } } else { //其他消息类型 NSDictionary *msgDic = dict[@"message"]; NSString * msgType = msgDic[@"type"]; NSInteger selectIndex = 0; //是否是申请的消息 if(!msgType || [msgType isEqualToString:@"unbind"]){ //被管理员取消关注不跳转页面 return ; } if(!msgType || [msgType isEqualToString:@"video"]){ //视频 if(![navVC.visibleViewController isKindOfClass:[CallViewController class]]) [[NSNotificationCenter defaultCenter] postNotificationName:AccountMessageNotification object:dict userInfo:dict]; return ; } if([msgType isEqualToString:@"reject"]){ AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate); return; } if (!msgType || [msgType isEqualToString:@"battery"]) { return; } if(!msgType || [msgType isEqualToString:@"LoginOffLine"]){ //被异地推送挤下线 // 异地下线 //清除 记住的密码 [UserDefaults setBool:NO forKey:kifRememberPWDKey]; [UserDefaults removeObjectForKey:@"lastpwd"]; [[NSNotificationCenter defaultCenter] postNotificationName:@"outLogin" object:nil]; return ; } //lowBattery rail sms sos photograph 提醒消息 //checkResults checkedResults 关注消息 //identityTransfer identityTransfered systemUpdate 系统消息 if([msgType isEqualToString:@"lowBattery"] || [msgType isEqualToString:@"rail"] || [msgType isEqualToString:@"sms"] || [msgType isEqualToString:@"sos"] || [msgType isEqualToString:@"photograph"]){ selectIndex = 0; } if([msgType isEqualToString:@"checkResults"] || [msgType isEqualToString:@"checkedResults"] || [msgType isEqualToString:@"applicationRrecord"] || [msgType isEqualToString:@"applicationOvertime"]){ selectIndex = 1; } if([msgType isEqualToString:@"identityTransfer"] || [msgType isEqualToString:@"identityTransfered"] || [msgType isEqualToString:@"systemUpdate"]){ selectIndex = 2; } if([msgType isEqualToString:@"CostFlow"]){ selectIndex = -1; } // 跳转 消息中心页面 if(navVC){ UIViewController *vc = navVC.viewControllers.lastObject; if(selectIndex == -1){ if([NSStringFromClass([vc class]) isEqualToString:@"QueryCallRatesRoFlowVC"] ){ [vc viewWillAppear:YES]; return; } UIViewController *pushVC = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"QueryCallRatesRoFlowVC"]; pushVC.hidesBottomBarWhenPushed = YES; [navVC pushViewController:pushVC animated:YES]; return; } if([msgType isEqualToString:@"photograph"]){ if([vc isKindOfClass:[RemoteCameraViewController class]] ){ [vc viewWillAppear:YES]; return; } //前往 远程拍照页面 RemoteCameraViewController *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"RemoteCameraViewController"]; vc.hidesBottomBarWhenPushed = YES; [navVC pushViewController:vc animated:YES]; }else{ if([vc isKindOfClass:[MessageViewController class]] ){ [vc viewWillAppear:YES]; return; } //前往查看 MessageViewController *vc = [MessageViewController new]; vc.title = @"消息中心"; vc.hidesBottomBarWhenPushed = YES; vc.selectedIndex = selectIndex; [navVC pushViewController:vc animated:YES]; } } } } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { xLog(@"Registfail %@",error); } - (void)registerForRemoteNotification { if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) { //iOS 10 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center setDelegate:self]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (!error) { xLog(@"request authorization succeeded!"); } }]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } else { if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) { [[UIApplication sharedApplication] registerForRemoteNotifications]; } UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert; UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings]; } } //#ifdef __IPHONE_8_0 //- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { // [application registerForRemoteNotifications]; //} //#endif #pragma mark 键盘自动调整位置 - (void)initIQKeyBorard{ IQKeyboardManager *manager = [IQKeyboardManager sharedManager]; manager.enable = YES; manager.shouldResignOnTouchOutside = YES; // manager.shouldToolbarUsesTextFieldTintColor = NO; manager.enableAutoToolbar = NO; } - (void)closeIQKeyBorard{ IQKeyboardManager *manager = [IQKeyboardManager sharedManager]; manager.enable = NO; manager.shouldResignOnTouchOutside = NO; // manager.shouldToolbarUsesTextFieldTintColor = YES; } - (void)applicationWillResignActive:(UIApplication *)application { // 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. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { //实现一个可以后台运行几分钟的权限, 当用户在后台强制退出程序时就会走applicationWillTerminate 了. [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]; // 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. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } //MARK: APP将要从后台返回 - (void)applicationWillEnterForeground:(UIApplication *)application { // 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. if(self.backgroudMsg){ //MARK: 取消本地推送 [self cleanVideoNotification]; [[JX_GCDTimerManager sharedInstance] cancelTimerWithName:VideoTimerIdentify]; [[JX_GCDTimerManager sharedInstance] cancelTimerWithName:PlayVibrationIdentify]; self.stopVibration = YES; //APP 运行之后发送推送 [self setNotificationData:self.backgroudMsg.userInfo]; self.backgroudMsg = nil; } [self upDataVersion]; } - (void)applicationDidBecomeActive:(UIApplication *)application { // 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. //MARK:重新启动在应用程序处于非活动状态时暂停(或尚未启动)的任何任务。如果应用程序以前在后台,可以选择刷新用户界面。 if(self.backgroudMsg){ //MARK: 取消本地推送 [self cleanVideoNotification]; [[JX_GCDTimerManager sharedInstance] cancelTimerWithName:VideoTimerIdentify]; [[JX_GCDTimerManager sharedInstance] cancelTimerWithName:PlayVibrationIdentify]; self.stopVibration = YES; //APP 运行之后发送推送 [self setNotificationData:self.backgroudMsg.userInfo]; self.backgroudMsg = nil; } } //MARK : APP被杀死前的回调 - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. //MARK: 标记APP 的状态是死了 NSUserDefaults* userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.tongxin"]; // [userDefault setValue:@(NO) forKey:@"APPStatus"]; [userDefault removeObjectForKey:@"APPStatus"]; } - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray> * __nullable restorableObjects))restorationHandler { return [[APHandleManager sharedManager] handleOpenUniversalLink:userActivity]; } - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { return [[APHandleManager sharedManager] handleOpenURL:url]; } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [[APHandleManager sharedManager] handleOpenURL:url]; } - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { return [[APHandleManager sharedManager] handleOpenURL:url]; } - (void)stajishiqi { self.isTouch = NO; [[GCDTimerManager sharedInstance] scheduleGCDTimerWithName:@"JISHIQI" interval:60 queue:dispatch_get_main_queue() repeats:NO option:CancelPreviousTimerAction action:^{ self.isTouch = YES; [self xiaohui]; }]; } - (void)xiaohui { [[GCDTimerManager sharedInstance] cancelTimerWithName:@"JISHIQI"]; } - (void)upding { //定位一次自身的位置 //初始化管理器 self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; self.locationManager.delegate = self; [self.locationManager startUpdatingLocation]; //检查是否授权 if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { [self.locationManager requestWhenInUseAuthorization]; } } -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { // CLLocation *userLocation = [locations lastObject]; // self.curLocation = [userLocation locationMarsFromEarth]; [manager stopUpdatingLocation]; } /** 上传版本号 */ -(void)upDataVersion { if([User currentUser]){ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *dayRecord = (NSString*)[defaults objectForKey:FirstEveryDayKey]; NSDateFormatter *formatter = [NSDateFormatter new]; [formatter setDateFormat:@"yyyy-MM-dd"]; NSDate *nowDate = [NSDate date]; NSString *nowDay = [formatter stringFromDate:nowDate]; if(dayRecord){ if([dayRecord isEqualToString:nowDay]){ return; }else{ [defaults setObject:nowDay forKey:FirstEveryDayKey]; } }else{ [defaults setObject:nowDay forKey:FirstEveryDayKey]; } //MARK: 每天的第一天获取广告配置 [cUser getADConfig]; NSMutableDictionary *params = [NSMutableDictionary dictionary]; if([ZKUDID value]){ [params setValue:[ZKUDID value] forKey:@"uuid"]; } //当前版本号 NSString *version = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"]; [params setValue:version forKey:@"version"]; [params setValue:@"zuoyebang" forKey:@"channel"]; [xMyHttp URL:HTTP_VERSION method:@"POST" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) { //判断当前版本是否是最新版本, !! 提示更新 !! NSDictionary *dic = (NSDictionary*)responseObject; NSString * newVersion = dic[@"ios_version"]; NSString * toAppStoreURL = dic[@"ios_url"]; NSString * content = dic[@"content"]; if(!(newVersion && toAppStoreURL && content)){ return ; } toAppStoreURL = [toAppStoreURL stringByReplacingOccurrencesOfString:@"https:" withString:@"itms-apps:"]; //去掉其他,只保留数字 NSString *tempNewVersion = [[newVersion componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet]] componentsJoinedByString:@""]; //当前版本号 NSString *version = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"]; version = [[version componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet]] componentsJoinedByString:@""]; // 判断是否是强制更新 NSInteger isforceUpdate = [dic[@"forceUpdate"] integerValue]; xLog(@"是否是强制更新 :%ld" ,(long)isforceUpdate); if (isforceUpdate == 1){ // 强制更新需要去除 每日标记 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults removeObjectForKey:FirstEveryDayKey]; } if(tempNewVersion.integerValue > version.integerValue){ //MARK : 显示内容 测试 WCUpVersionView * view = [[WCUpVersionView alloc] initWithNewUpversionAlertViewWithSetVersion:newVersion Content:content]; view.isforceUpdate = @(isforceUpdate).boolValue; //更新跳转 view.upVersionBlock = ^{ // IOS11 以下的 if([[[UIDevice currentDevice] systemVersion] doubleValue] < 11.0){ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:toAppStoreURL]]; }else{ // iOS 11 以上 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:toAppStoreURL] options:@{} completionHandler:^(BOOL success) { xLog(@"success: %d",success); }]; } }; } // itms-apps://itunes.apple.com/cn/app/id1268542657?mt=8 xLog(@"版本更新打印的信息 %@",responseObject); } failure:^(NSURLSessionDataTask *task, NSError *error) { }]; } } @end