【问题标题】:iOS UNUserNotificationCenter didReceiveNotificationResponse only run code if app is open in backgroundiOS UNUserNotificationCenter didReceiveNotificationResponse 仅在应用程序在后台打开时运行代码
【发布时间】:2020-12-15 09:11:30
【问题描述】:

如果应用是inactivebackground,是否可以有条件地运行代码。

这是两种情况:

  • 如果应用在后台或处于非活动状态,我确实希望运行此代码块。
  • 如果应用程序被终止并按下通知启动应用程序,我不想运行此代码块。

这是我的代码:

// Push notification received in background
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
  NSDictionary *userInfo = response.notification.request.content.userInfo;

  [[SEGAnalytics sharedAnalytics] receivedRemoteNotification:userInfo];

  if ([HSBeacon isBeaconPushNotification:userInfo]) {
    UIApplication *applicaiton = [UIApplication sharedApplication];

    // @todo Do not run if app was killed
    if (application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground) {
      NSString *helpScoutBeaconID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HelpScoutBeaconID"];
      HSBeaconSettings *settings = [[HSBeaconSettings alloc] initWithBeaconId:helpScoutBeaconID];
      [HSBeacon handlePushNotification:userInfo beaconSettings:settings];
    }
    // End of conditional code
  }

  completionHandler();
}

我尝试过使用:

    UIApplication *applicaiton = [UIApplication sharedApplication];

    if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground) {
      ...
    }

但是当应用程序被终止、不活动或在后台时会触发。

谢谢

【问题讨论】:

    标签: ios objective-c iphone push-notification apple-push-notifications


    【解决方案1】:

    感谢@ScottPetit 的回答!我不得不改变一些东西,但得到了它的工作:

    AppDelegate.h

    // Use a local variable to determine if we deeplink to help scout chat
    @property (nonatomic, assign) BOOL launchedFromPushNotification;
    

    AppDelegate.m

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
      NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
      if (notification) {
        self.launchedFromPushNotification = YES;
      } else {
        self.launchedFromPushNotification = NO;
      }
    
      ...
    }
    
    
    // Push notification received in foreground
     - (void)userNotificationCenter:(UNUserNotificationCenter *)center
    willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
      self.launchedFromPushNotification = NO;
    }
    
    // Push notification received in background
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
      NSDictionary *userInfo = response.notification.request.content.userInfo;
    
      if ([HSBeacon isBeaconPushNotification:userInfo] && !self.launchedFromPushNotification) {
        NSString *helpScoutBeaconID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HelpScoutBeaconID"];
        HSBeaconSettings *settings = [[HSBeaconSettings alloc] initWithBeaconId:helpScoutBeaconID];
        [HSBeacon handlePushNotification:userInfo beaconSettings:settings];
    
        self.launchedFromPushNotification = NO;
      }
    
      completionHandler();
    }
    

    感谢您的帮助!

    【讨论】:

      【解决方案2】:

      感觉必须有更好的方法来做到这一点,但我认为可行的一种方法是保留您设置的局部变量:

      - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler;
      

      仅当应用程序当前处于前台时才会调用该委托,因此如果您有类似的属性

      @property (nonatomic, assign) BOOL receivedWillPresentNotification;
      

      那么你可能会像这样实现这个

      - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
        // Whatever other logic you have here
        self.receivedWillPresentNotification = YES;
      }
      
      - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
        NSDictionary *userInfo = response.notification.request.content.userInfo;
      
        [[SEGAnalytics sharedAnalytics] receivedRemoteNotification:userInfo];
      
        if ([HSBeacon isBeaconPushNotification:userInfo] && self.receivedWillPresentNotification) {
            NSString *helpScoutBeaconID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HelpScoutBeaconID"];
            HSBeaconSettings *settings = [[HSBeaconSettings alloc] initWithBeaconId:helpScoutBeaconID];
            [HSBeacon handlePushNotification:userInfo beaconSettings:settings];
        }
      
        self.receivedWillPresentNotification = NO;
        completionHandler();
      }
      

      可能还有一个更好的解决方案,与检查 applicationDidFinishLaunching 中的通知和检查应用程序的状态有关,然后您可以在那里存储,但我认为您可能会使用另一个 @ 987654325@ 方法作为代理。

      【讨论】:

        猜你喜欢
        • 2020-08-31
        • 2017-12-25
        • 2011-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-09
        • 2012-05-27
        相关资源
        最近更新 更多