实现didReceiveRemoteNotification以在推送到来时显示新的viewController

时间:2015-04-05 11:42:04

标签: ios objective-c iphone

我有一个应用程序应该在远程推送通知到来时加载ViewController,我的代码目前在我的appDelegate.m中:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    NSLog(@"REMOTE NOTIFICATION %@", userInfo);
    if( [[MTMAPIClient sharedClient] isLoggedIn: nil]){
        if (userInfo && userInfo[@"aps"] && userInfo[@"aps"][@"extra"]) {
            if ( application.applicationState == UIApplicationStateActive ) {
                [self playSound];
            }
        }

        [NotificationHelper pushNotificationCame:userInfo view:self.tabBarController.selectedViewController];
    }
}

我的应用程序是一个标签式应用程序(如AppStore和iTunes),我在appDelegate中保留了对UITabBarController的引用。

我的通知助手代码是:

+ (void) pushNotificationCame:(NSDictionary*)userInfo view:(UINavigationController*) viewController
{
    NSString* otp;
    if (userInfo && userInfo[@"aps"] && userInfo[@"aps"][@"extra"]) {

        otp = (NSString*)userInfo[@"aps"][@"extra"][@"otp"];


       [Authorization loadAuthByOtp:otp
                            success:^(Authorization *auth) {
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryBoard" bundle:[NSBundle mainBundle]];
                                    TransactionDetailViewController* appTransactionDetailsView = [storyboard instantiateViewControllerWithIdentifier:@"transactionDetails"];
                                    appTransactionDetailsView.authorization = auth;
                                    [viewController pushViewController:appTransactionDetailsView animated:YES];
                                });

                            } failure:^(NSString *error, ErrorType errorType) {
                                NSLog(@"pushNotificationCame loadAuthByOtp failed with error: %@", error);
                            }];
    }
}

这在70%的场景中有效,但有时当我退出应用程序并重新登录时,推送通知自带了。在pushNotificationCame方法中的self.tabBarController.selectedViewController和“viewController”不是我标签中当前活动的视图Bar所以PushViewController不起作用。

换句话说,我的应用程序选项卡A,B,C中有三个选项卡,当推送通知到来时我在选项卡A但调试器中的self.tabBarController.selectedViewController是B viewController所以当我推送一个新的viewController时,它转到选项卡B没有任何反应。没有错误,但没有新的viewController。只有当我退出并回到应用程序时才会发生这种情况,通常情况下它才有效!

我的退出代码:

[viewController.navigationController.tabBarController performSegueWithIdentifier:@"logoutSegue" sender:viewController];

和我的代码登录:

[self performSegueWithIdentifier:@"fromSignInToApplications" sender:self];

将用户带到TabBarController的第一个标签页。

和AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
    self.tabBarController = (UITabBarController *)self.window.rootViewController;
}

1 个答案:

答案 0 :(得分:1)

看起来问题是你在登出/登录时正在构建一堆视图控制器,所以在堆栈的根目录下你有原始的选项卡视图控制器然后你有注销,然后登录,然后一个新的标签视图控制器。此时,app委托仍然具有对原始选项卡视图控制器的引用,并且不再有任何工作。

(注意,您可能没有注销视图控制器,但原则适用于登录视图控制器)

您应该考虑做的是呈现注销和登录视图控制器而不是推送它们,然后,当登录完成时,而不是使用fromSignInToApplications推送,您将再次关闭并显示原始选项卡视图控制器。这也使用较少的内存,并可能导致观察等未来问题较少。

替代方法是在segue之后发布登录通知,以便app delegate可以获得新的选项卡视图控制器 - 但是,它不是窗口根视图控制器,因此您需要进行一些更改或考虑这将是如何工作的。