1.如果是應(yīng)用未啟動
則可以通過
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
方法來判斷是點擊圖標(biāo)啟動應(yīng)用還是點擊推送消息啟動應(yīng)用紧索,如果是點擊推送啟動應(yīng)用的話,上面的那個方法的launchOptions必不為nil鉴竭,可以通過是否為nil進行判斷粉铐;然后可以通過
if(launchOptions) {
NSDictionary*?remoteNotification?= [launchOptionsobjectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(remoteNotification) {
NSLog(@"推送過來的消息是%@",remoteNotification);
//點擊推送通知進入指定界面(這個肯定是相當(dāng)于從后臺進入的)
[self?goToMssageViewControllerWith:remoteNotification];//進入相應(yīng)頁面的方法
}
}
返回的詞典remoteNotification就是推送的消息主體每辟,可以在此進行打印查看,然后判斷是點擊推送消息啟動的應(yīng)用之后,在goToMssageViewControllerWith:的方法里面寫進入自己消息對應(yīng)頁面的代碼(下面再講)
2.如果應(yīng)用已啟動,掛在后臺
這種情況下點擊推送的消息進入應(yīng)用時會調(diào)用
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
userInfo就是推送的消息的主體
在這個方法中可以進行自己進入消息對應(yīng)頁面的代碼操作
3.如果推送消息到達時應(yīng)用就在前臺運行
這種情況依然會調(diào)用2.中的方法才菠,但是如果你什么都沒設(shè)置,用戶就不會知道你推送了消息贡定,如果你設(shè)置了進入對應(yīng)頁面赋访,則應(yīng)用會一下子很突然的進入對應(yīng)界面,體驗不好;這個時候就需要判斷應(yīng)用是在前臺運行還是掛在后臺(如果程序未啟動就不用考慮這種情況)
if([UIApplicationsharedApplication].applicationState==UIApplicationStateActive)
{//前臺運行時蚓耽,收到推送的通知會彈出alertview提醒
NSDictionary*oneDict = [userInfoobjectForKey:@"aps"];
NSDictionary*twoDict = [oneDictobjectForKey:@"alert"];
NSString*msg = [twoDictobjectForKey:@"body"];
UIAlertView*alert = [[UIAlertViewalloc]initWithTitle:@"溫馨提示"message:msgdelegate:selfcancelButtonTitle:nilotherButtonTitles:@"確定",nil];
[alertshow];
}
else if ([UIApplicationsharedApplication].applicationState==UIApplicationStateInactive)
{//點擊推送通知進入界面的時候
[self goToMssageViewControllerWith:userInfo];
}
UIApplicationsharedApplication].applicationState有三個狀態(tài)渠牲,分別是UIApplicationStateActive//應(yīng)用正在前臺運行
UIApplicationStateInactive//點擊推送的通知進入應(yīng)用
UIApplicationStateBackground//應(yīng)用在后臺掛起
這里面只須判斷應(yīng)用是在前臺運行(2.)還是點擊推送通知進入應(yīng)用(3.)了,然后再進行相應(yīng)的處理步悠,我項目中所用的是如果在前臺運行签杈,推送消息來了就彈窗告知,不過感覺不是很好鼎兽,讀者可用自己方法答姥,也可以用第三方MBProgressHUD中的那個浮現(xiàn)兩三秒自動消失的控件來操作;如果是點擊推送通知進入應(yīng)用谚咬,我還是用的那個進入相應(yīng)界面的方法
4.如何進入推送消息相應(yīng)的界面
重頭戲來了額鹦付,做到這塊的時候我在網(wǎng)上搜了好多,但并沒什么很多值得參考的資料择卦,最后的話在cocoaChina論壇中找到一個值得參考的http://www.cocoachina.com/bbs/read.php?tid=257582敲长,里面的8樓說的很有道理,我也是基于此做的互捌;
首先關(guān)于推送的消息這塊潘明,比如你推送的消息分為三類,一類是點擊消息進入A頁面秕噪,一類是點擊進入B頁面钳降,一類是點擊進入C頁面,你可以在推送的消息主體中設(shè)置一個事件值EventID腌巾,定義101就是關(guān)于A頁面的消息遂填,102就是關(guān)于B頁面的消息,103就是關(guān)于C頁面的消息澈蝙;然后接收到消息主體后解析出來進行判斷吓坚,可以使用switch case進行判斷,
NSIntegerEventID = [[msgDic objectForKey:@"eventId"]integerValue];
switch(EventID) {
case101: {//寫進入A頁面的代碼
break;
}
case102: {//寫進入B頁面的代碼
break;
}
case103: {//寫進入C頁面的代碼
break;
}
default:
break;
}
然后是進入相應(yīng)的界面灯荧,我這里做的處理是已知消息對應(yīng)的界面之后礁击,在appdelegate文件中包含此界面的頭文件,然后在對應(yīng)的位置處進行初始化逗载,然后present過去
case101: {
//進入A界面
AViewController *Avc = [[AViewController alloc] init];
[self.window.rootViewControllerpresentViewController:Avc?animated:YEScompletion:?nil ];
break;
}
這里的話要說明幾點
第一哆窿、以上代碼是只是針對與不帶導(dǎo)航欄的簡單頁面,并且A頁面與其上級界面并沒有數(shù)據(jù)傳遞厉斟,也就是說挚躯,A頁面的初始化并沒有用到它上一級頁面的數(shù)據(jù)
第二、很明顯擦秽,大家想要進入的頁面沒有像A這么簡單的码荔;就像我這次漩勤,有一類是進入帶有導(dǎo)航欄的頁面;有一類是進入tabbar的其中一個標(biāo)簽頁面
A.如何進入帶有導(dǎo)航欄的頁面
對于這個問題我也找了好久缩搅,試探了好幾種辦法越败,比如使用根視圖的導(dǎo)航控制器進行push,均不行誉己,最后使用的就是之前參考那個論壇上的方法眉尸;
case101: {
//進入帶有導(dǎo)航欄的A頁面
AViewController*Avc = [[AViewControlleralloc]init];
UINavigationController*planNav = [[UINavigationControlleralloc]initWithRootViewController:Avc];
[self.window.rootViewController presentViewController:planNav animated:YES ?completion: nil ];
break;
}
使用把A頁面裝入導(dǎo)航控制器中,然后present導(dǎo)航控制器就好了巨双,這樣點擊推送消息就可以進入帶有導(dǎo)航控制器的頁面了噪猾;如果A頁面是從上個界面push過來的,并且初始化的時候使用到了上級界面的一些數(shù)據(jù)筑累,這種情況的話袱蜡,就需要讓推送消息把這些數(shù)據(jù)一并推送過來,然后進行解析慢宗,在上面進行初始化的時候使用這些數(shù)據(jù)進行初始化坪蚁,相當(dāng)于斷絕它與上級界面的關(guān)系;剩下的還有一點就是導(dǎo)航欄上的返回鍵了镜沽,因為是present過去的敏晤,所以系統(tǒng)導(dǎo)航欄自帶的backBarButtonItem并不會出現(xiàn),即使你在那個present方法最后一個block參數(shù)中設(shè)置也不行缅茉;這里的話用的是之前說的那個論壇哥們說的方法嘴脾,在viewwillappear方法里面進行判斷
- (void)viewWillAppear:(BOOL)animated {
//判斷是否是點擊推送過來的,如果是的話設(shè)置左導(dǎo)航標(biāo)簽為返回鍵
NSUserDefaults*pushJudge = [NSUserDefaultsstandardUserDefaults];
if([[pushJudgeobjectForKey:@"push"]isEqualToString:@"push"]) {
//給導(dǎo)航欄加一個返回按鈕蔬墩,便于將推送進入的頁面返回出去译打,如果不是推送進入該頁面,那肯定是通過導(dǎo)航欄進入的拇颅,則頁面導(dǎo)航欄肯定會有導(dǎo)航欄自帶的leftBarButtonItem返回上一個頁面
UIBarButtonItem*leftButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReplytarget:self action:@selector(rebackToRootViewAction)];
self.navigationItem.leftBarButtonItem= leftButton;
}else{
self.navigationItem.leftBarButtonItem=nil;
}
}
- (void)rebackToRootViewAction {
//將標(biāo)示條件置空奏司,以防通過正常情況下導(dǎo)航欄進入該頁面時無法返回上一級頁面
NSUserDefaults*pushJudge = [NSUserDefaults standardUserDefaults];
[pushJudge setObject:@""forKey:@"push"];
[pushJudge synchronize];
[self dismissViewControllerAnimated:YES completion:nil];
}
就是在本地存儲NSUserDefaults中存儲用來判斷是否是點擊推送進入頁面的,這個判斷值是在goToMssageViewControllerWith:(上面找)方法中存入的樟插,即進入相應(yīng)頁面之前先設(shè)置這個值韵洋,
- (void)goToMssageViewControllerWith:(NSDictionary*)msgDic
{
//將字段存入本地
NSUserDefaults*pushJudge = [NSUserDefaults standardUserDefaults];
[pushJudge setObject:@"push"forKey:@"push"];
[pushJudge synchronize];
NSIntegerEventID = [[msgDic objectForKey:@"eventId"] integerValue];
switch(EventID) {
...
? ?}
}
這樣就能達到基本一樣的相應(yīng)頁了,點擊返回的話是返回之前應(yīng)用退入后臺時的那個頁面
B.如何進入tabbar的其中一個標(biāo)簽頁面
這個其實很簡單的黄锤,因為這個肯定不會跟上級頁面有什么關(guān)聯(lián)麻献,我用的方法是重新把所有的標(biāo)簽頁面存入一個tabbar中,然后present過去就好了猜扮;
RootTabBarController*tabBarController = [RootTabBarController new];?
UINavigationController*AAController = [[UINavigationController alloc] initWithRootViewController:[AAViewController new]];
UINavigationController*BBController = [[UINavigationController alloc] initWithRootViewController:[BBViewController new]];
UINavigationController*CCController = [[UINavigationController alloc] initWithRootViewController:[CCViewController new]];
NSArray*array_controllers = [NSArray arrayWithObjects:AAController,BBController,CCController,nil];
tabBarController.viewControllers= array_controllers;
tabBarController.selectedViewController= [tabBarController.viewControllersobjectAtIndex:2];
[tabBarControllersetSelBtn:2];
[self.window.rootViewControllerpresentViewController:tabBarControlleranimated:YEScompletion:nil];