本文介绍了iOS:推送通知,UIApplicationStateInactive和快速应用切换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我发现这并非总是如此。例如:



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



解决方案

我能够通过一些漂亮的支票来解决这个问题......



基本上这一切的关键是

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

当您输入快速应用切换(或控制中心)时,不会调用此方法,因此您需要根据它设置支票。

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

当您收到通知时......

   - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIApplicationState appState = application.applicationState;
//检查我们是否处于这种特殊状态。如果是这样,请将消息排队
if(appState == UIApplicationStateInactive&&!self.isInBackground){
//这是我们在快速app切换或控制中心的特殊情况
if(!self.queuedNotifications){
self.queuedNotifications = [NSMutableArray array];
}

//排队时显示我们何时回来
[self.queuedNotifications addObject:userInfo];
}
}

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

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


if(!self.isInBackground){
//在此处显示通知

//然后确保重置排队通知数组
self.queuedNotifications = [NSMutableArray array];
}
}

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

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

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


According to the Apple Docs, in order to find out if a user tapped on your push notification you are supposed to check the applicationState in application:didReceiveRemoteNotification:

I have found that this is not always true. For example:

Double-tap the home button to reveal the system tray and enter "fast app switching mode", your application slides up to reveal other running applications and your app is put into the inactive state (even though it's still mostyle visible). If you receive a push notification in this mode your app delegate will still receive the application:didReceiveRemoteNotification: and at this point your applicationState is UIApplicationStateActive. According to the docs you should treat it like the user tapped the alert... but in this case they didn't. Not only that, the user didn't even see the push notification (possibly because the top of your application is cut off in this mode).

Does anyone know of a way to detect being in 'fast app switching mode' or handle the notification correctly?

解决方案

I was able to fix it myself with some nifty checks...

Essentially the key to this whole thing is

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

This method isn't called when you enter fast app switching (or control center) so you need to setup a check based on it.

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

And when you receive a notification...

- (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];
 }
}

And then when we come back...

- (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];
 }
}

One more thing you may want to do is check for this special case of going to fast app switching and the user going somewhere else. I do this just before setting the isInBackground BOOL. I choose to send them as local notifications

-(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和快速应用切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 10:14