iOS:特定 View Controller 类的 didReceiveRemoteNotification

标签 ios objective-c push-notification parse-platform apple-push-notifications

场景 = 我有一个具有消息传递功能的应用程序。发送消息后,推送通知也会发送到收件人的手机。我希望用户在任何时候都能收到带有“警报”(在屏幕上显示消息)、“角标(Badge)”(红色圆圈中的应用程序图标角标(Badge)编号)和“声音”(推送时播放的声音)的推送通知没有在看 Instant Messenger 屏幕-并且当用户在 Instant Messenger 屏幕上时,我希望用户收到“角标(Badge)”和“声音”

为什么我不想在 Instant Messenger 屏幕上发送“提醒”? 因为当消息加载到 tableView 中时,即时消息屏幕已经将消息显示给用户。当他们必须一直点击它才能在屏幕上再次阅读以回复时,我为什么要将带有“警报”的 IM 推送到他们的屏幕?没有意义。

为什么我只希望用户在 IM 屏幕上时收到“角标(Badge)”? 这是因为我的应用程序不断检查应用程序的角标(Badge)计数是否会增加,因此它会在应用程序角标(Badge)出现时刷新 TableView 。我还希望播放“声音”以通过声音通知用户推送已到达他们的手机。

需要注意的事项 = 我的应用基于包含标签栏 Controller 的架构,该 Controller 包含每个标签的导航 Controller 。如果这有所作为。

编辑 - 总结和简化的问题。

你是怎么做到的?...(不是真正的代码)

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    if (isOnInstantMessagingScreen) {

        //Disable Push "Alert" messages
        //Enable Push "Badge"
        //Enable Push "Sound"
    }

    else {

        //Enable Push "Alert" messages
        //Enable Push "Badge"
        //Enable Push "Sound"
    }

最佳答案

当应用程序打开时,Apple 会将通知静音,因此您有责任显示警告或播放声音。这是个好消息,因为您不必担心取消注册通知类型。

要回答您的第一个问题,您可以通过以下方式从您的应用程序委托(delegate)访问 topMostViewController

UIViewController *topMostViewController = [(UINavigationController *)[self.tabBarController selectedViewController] topViewController];

我假设您已将 tabBarController 设置为属性

@property (strong, nonatomic) UITabBarController *tabBarController;

如果你有超过五个选项卡,selectedViewController 可以是 moreViewController 在这种情况下你可以尝试

UIViewController *topMostViewController = [(UINavigationController *)[[self.tabBarController viewControllers] objectAtIndex:[self.tabBarController selectedIndex]] topViewController];

然后您可以分配 bool 值 - 其中 MessageScreenViewController 是您的消息 Controller

isOnInstantMessagingScreen = [topMostViewController isKindOfClass:[MessageScreenViewController class]];

你会想知道应用程序是否在前台,以便显示 UIAlertView 和播放声音

if([application applicationState] == UIApplicationStateActive){}

如果用户不在消息屏幕上,您将希望显示通知并播放声音

if(!isOnInstantMessagingScreen){
   [PFPush handlePush:userInfo]; // Display alert - can also be UIAlertView

   //Play sound
   NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Notification" ofType:@"wav"]];
        AVAudioPlayer *notify  = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile  error:nil];
        [notify play];

    //Perhaps increment badge number
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber: +1];
}

这对您有帮助吗?

最终的解决方案可能类似于(未测试):

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    //The application is currently in the foreground
    if([application applicationState] == UIApplicationStateActive){
        UIViewController *topMostViewController = [(UINavigationController *)[self.tabBarController selectedViewController] topViewController];
        BOOL isOnInstantMessagingScreen = [topMostViewController isKindOfClass:[MessageScreenViewController class]];

        if(!isOnInstantMessagingScreen){
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Notification" message:[[userInfo objectForKey:@"aps"] objectForKey:@"alert"] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"View", nil];
            alert.tag = 1;
            [alert show];

            //Play sound
            NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Notification" ofType:@"wav"]];
            AVAudioPlayer *notify  = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile  error:nil];
            [notify play];

            //Perhaps increment badge number
            [[UIApplication sharedApplication] setApplicationIconBadgeNumber: +1];
        }
    } else {
        //Application is in background - When the notification is clicked on, we will get here
        [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0]; //Clear notification as we have clicked it, potentially could also be -1 to decrement?

        UINavigationController *navigationController = (UINavigationController *)[self.tabBarController.viewControllers objectAtIndex:2];
        BOOL isOnInstantMessagingScreen = [[navigationController topViewController] isKindOfClass:[MessageScreenViewController class]];

        //Perhaps we want to navigate to the message controller screen
        if(!isOnInstantMessagingScreen){

            //Somehow push the messaging screen onto the UINavigationController
            //This could be done here by alloc and initing the view controller
            MessageScreenViewController *viewContoller = [[MessageScreenViewController alloc] init];
            [navigationController pushViewController:viewContoller animated:YES];

            //Or perhaps by calling a function on the rootView of the UINavigationController
            RootViewController *rootViewController = (RootViewController *)[navigationController.viewControllers objectAtIndex:0];
            [rootViewController loadMessageScreenWithUserInfo:userInfo];

            //Show tab
            [self.tabBarController setSelectedIndex:2]; // Index of NavigationController which will contain the MessageViewController
        }
    }
}

关于iOS:特定 View Controller 类的 didReceiveRemoteNotification,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24986123/

相关文章:

php - 如何在android中安排通知并在固定时间发送

ios - 如何在 Xcode 中执行数据驱动测试

ios - 尝试圆形图像,输出菱形?

objective-c - PDF 未正确显示

objective-c - HDR 和全景图 : where to learn

objective-c - UIDatePicker Date 属性不会设置所选日期 - 而是给出当前日期

ios - 获取新的 Apple 设备 token ?

ios - 自动保存和加载使用

ios - 我可以在 iOS 中使用 AllJoyn 框架进行 Wifi Direct 吗?

email - 网站或服务器停机通知工具