IOS: Push Notifications, UIApplicationStateInactive, and Fast Application Switching

According to Apple's docs, to find out if a user is listening to your push notification, you should check applicationState in application:didReceiveRemoteNotification:

If the value is UIApplicationStateInactive, the user clicked the action button; if this value is UIApplicationStateActive, the application was the earliest when it received the notification.

I have found that this is not always the case. For instance:

Double-click the home button to open the system tray and enter “quick application switching mode”, your application slides to show other running applications, and your application will be inactive (although it is still the most accessible). If you receive a push notification in this mode, your application delegate will still receive application:didReceiveRemoteNotification: and at that point UIApplicationStateActive application will be UIApplicationStateActive . According to the docs, you should treat it the same way the user listened to the warning ... but in this case they did not. In addition, the user did not even see push notifications (possibly because the top of your application is disabled in this mode).

Does anyone know how to find yourself in quick app switching mode or handle notification properly?

+6
source share
1 answer

I was able to fix this with some great checks ...

Essentially, the key to this goal is

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

This method is not called when entering a quick application switch (or control center), so you need to configure a check based on this.

 @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 get 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]; } } 

Another thing you might want to do is check out this special case of switching to quickly switching applications and the user going somewhere else. I do this before installing isInBackground BOOL. I prefer 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; } 
+4
source

Source: https://habr.com/ru/post/953523/


All Articles