Метод удаленного уведомления называется дважды

Я выполнил application:didReceiveRemoteNotification:fetchCompletionHandler: в своем делете делегата для ответа на push-уведомления.

Когда уведомление получено, когда приложение находится в фоновом режиме, этот метод вызывается немедленно, и я беру новые данные и выполняю блок завершения по завершении. Все в соответствии с документацией. Однако, если я нажму уведомление о уведомлении, этот метод снова вызван, что приведет к другому сетевому вызову и обновлению пользовательского интерфейса. Я бы ожидал, что этот метод будет вызываться один раз для каждого push-уведомления, а не один раз при получении и снова в действии.

Как другие реализовали этот метод?

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [self loadSomeResource:^(NSData *data,NSError *error){
        if (error) {
            completionHandler(UIBackgroundFetchResultFailed);
        }
        else if (data){
            completionHandler(UIBackgroundFetchResultNewData);
        }
        else {
            completionHandler(UIBackgroundFetchResultNoData);
        }
    }];
}

Ответ 1

Вот что нужно заметить в приложении: didReceiveRemoteNotification: fetchCompletionHandler: метод, когда вы получаете push-уведомление:
1. Когда приложение не запускается (т.е. Когда приложение не находится ни в фоновом режиме, ни на переднем плане), метод вызывается один раз, а applicationState будет UIApplicationStateInactive.
2. Когда приложение находится на переднем плане, метод вызывается один раз, а applicationState - UIApplicationStateActive.
3. Когда приложение находится в фоновом режиме, метод вызывается дважды, один раз, когда вы получаете push-уведомление, и в другое время, когда вы нажимаете на это уведомление. Когда вы получаете push-уведомление, ApplicationState будет UIApplicationStateBackground, и при нажатии на это уведомление ApplicationState будет UIApplicationStateInactive.

Мы можем игнорировать его, когда applicationState будет UIApplicationStateBackground, и, следовательно, мы можем обрабатывать push-уведомление только один раз для всех трех сценариев.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    if (application.applicationState == UIApplicationStateBackground) {
        completionHandler(UIBackgroundFetchResultNoData);
        return;
    }

    // Do whatever you need here and call completionHandler with appropriate UIBackgroundFetchResult
}

Ответ 2

Проверьте приложение application.applicationState, чтобы узнать, находитесь ли вы в фоновом режиме или неактивны и действуете соответственно.