今天恰好有個需求當點擊推送需要跳轉到指定控制器,找了很多資料,自己也想了很久沒有一個極佳的辦法,再經過多番試煉之后,終于找到一個不錯的方法,接下來先從集成友盟推送開始:
此文章分為兩部分:
1.集成友盟推送
2.點擊推送跳轉到指定控制器
1.1 開始:如果你沒有創建應用,那么首先去創建應用吧
獲得 AppKey 和 AppSecret (后面用)
1.2 接著: 到iOS集成友盟推送SDK文檔中心:http://dev.umeng.com/push/ios/integration下載UMessage_Sdk_All_x.x.x.zip壓縮包并解壓縮
下載的壓縮包中將包括以下內容:
文件名稱介紹
UMessage_Sdk_Introductions.html該文件介紹如何使用【友盟+】消息推送SDK
UMessage_Sdk_ReleaseNotes.html該文件記錄了【友盟+】消息推送SDK的更新日志
UMessage_Sdk_Api_Reference/該文件夾中包含了【友盟+】消息推送的API文檔
UMessage_Sdk_x.x.x/該文件夾中包含了SDK的庫文件
UMessage_Sdk_Demo/該文件夾中包含了示例工程
NotificatonService/iOS10的Notificaton Service
1.3 將SDK 文件拖入或者拷貝到你項目中
拖入會彈出這個窗:
拷貝:
右鍵添加到指定的文件夾中
3.1 ?引入庫文件
增加UserNotifications.framework到項目中。
具體操作如下:點擊項目---->TARGET---->Build Phases---->Link Binary with Libraries---->左側+號---->搜索UserNotifications---->選中UserNotifications.framework---->點擊Add
3.2? 打開推送開關
點擊項目---->TARGET---->Capabilities,將這里的Push Notification的開關打開
1.4 集成推送
4.1 好,前面都是準備工作,現在上代碼:
進入 AppDelegate.m
引入 UMessage.h,UserNotifications.h
在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中:
UMConfigInstance.appKey = @"AppKey";
UMConfigInstance.channelId = @"App Store";
[MobClick startWithConfigure:UMConfigInstance];
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
[MobClick setAppVersion:version];
//打開日志,方便測試
[MobClick setLogEnabled:NO];
// 適配Https
[UMessage startWithAppkey:@"AppKey" launchOptions:launchOptions httpsEnable:YES];
//注冊通知
[UMessage registerForRemoteNotifications];
//ios10針對
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
UNAuthorizationOptions types10 = UNAuthorizationOptionBadge | UNAuthorizationOptionAlert|UNAuthorizationOptionSound;
[center requestAuthorizationWithOptions:types10 completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted){? //點擊允許
NSLog(@"點擊允許了");
}else{ //點擊不允許
NSLog(@"點擊不允許");
}
}];
//測試日志
[UMessage setLogEnabled:NO];
4.2 接收通知
//iOS10以下使用這個方法接收通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo {
// 關閉自動推送
[UMessage setAutoAlert:NO];
//統計點擊數
[UMessage didReceiveRemoteNotification:userInfo];
if ([userInfo[@"type"] isEqualToString:@"workflow"]){
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifyPresnetWeb" object:userInfo];
}
}
//iOS10新增:處理前臺收到通知的代理方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
NSDictionary *userInfo = notification.request.content.userInfo;
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//應用處于前臺的遠程推送接受
//關閉友盟自帶的alert
[UMessage setAutoAlert:NO];
//必須加這句代碼
[UMessage didReceiveRemoteNotification:userInfo];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]] message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"查看", nil];
_notification = userInfo;
alert.delegate = self;
[alert show];
}else {
//應用處于前臺時的本地推送接受
NSLog(@"大帥處于前臺的本地的消息來了%@",[NSString stringWithFormat:@"%@",userInfo]);
}
//當應用處于前臺時提示設置,需要哪個可以設置哪一個
completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);
}
這句代碼不寫,會報一個? completionHandler never called 錯誤信息
completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);?
//iOS10新增:處理后臺點擊通知的代理方法
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//應用處于后臺時的遠程推送接受
[UMessage didReceiveRemoteNotification:userInfo];
NSLog(@"大帥的遠程推送的消息來了%@",userInfo);
if ([userInfo[@"type"] isEqualToString:@"workflow"]){
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifyPresnetNotice" object:userInfo];
}
}else{
//應用處于后臺時的本地推送接受
NSLog(@"小帥的本地后臺推送的消息來了%@",userInfo);
}
}
2.跳轉指定控制器部分
2.1 還是在 delegate.m中
// 彈窗監聽方法
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(@"點擊取消");
}else{
if ([_notification[@"type"] isEqualToString:@"workflow"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifyPresnetNotice" object:_notification];
}
[alertView dismissWithClickedButtonIndex:buttonIndex animated:YES];
NSLog(@"點擊確定按鈕");
}
}
2.2 在 tabBarVC.m 中接收通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(presentNotice:) name:@"notifyPresnetNotice" object:nil];
2.3 這里要借用到一個工具類
得益于http://www.lxweimin.com/p/bc3c80fa5166 的作者寫的工具類, 里面寫的挺詳細,但我根據自己實際情況汲取了一些代碼
工具類在作者的GitHub: https://github.com/liu521227/PushDemo 中,可自己下載
下載后只需將工具拖入或拷貝到項目中就可以
在 tabBarVC.m 中導入頭文件 #import "NSObject+Tool.h"
這時候實現你的通知方法:
// MARK: - 跳轉到公告頁面
- (void)presentNotice:(NSNotification *)info {
IAAnnouncementVC *announceVC = [[IAAnnouncementVC alloc]init]; // 創建你的目標控制器
announceVC.hidesBottomBarWhenPushed = YES; // 隱藏你的 tabBar
// [self currentViewController] 調用工具類的 ?- currentViewController 方法 獲取當前控制器
會打印兩次,第一次是當前控制器, 第二次是目標控制器
if (![[self currentViewController] isKindOfClass:[IAAnnouncementVC class]]) { // 這個判斷防止兩次執行里面代碼
// 如果不想隱藏導航欄返回按鈕文字就去掉這個判斷
if (![[self currentViewController] isKindOfClass:[IAMessageVC class]]) {// 如果不是父控制器就進入,應領導要求,不是從父控制器(指的是正常進入目標控制器的父控制器) 就隱藏導航欄返回按鈕的文字
// 隱藏導航欄返回按鈕的文字
[self currentViewController].navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:self action:nil];
}else { // 這個判斷是走完上面方法之后,所有返回按鈕文字都隱藏了, 下面這方法可以解決這個問題
[self currentViewController].navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[self currentViewController].title style:UIBarButtonItemStylePlain target:self action:nil];
}
// 正角來了,這個方法可以讓你在任何頁面都可以跳轉到目標控制器, 當然返回也是進入之前的頁面(愛奇藝也是這效果)
[[self currentViewController].navigationController pushViewController:announceVC animated:YES];
}
}