草庐IT

ios - App未运行时收不到远程通知

coder 2024-01-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];
}

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

最佳答案

您错过了 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 - App未运行时收不到远程通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22962873/

有关ios - App未运行时收不到远程通知的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  4. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  7. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  8. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  9. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  10. ruby-on-rails - 无法让 rspec、spork 和调试器正常运行 - 2

    GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'

随机推荐