【问题标题】:App doesn't receive remote notification when it is not running应用未运行时未收到远程通知
【发布时间】:2014-04-09 12:41:19
【问题描述】:

我的应用在未运行时不会收到推送通知。 我正在尝试处理以 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];
}

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

【问题讨论】:

  • 你设置了后台模式remote-notification 吗?
  • 在 plist 文件中我设置了“必需的后台模式 = 应用下载内容以响应推送通知”。

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


【解决方案1】:

你错过了Local and Push Notification Programming Guide 中的那个位-

如果点击操作按钮(在运行 iOS 的设备上),系统 启动应用程序,应用程序调用其委托的 应用程序:didFinishLaunchingWithOptions:方法(如果实现);它 传入通知有效负载(用于远程通知)或 local-notification 对象(用于本地通知)。

如果在运行 iOS 的设备上点击应用程序图标, 应用程序调用相同的方法,但没有提供关于 通知

另外,来自 Apple 的这份说明 -

重要提示:发送通知是“尽力而为”,而不是 保证。它并非旨在向您的应用程序提供数据,仅用于 通知用户有新数据可用。

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

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

【讨论】:

  • 只有当内容在服务器上可用时才有效。谢谢!
  • 我还有一个关于“未运行”应用程序的远程通知的问题。当我发送简单推送通知(简单文本)时,应用程序图标上的徽章会增加,但是当我发送 JSON 时,它不会增加。问题出在哪里?
  • 需要在aps字典中指定badge键-developer.apple.com/library/ios/documentation/…
  • 指定了徽章键,应用图标上的徽章只有在应用未运行时才会增加。
  • 您为徽章发送什么价值:?它不会增加,您必须发送要显示的数字或 0 以清除徽章
【解决方案2】:

当您通过显式点击应用图标启动应用时,您无法获取有关您的推送通知 JSON 负载的信息。

这是按照 Apple 的设计。当您从任何推送通知操作打开应用程序时,您可以在application: didFinishLaunchingWithOptions: 委托方法中检索推送通知。通常,您会在您的 launchOptions 字典中查找 UIApplicationLaunchOptionsRemoteNotificationKey 键。

但是,当您通过显式点击应用程序图标打开应用程序时,尽管仍会调用 application: didFinishLaunchingWithOptions: 委托,但 UIApplicationLaunchOptionsRemoteNotificationKey 键将返回 nil

【讨论】:

  • 如果用户不点击通知有效负载,解决方案是什么。如果用户通过单击应用程序图标直接打开应用程序 UIApplicationLaunchOptionsRemoteNotificationKey 返回 nil
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
相关资源
最近更新 更多