简体   繁体   中英

Identifying the trigger of iOS Remote notifications callback

Suppose you implement email client application. When a new mail is received, a notification should be displayed, and the app should pull the new mail ASAP. When the user taps the notification in the notification center, the app should display the new mail. However, if he opens the application directly (not through the notification) he should see the list of mails already updated with the latest data.

Ideally, the app would have a callback called upon arrival of a notification with {content-available:1} for updating the data, and another callback when the user clicks the notification.

However, if the app implements application:didReceiveRemoteNotification:fetchCompletionHandler: the same callback might be called twice - once immediately when the notification arrives, and again if the user clicks the notification in the notification center.

So, when the callback is triggered, how should the app know if it should navigate to the new mail (when the user taps the notification) or fetch the data (called by the system)?

Update - I tried querying the applicationState according to this answer . This doesn't help as when the user opens the control center and a notification is received (but not tapped), the application is in inactive state, same as it is when the user taps the notification.

I agree that it's rather strange and inconvenient that the same method is called for both "background-fetch" and "user-did-tap-on-notification".

You should be able to use the app's UIApplicationState to take action on a Notification, either by triggering a background fetch or presenting UI.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

    switch ([UIApplication sharedApplication].applicationState) {
        case UIApplicationStateBackground: {
            // Fetch data in background
            // TODO

            break;
        }
        case UIApplicationStateInactive:
            // User Tapped Notification

            // If needed:
            // Store the Notification, to be presented when app becomes active.
            self.notificationToPresentWhenActive = userInfo;

            completionHandler(UIBackgroundFetchResultNoData);
            break;
        case UIApplicationStateActive:
            // App was open

            // Present the in-app Notification UI
            [self presentNotification:userInfo];

            completionHandler(UIBackgroundFetchResultNoData);
            break;
    }
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    if (self.notificationToPresentWhenActive) {
        [self presentNotification:self.notificationToPresentWhenActive];

        self.notificationToPresentWhenActive = nil;
    }
}

Update - I tried querying the applicationState according to this answer. This doesn't help as when the user opens the control center and a notification is received (but not tapped), the application is in inactive state, same as it is when the user taps the notification.

I can't reproduce this issue (iOS 9.0.2) using either Control Center (bottom) or Notification Center (top). Perhaps it was fixed in iOS 9 or one of the betas?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM