iOS:推送通知、UIApplicationStateInactive 和快速应用切换

Posted

技术标签:

【中文标题】iOS:推送通知、UIApplicationStateInactive 和快速应用切换【英文标题】:iOS: Push notifications, UIApplicationStateInactive and fast app switching 【发布时间】:2013-09-09 21:20:04 【问题描述】:

根据 Apple Docs,为了了解用户是否点击您的推送通知,您应该检查 application:didReceiveRemoteNotification: 中的 applicationState

如果值为 UIApplicationStateInactive,则用户点击了操作按钮;如果值为 UIApplicationStateActive,则应用程序在收到通知时位于最前面。

我发现这并不总是正确的。例如:

双击主页按钮显示系统托盘并进入“快速应用程序切换模式”,您的应用程序向上滑动以显示其他正在运行的应用程序,您的应用程序进入非活动状态(即使它仍然可见)。如果您在此模式下收到推送通知,您的应用程序委托仍然会收到 application:didReceiveRemoteNotification:,此时您的 applicationState 为 UIApplicationStateActive。根据文档,您应该像用户点击警报一样对待它......但在这种情况下他们没有。不仅如此,用户甚至没有看到推送通知(可能是因为您的应用程序的顶部在这种模式下被切断了)。

有谁知道一种方法来检测是否处于“快速应用切换模式”或正确处理通知?

【问题讨论】:

【参考方案1】:

我能够自己通过一些漂亮的检查来修复它......

基本上这整件事的关键是

-(void)applicationDidEnterBackground:(UIApplication *)application;

进入快速应用切换(或控制中心)时不会调用此方法,因此需要根据它设置检查。

@property                     BOOL isInBackground;
@property (nonatomic, retain) NSMutableArray *queuedNotifications;

当你收到通知时……

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
 UIApplicationState appState = application.applicationState;
 // Check if we're in this special state. If so, queue the message up
 if (appState == UIApplicationStateInactive && !self.isInBackground) 
    // This is a special case in which we're in fast app switching or control center
    if (!self.queuedNotifications) 
        self.queuedNotifications = [NSMutableArray array];
    

    // Queue this to show when we come back
    [self.queuedNotifications addObject:userInfo];
 

然后当我们回来时......

- (void)applicationDidBecomeActive:(UIApplication *)application 
     application.applicationIconBadgeNumber = 0;


 if (!self.isInBackground) 
    // Show your notifications here

    // Then make sure to reset your array of queued notifications
    self.queuedNotifications = [NSMutableArray array];
 

您可能想要做的另一件事是检查这种特殊情况,即快速切换应用程序和用户去其他地方。我在设置 isInBackground BOOL 之前执行此操作。我选择将它们作为本地通知发送

-(void)applicationDidEnterBackground:(UIApplication *)application 

  for (NSDictionary *eachNotification in self.queuedNotifications) 
     UILocalNotification *notification = [self convertUserInfoToLocalNotification:eachNotification];
     [[UIApplication sharedApplication] scheduleLocalNotification:notification];
 
 self.queuedNotifications = [NSMutableArray array];
 self.isInBackground = YES;

【讨论】:

以上是关于iOS:推送通知、UIApplicationStateInactive 和快速应用切换的主要内容,如果未能解决你的问题,请参考以下文章

ios推送通知之ios推送证书的申请和使用配置

ios推送通知之ios证书的申请和使用配置

Xamarin iOS - 推送通知 - 区分点击的推送通知与到达

iOS推送通知和远程通知的区别?

iOS(本地通知与远程通知)

我们可以控制推送通知的“允许推送通知”对话框 ios 吗?