以前做過推送, 但只是那種最基本的廣播推送(向所有安裝appde設(shè)備通知), 列播組播這種對(duì)指定用戶推送消息還沒做過, 最近剛好有個(gè)項(xiàng)目,向指定用戶推送物流信息、物品狀態(tài)等等。于是前幾天就和也沒做過推送的后臺(tái)干起來了,詳情如下:
我用的是友盟推送, 配置證書這一環(huán)節(jié)直接跳過了,這個(gè)網(wǎng)上有講的。給大家講一點(diǎn)常識(shí),友盟推送分生產(chǎn)環(huán)境和開發(fā)環(huán)境。用手機(jī)刷上去的就是開發(fā)環(huán)境, 發(fā)布到蘋果商店就是生產(chǎn)環(huán)境,沒發(fā)布前怎么模擬呢, 用普通賬號(hào)打的ad hoc 包, 用企業(yè)賬號(hào)打的ad hoc 包或者enterprise包都可以測(cè)試生產(chǎn)環(huán)境。

** 開發(fā)環(huán)境下, 你把APP刪掉,重新調(diào)試上來,就會(huì)生成一個(gè)新的device_token了!下面的幾個(gè)步驟是自己的理解結(jié)合網(wǎng)上的資料寫出的想法,大牛們輕的吐槽…… **
1、傳device_token的時(shí)機(jī)
后臺(tái)向指定用戶做推送,那么必須知道某個(gè)用戶的device_token,那么怎么獲取token呢,APP啟動(dòng)后會(huì)在appdelegate的didRegisterForRemoteNotificationsWithDeviceToken方法里返回device_token信息:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[UMessage registerDeviceToken:deviceToken];
NSString * token = [[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""]
stringByReplacingOccurrencesOfString: @" " withString: @""];
}
但是后臺(tái)向指定用戶推送, 就必須把uid(用戶ID)和token關(guān)聯(lián)起來,我這里的做法時(shí), 用戶登錄的時(shí)候就上傳token信息, 退出登錄的時(shí)候, 就清除用戶綁定的token信息, 這樣確保后臺(tái)會(huì)向用戶最后一次登錄的設(shè)備號(hào)做推送(只是自己的理解,當(dāng)然了,iOS設(shè)備收到推送后,還要判斷用戶是否登錄而且登錄的是不是你要推送的用戶)。
2、 收到通知時(shí)app的狀態(tài)
收到通知的時(shí)候APP的狀態(tài)可能是未啟動(dòng)、前臺(tái)活躍(任何界面)、后臺(tái)等三種。
未啟動(dòng)時(shí),點(diǎn)擊通知欄啟動(dòng)App, 會(huì)在didFinishLaunchingWithOptions方法里收到通知內(nèi)容。
-
剩下兩種會(huì)在didReceiveRemoteNotification方法里收到通內(nèi)容。
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{ _userInfo = userInfo; //關(guān)閉友盟對(duì)話框 [UMessage setAutoAlert:NO]; [UMessage didReceiveRemoteNotification:userInfo]; NSLog(@"_______________友盟系統(tǒng)方法 userInfo %@",userInfo); if(userInfo)// 調(diào)用appdelegate的分類處理業(yè)務(wù)邏輯 [self dealWithMyMessagePush:userInfo]; }** 代碼里面刪減了一些和推送不相關(guān)的代碼,我的項(xiàng)目架構(gòu)是tab+nav **
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window.rootViewController = [[FDIMGBarController alloc] init]; // 分類 [self UMengShareMethodAndCount:launchOptions]; // 類別 [self FD_updateAppVersion]; NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; if(userInfo){//推送信息 self.userInfo = userInfo;//[userInfo copy] } return YES; } 未啟動(dòng)時(shí)收到通知,就判斷字典userInfo是否為空, 不為空是說明有通知消息。我這里的做法是把她復(fù)制給AppDelegate的某個(gè)屬性, 在首頁控制器取到AppDelegate的這個(gè)值,判斷是否為空,不為空就進(jìn)行下一步操作。
-
用戶在前臺(tái)或后臺(tái)收到消息的時(shí)候, 我會(huì)彈出一個(gè)彈出框提醒用戶,是否前往我的消息界面。
5、 未啟動(dòng)時(shí)首頁控制器邏輯處理
在viewDidLoad方法里:
AppDelegate * app = (AppDelegate *)[UIApplication sharedApplication].delegate;
//pushName 是我給后天約定的通知必傳值,所以我可以根據(jù)他是否為空來判斷是否有通知
NSString * pushName = [[app.userInfo objectForKey:@"aps"] objectForKey:@"alert"];
if(![SYFCustomCLASS SYFIsEmptyOrNull:pushName])
[self getPushInfo:app.userInfo];
如果有通知的話:
-(void)getPushInfo:(NSDictionary *)dict{
if(!IsLogin){// 判斷用戶是否登錄
LoginViewController * loginVC = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];
//通知必返回要通知用戶的uid, 判斷登錄的用戶是不是你要通知的用戶
loginVC.push_uid = dict[@"uid"];
FDNavigationController * loginNav = [[FDNavigationController alloc] initWithRootViewController:loginVC];
[self presentViewController:loginNav animated:YES completion:^{}];
}else
{// 這就文章標(biāo)題說的某一界面
MyUserMessageVC * messageVC = [[MyUserMessageVC alloc] initWithNibName:@"MyUserMessageVC" bundle:nil];
[self.navigationController pushViewController:messageVC animated:YES];
}
}
當(dāng)用戶的登錄成功的時(shí)候,在上傳device_token的接口方法里, 需要判斷登錄用戶的uid是不是你要通知的用戶。如果不是你要通知的用戶,dismiss就好了,結(jié)束;如果是就要跳轉(zhuǎn)到我的消息界面。
if(![self.push_uid isEqualToString:currentuid])
[self dismissViewControllerAnimated:YES completion:NULL];
else{
[self dismissViewControllerAnimated:YES completion:^{
AppDelegate * app = (AppDelegate *)[UIApplication sharedApplication].delegate;
//AppDelegate的分類
[app testLoginerUidCorret];
}];
方法如下:
- (void)testLoginerUidCorret{
// 取到tabbarcontroller
FDIMGBarController *tabBarController = ( FDIMGBarController*)self.window.rootViewController;
// 取到navigationcontroller
FDNavigationController * nav = (FDNavigationController *)tabBarController.selectedViewController;
//取到nav控制器當(dāng)前顯示的控制器
UIViewController * baseVC = (UIViewController *)nav.visibleViewController;
//如果是當(dāng)前控制器是我的消息控制器的話,刷新數(shù)據(jù)即可
if([baseVC isKindOfClass:[MyUserMessageVC class]])
{
MyUserMessageVC * vc = (MyUserMessageVC *)baseVC;
[vc reloadMessageData];
return;
}
// 否則,跳轉(zhuǎn)到我的消息
MyUserMessageVC * messageVC = [[MyUserMessageVC alloc] initWithNibName:@"MyUserMessageVC" bundle:nil];
[nav pushViewController:messageVC animated:YES];
}
6、應(yīng)用在前臺(tái)或后臺(tái)的邏輯處理
邏輯和未啟動(dòng)時(shí)很多情況都是類似,彈出提醒框, 點(diǎn)擊立即前往時(shí),判斷用戶是否登錄,如果用戶登錄,直接跳轉(zhuǎn)到我的消息界面;沒有登錄請(qǐng)參考上面邏輯。
** 由于第一次做推送某一頁面,寫的不好處,請(qǐng)大家多多交流指點(diǎn),有疑問或更好的想法的可以和我說。 **