ios - 应用程序未运行时不会收到远程通知

标签 ios objective-c push-notification parse-platform

我的应用程序在未运行时不会收到推送通知。 我正在尝试处理以 JSON 形式发送的远程通知,并使用给定 JSON 中的数据更新应用程序中的数据。 当应用程序处于事件状态或在后台时,一切进展顺利。 但是,当应用程序未运行时,仅当我通过点击通知打开应用程序时,应用程序才会处理通知,但当我通过点击图标打开应用程序时,应用程序不会处理通知。 以下是 appDelegate 类的代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Parse setApplicationId:appId
              clientKey:clKey];

   if (application.applicationState != UIApplicationStateBackground) {

     BOOL preBackgroundPush = ![application respondsToSelector:@selector(backgroundRefreshStatus)];
     BOOL oldPushHandlerOnly = ![self respondsToSelector:@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)];
     BOOL noPushPayload = ![launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
     if (preBackgroundPush || oldPushHandlerOnly || noPushPayload) {
        [PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
     }
   }
   [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|
                                                UIRemoteNotificationTypeAlert|
                                                UIRemoteNotificationTypeSound|
                        UIRemoteNotificationTypeNewsstandContentAvailability];
   NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];

   [self processPushNotification:notificationPayload foreground:YES];
   return YES;
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  TFLog(@"didRegisterForRemoteNotificationsWithDeviceToken");
// Store the deviceToken in the current installation and save it to Parse.
  PFInstallation *currentInstallation = [PFInstallation currentInstallation];
  [currentInstallation setDeviceTokenFromData:deviceToken];
  [currentInstallation saveInBackground];

  TFLog(@"deviceToken: %@, currentInstallation.badge: %ld", currentInstallation.deviceToken, (long)currentInstallation.badge);

  TFLog(@"deviceToken: %@, deviceType: %@", currentInstallation.deviceToken, currentInstallation.deviceType);
  TFLog(@"installationId: %@", currentInstallation.installationId);
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  TFLog(@"didFailToRegisterForRemoteNotificationsWithError %@", error);
  if (error.code == 3010) {
    TFLog(@"Push notifications are not supported in the iOS Simulator.");
  } else {
    // show some alert or otherwise handle the failure to register.
    TFLog(@"application:didFailToRegisterForRemoteNotificationsWithError: %@", error);
  }
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  TFLog(@"%@", userInfo);
  [PFPush handlePush:userInfo];
  [self processPushNotification:userInfo foreground:YES];
  [PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  TFLog(@"didReceiveRemoteNotification2");
  [self processPushNotification:userInfo foreground:YES];
  [PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
}

因此,应用程序在所有状态下都会接收远程通知,但未运行时除外。 我错过了什么?

最佳答案

您错过了 Local and Push Notification Programming Guide 中的部分它说的地方 -

If the action button is tapped (on a device running iOS), the system launches the application and the application calls its delegate’s application:didFinishLaunchingWithOptions: method (if implemented); it passes in the notification payload (for remote notifications) or the local-notification object (for local notifications).

If the application icon is tapped on a device running iOS, the application calls the same method, but furnishes no information about the notification

此外,Apple 的此说明 -

Important: Delivery of notifications is a “best effort”, not guaranteed. It is not intended to deliver data to your app, only to notify the user that there is new data available.

如果您的应用程序是从应用程序图标而不是通知启动的,您需要检查更新的内容,而与可能收到的任何推送通知无关。这使得应用程序在从通知打开时和从应用程序图标打开时表现不同。

例如,Facebook 应用程序从通知警报启动时会直接打开通知中的项目,但从应用程序图标启动时则不会 - 从用户的角度来看,这是“正确”的行为。如果我与通知进行交互,那么我对其内容感兴趣。如果我从图标启动应用程序,那么我只想使用该应用程序 - 如果需要,我可以访问应用程序中的通知。

关于ios - 应用程序未运行时不会收到远程通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22962873/

相关文章:

ios - swift生成的IPA好大,大约5MB

ios - 隐藏 `UITableViewCell`的越界部分

iphone - 对象 "sending messages"是什么意思?协议(protocol)如何帮助对象通告它支持的消息?

ios - 在静态库中获取设备 token

用于测试的 iOS 推送通知分发

objective-c - UITextView 返回 null

iOS 8 - 无法获取当前位置,错误域=kCLErrorDomain 代码=0

ios - 自定义 Xcode IDE 插件错误 : "Could not find class named..."

java - 如何指定在 NSMenuItem(最小化窗口指示器)中显示菱形?

push-notification - 增强推送格式是否防止被苹果断开连接?