推送跳轉到指定的controllers

以前做過推送, 但只是那種最基本的廣播推送(向所有安裝appde設備通知), 列播組播這種對指定用戶推送消息還沒做過, 最近剛好有個項目,向指定用戶推送物流信息、物品狀態等等。於是前幾天就和也沒做過推送的後臺幹起來了,詳情如下:

我用的是友盟推送, 配置證書這一環節直接跳過了,這個網上有講的。給大家講一點常識,友盟推送分生產環境和開發環境。用手機刷上去的就是開發環境, 發佈到蘋果商店就是生產環境,沒發佈前怎麼模擬呢, 用普通賬號打的ad hoc 包, 用企業賬號打的ad hoc 包或者enterprise包都可以測試生產環境。


開發環境下, 你把APP刪掉,重新調試上來,就會生成一個新的device_token了!下面的幾個步驟是自己的理解結合網上的資料寫出的想法,大牛們輕的吐槽……

1、傳device_token的時機

後臺向指定用戶做同送,那麼必須知道某個用戶的device_token,那麼怎麼獲取token呢,APP啓動後會在appdelegate的didRegisterForRemoteNotificationsWithDeviceToken方法裏返回device_token信息:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  [UMessage registerDeviceToken:deviceToken];
   NSString * token = [[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
                     stringByReplacingOccurrencesOfString: @">" withString: @""]
                    stringByReplacingOccurrencesOfString: @" " withString: @""];
  }

但是後臺向指定用戶推送, 就必須把uid(用戶ID)和token關聯起來,我這裏的做法時, 用戶登錄的時候就上傳token信息, 退出登錄的時候, 就清除用戶綁定的token信息, 這樣確保後臺會向用戶最後一次登錄的設備號做推送(只是自己的理解,當然了,iOS設備收到推送後,還要判斷用戶是否登錄而且登錄的是不是你要推送的用戶)。

2、 收到通知時app的狀態

收到通知的時候APP的狀態可能是未啓動、前臺活躍(任何界面)、後臺等三種。

  • 未啓動時,點擊通知欄啓動App, 會在didFinishLaunchingWithOptions方法裏收到通知內容。
  • 剩下兩種會在didReceiveRemoteNotification方法裏收到通內容。

    - (void)application:(UIApplication *)application   didReceiveRemoteNotification:(NSDictionary *)userInfo{
     _userInfo = userInfo;
       //關閉友盟對話框
     [UMessage setAutoAlert:NO];
     [UMessage didReceiveRemoteNotification:userInfo];
     NSLog(@"_______________友盟系統方法 userInfo %@",userInfo);
    if(userInfo)// 調用appdelegate的分類處理業務邏輯
      [self dealWithMyMessagePush:userInfo];
    }

    代碼裏面刪減了一些和推送不相關的代碼,我的項目架構是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;
    }
  • 未啓動時收到通知,就判斷字典userInfo是否爲空, 不爲空是說明有通知消息。我這裏的做法是把她複製給AppDelegate的某個屬性, 在首頁控制器取到AppDelegate的這個值,判斷是否爲空,不爲空就進行下一步操作。
  • 用戶在前臺或後臺收到消息的時候, 我會彈出一個彈出框提醒用戶,是否前往我的消息界面。

5、 未啓動時首頁控制器邏輯處理

在viewDidLoad方法裏:
AppDelegate * app = (AppDelegate *)[UIApplication sharedApplication].delegate;
//pushName 是我給後天約定的通知必傳值,所以我可以根據他是否爲空來判斷是否有通知
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
{// 這就文章標題說的某一界面
   MyUserMessageVC * messageVC = [[MyUserMessageVC alloc] initWithNibName:@"MyUserMessageVC" bundle:nil];
    [self.navigationController pushViewController:messageVC animated:YES];
 }
}

當用戶的登錄成功的時候,在上傳device_token的接口方法裏, 需要判斷登錄用戶的uid是不是你要通知的用戶。如果不是你要通知的用戶,dismiss就好了,結束;如果是就要跳轉到我的消息界面。

   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控制器當前顯示的控制器
  UIViewController * baseVC = (UIViewController *)nav.visibleViewController;
//如果是當前控制器是我的消息控制器的話,刷新數據即可
if([baseVC isKindOfClass:[MyUserMessageVC class]])
{
    MyUserMessageVC * vc = (MyUserMessageVC *)baseVC;
    [vc reloadMessageData];
    return;
}
// 否則,跳轉到我的消息
MyUserMessageVC * messageVC = [[MyUserMessageVC alloc] initWithNibName:@"MyUserMessageVC" bundle:nil];
[nav pushViewController:messageVC animated:YES];
}

6、應用在前臺或後臺的邏輯處理

邏輯和未啓動時很多情況都是類似,彈出提醒框, 點擊立即前往時,判斷用戶是否登錄,如果用戶登錄,直接跳轉到我的消息界面;沒有登錄請參考上面邏輯。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章