// // AppDelegate.m // JSJPCoach // // Created by apple on 2017/3/10. // Copyright © 2017年 Danson. All rights reserved. // #import "AppDelegate.h" #import "ViewController.h" #import "LoginVC.h" #import "ADView.h" #import "MyMsgVC.h" #import #import "MyUINavigationController.h" #import "TheoryTrainVC.h" //客服 #import "QMProfileManager.h" //bugly腾讯bug统计 #import @interface AppDelegate () { UIScrollView* scroll; //no use NSString *pushType; NSString *pushID; } @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //异常统计 #ifdef DEBUG //do sth1. #else [Bugly startWithAppId:BUGLY_APP_ID]; #endif self.window = [[UIWindow alloc] initWithFrame:kFrame]; [self.window makeKeyAndVisible]; //初始化地图 _mapManager = [[BMKMapManager alloc]init]; // 如果要关注网络及授权验证事件,请设定 generalDelegate参数 BOOL ret = [_mapManager start:@"d6Zg7kcdIcasgMKsFdUzyPLyFNhkkvXx" generalDelegate:self]; if (!ret) { NSLog(@"manager start failed!"); } //客服注册 QMProfileManager *manger = [QMProfileManager sharedInstance]; [manger loadProfile:@"sinatechcn" password:@"321456"];//8062moor 123456 // 通过个推平台分配的appId、 appKey 、appSecret 启动SDK,注:该方法需要在主线程中调用 [GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self]; // 注册 通知(本地/远程) [self registerRemoteNotification]; /* 若用户点击icon启动,lauchOptions内无数据 */ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 //didReceiveNotificationResponse 统一处理 #else //本地通知 // 处理退出后通知的点击,程序启动后获取通知对象,如果是首次启动还没有发送通知,那第一次通知对象为空,没必要去处理通知(如跳转到指定页面) if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { //ios<10的话,对应的didreceiveLoacal说是接受不到消息(要求前/后台),这一点在ios10以后解决了 UILocalNotification *localNotifi = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; NSDictionary *userInfo = localNotifi.userInfo; if (userInfo[@"theoryTrainVC_classId"]) { //理论计时提醒本地推送 [self gotoTheory]; return YES; } } //远程通知 if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) { //关于这个方法远程和进程不一样 一个是userinfo字典。一个是本地通知 NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; //这里不用判断重复消息 NSString *msgId = [userInfo[@"_gmid_"] componentsSeparatedByString:@":"][1]; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:msgId forKey:@"remoteNotifymsgId"]; [userDefaults synchronize]; NSString *jsonStr = userInfo[@"payload"]; if ([jsonStr length] != 0) { NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding]; if (data) { NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]]; pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]]; if (pushType != 0) { [self gotoPush]; }else{ //其它信息 [self gotoLoad]; [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]]; } return YES; } } } #endif loadADPaths(); //判断跳转页面 这样每次更新版本 都会有导航页 NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; NSString *vesionNow = [infoDic objectForKey:@"CFBundleShortVersionString"]; if (![defUser.isWelcomed isEqualToString:vesionNow]) { //刚刚下载 要加载一次广告 存本地 defUser.isWelcomed = vesionNow; [self makeLaunchView]; loadADPaths(); }else{ //在这里搞个 广告页面 加载广告 [ADView showADView]; @try { //是否为新版本 [self onCheckVersion]; } @catch (NSException *exception) { } @finally { [self gotoLoad]; } } return YES; } #pragma mark 推送注册 /** 注册 APNs */ - (void)registerRemoteNotification { /* 警告:Xcode8 需要手动开启"TARGETS -> Capabilities -> Push Notifications" */ if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) { if (!error) { NSLog(@"request authorization succeeded!(iOS >= 10.0)"); } }]; } else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; } //远程需添加 [[UIApplication sharedApplication] registerForRemoteNotifications]; } /** 远程通知注册成功委托 */ - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; // NSLog(@"\n>>>[DeviceToken Success]:%@\n\n", token); // 向个推服务器注册deviceToken [GeTuiSdk registerDeviceToken:token]; } /** 远程通知注册失败委托 */ - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"FailToRegisterForRemoteNotificationsWithError:%@",error); } //iOS7.0 以后支持 APP 后台刷新数据,会回调 performFetchWithCompletionHandler 接口。为保证个推SDK的数据刷新,需在该回调接口中调用[GeTuiSdk resume]方法帮助个推 SDK 刷新数据。 - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { /// Background Fetch 恢复SDK 运行 [GeTuiSdk resume]; completionHandler(UIBackgroundFetchResultNewData); } #pragma mark - iOS < 10 /* 1.点击通知栏, 2.要求app未被杀死,如果app是terminate就去didfinishlaunch获取;这一点在ios10以后改善了 */ //-----本地推送 - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{ //ios<10 点击弹窗 if (notification.userInfo[@"theoryTrainVC_classId"]) { [self gotoTheory]; } } //------远程推送 //处理APNs 通知点击事件,统计有效用户点击数 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // NSLog(@"didReceiveRemoteNotification and iOS<10"); // 将收到的APNs信息传给个推统计 [GeTuiSdk handleRemoteNotification:userInfo]; completionHandler(UIBackgroundFetchResultNewData); [self remoteNotificationDealWithPayLoadDic:userInfo]; } #pragma mark iOS > 10 /* 1.对于iOS 10 及以后版本,为处理 APNs 通知点击,统计有效用户点击数,需先添加 UNUserNotificationCenterDelegate 2.app可以处于任何状态(terminate,前/后台) */ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { // NSLog(@"willPresentNotification and iOS>10前台:%@", notification.request.content.userInfo); // 根据APP需要,判断是否要提示用户Badge、Sound、Alert(ios>10 如果需要应用在前台也展示通知) completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert); } // iOS 10: 统一获取推送的接口 点击通知进入App时触发,在该方法内统计有效用户点击数 (点击弹窗,不管app处于任何状态(terminate,前/后台)都会调用) - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { // NSLog(@"didReceiveNotificationResponse iOS>10:%@", response.notification.request.content.userInfo); //理论计时提醒本地推送 if (response.notification.request.content.userInfo[@"theoryTrainVC_classId"]) { [self gotoTheory]; return; } //远程推送 //将收到的APNs信息传给个推统计 [GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo]; completionHandler(); NSDictionary* userInfo = response.notification.request.content.userInfo; [self remoteNotificationDealWithPayLoadDic:userInfo]; } #endif #pragma mark - 个推相关方法 /** SDK启动成功返回cid */ - (void)GeTuiSdkDidRegisterClient:(NSString *)clientId { //个推SDK已注册,返回clientId // NSLog(@"\n>>>[GeTuiSdk RegisterClient]:%@\n\n", clientId); myDelegate.token = clientId; upLoadToken(); } /** SDK遇到错误回调 */ - (void)GeTuiSdkDidOccurError:(NSError *)error { //个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。 NSLog(@"\n>>>[GexinSdk error]:%@\n\n", [error localizedDescription]); } /** SDK收到透传消息回调 */ - (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId { //收到个推消息 if (payloadData) { // NSString * payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding]; // NSLog(@"GeTuiSdkDidReceivepayloadMsg:%@",payloadMsg); //判断是否被处理过[即发送离线消息的时候,会走apns+个推sdk(有效期内)] //ps:这里处理之后不做存档操作,保证点击通知栏的时候可以”再处理一次“ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSString *oldmsgId = [userDefaults objectForKey:@"remoteNotifymsgId"]; if ([oldmsgId isEqualToString:msgId]) { return; } NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:payloadData options:NSJSONReadingMutableContainers error:nil]; if (payloadDic.count == 0) { return; } pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]]; pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]]; if ([pushType integerValue] != 0) { UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:payloadDic[@"title"] message:payloadDic[@"body"] preferredStyle:UIAlertControllerStyleAlert]; [alertFind addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]]; [alertFind addAction:[UIAlertAction actionWithTitle:@"前往" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { [self gotoPush]; }]]; [self.window.rootViewController presentViewController:alertFind animated:true completion:nil]; }else{ //其它信息 [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]]; } } } #pragma mark 远程通知的数据处理 -(void)remoteNotificationDealWithPayLoadDic:(NSDictionary *)userInfo{ /* { "_ge_" = 1; "_gmid_" = "OSL-0818_bJ6zVRy8cC6JsflZOYPXO9:965f14a1051748c4a48f9db2437362e5:d48422d462d2bcf0b9d962f150b235b9"; "_gurl_" = "sdk.open.extension.getui.com:8123"; aps = { alert = { body = "\U60a8\U9a7e\U6821\U6709\U8f66\U8f86\U7ec8\U7aef\U62a5\U8b66\U9700\U89e3\U9664\Uff0c\U8bf7\U67e5\U770b\U5e76\U5904\U7406"; title = "\U544a\U8b66\U6d88\U606f"; }; badge = 2; category = "button\U663e\U793a"; "content-available" = 1; "mutable-content" = 1; sound = default; }; payload = "{\"title\":\"\U544a\U8b66\U6d88\U606f\",\"code\":\"1\",\"body\":\"\U60a8\U9a7e\U6821\U6709\U8f66\U8f86\U7ec8\U7aef\U62a5\U8b66\U9700\U89e3\U9664\Uff0c\U8bf7\U67e5\U770b\U5e76\U5904\U7406\,\"id\":\"2\"}"; } */ // _gmid_对应-- taskId msgId clientID //这里使用msgid判断是否被处理【不过似乎应该用taskid?@lee,幻想着一个任务多条消息] NSString *msgId = [userInfo[@"_gmid_"] componentsSeparatedByString:@":"][1]; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSString *oldMsgId = [userDefaults objectForKey:@"remoteNotifymsgId"]; if ([msgId isEqualToString:oldMsgId]) { return; } //开始处理 [userDefaults setObject:msgId forKey:@"remoteNotifymsgId"]; [userDefaults synchronize]; NSString *jsonStr = userInfo[@"payload"]; if ([jsonStr length] == 0) { return; } NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding]; if (data) { NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]]; pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]]; if (pushType != 0) { [self gotoPush]; }else{ //其它信息 [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]]; } } } -(void)showMsgByArertWithTitle:(NSString *)title message:(NSString *)message{ if (message.length == 0) { return; } //其它信息 UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; [alertFind addAction:[UIAlertAction actionWithTitle:@"我知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]]; [self.window.rootViewController presentViewController:alertFind animated:true completion:nil]; } #pragma mark 跳转相关 -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (alertView.tag == 10000) { if (buttonIndex == 1) { NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.apple.com/cn/app/liao-ning-jia-pei-jiao-lian-ban/id1225444971?l=en&mt=8"]; [[UIApplication sharedApplication]openURL:url]; } }else{ if (buttonIndex != alertView.cancelButtonIndex) { [self gotoPush]; } } } -(void)gotoTheory{ TheoryTrainVC * vc = [[TheoryTrainVC alloc]init]; vc.isNotification = YES; MyUINavigationController *nav = [[MyUINavigationController alloc]initWithRootViewController:vc]; [myDelegate.window setRootViewController:nav]; } -(void)gotoPush { [self goToMessage]; } -(void)goToMessage { MyMsgVC* vc = [[MyMsgVC alloc] init]; vc.isNotification = YES; MyUINavigationController *nav = [[MyUINavigationController alloc]initWithRootViewController:vc]; [myDelegate.window setRootViewController:nav]; } #pragma mark - //程序挂起 - (void)applicationWillResignActive:(UIApplication *)application { } //程序进入后台 - (void)applicationDidEnterBackground:(UIApplication *)application { myDelegate.isBackgroundTask = YES; } //程序到前台 - (void)applicationWillEnterForeground:(UIApplication *)application { //[ADView showADView]; } //程序复原 - (void)applicationDidBecomeActive:(UIApplication *)application { [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];//本地 myDelegate.isBackgroundTask = NO; [GeTuiSdk resetBadge];//同步给个推 } - (void)applicationWillTerminate:(UIApplication *)application { } #pragma mark 检查新旧 -(void)onCheckVersion { if (![Util connectedToNetWork]) { return; } NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; NSString *currentVersion = [infoDic objectForKey:@"CFBundleShortVersionString"]; NSString *URL = @"http://itunes.apple.com/lookup?id=1225444971"; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:URL]]; [request setHTTPMethod:@"POST"]; NSOperationQueue *queue=[NSOperationQueue mainQueue]; [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if (!data) { return; } //如果data等于nil的时候 再去解析 会发生崩溃 NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; if (!dic) { return; } NSArray *infoArray = [dic objectForKey:@"results"]; if ([infoArray count]) { NSDictionary *releaseInfo = [infoArray objectAtIndex:0]; NSString *lastVersion = [releaseInfo objectForKey:@"version"]; NSArray *last = [lastVersion componentsSeparatedByString:@"."]; NSArray *current = [currentVersion componentsSeparatedByString:@"."]; NSComparisonResult result = [last[0] compare:current[0]]; if (result == NSOrderedDescending) { [self updateVersion]; }else if(result == NSOrderedSame){ result = [last[1] compare:current[1]]; if (result == NSOrderedDescending) { [self updateVersion]; }else if(result == NSOrderedSame){ result = [last[2] compare:current[2]]; if (result == NSOrderedDescending) { [self updateVersion]; } } } } }]; } -(void)updateVersion { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"更新提示" message:@"有新的版本发布,是否前往更新?" delegate:self cancelButtonTitle:@"关闭" otherButtonTitles:@"更新", nil]; alert.tag = 10000; [alert show]; } #pragma mark - 欢迎页面 -(void)makeLaunchView { NSArray* images = @[@"welcom_page_21.jpg",@"welcom_page_22.jpg",@"welcom_page_23.jpg"]; //关于导航页要修改 添上新的导航页 scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, kSize.width, kSize.height)]; /**跳到第4页,也会欢迎结束。 */ [scroll setContentSize:CGSizeMake(kSize.width* images.count+10, 0)]; [scroll setBackgroundColor:[UIColor orangeColor]]; [scroll setShowsHorizontalScrollIndicator:NO]; [scroll setDelegate:self]; scroll.pagingEnabled = YES; scroll.bounces = NO; UIViewController* vc = [UIViewController new]; [vc.view addSubview:scroll]; [self.window setRootViewController:vc]; UIImageView* iv; for (int i =0; i 2.0) { [self gotoLoad]; } } @end