在显示推送通知VS静音推送之前,推送触发后台刷新的通知

时间:2015-06-10 15:39:39

标签: ios objective-c push-notification

我想在我的应用中实现后台刷新功能,以便在收到推送时。就在向用户显示推送通知之前,我想从后端(Parse.com)下载新消息并将其保存到阵列中。我正在按照此处的指南进行操作:http://developer.xamarin.com/guides/ios/application_fundamentals/backgrounding/part_3_ios_backgrounding_techniques/updating_an_application_in_the_background/

我不确定本指南的准确性如何。它声明: iOS 7(及更高版本)通过为应用程序提供在后台通知用户之前更新内容的机会来扩展普通推送通知,以便用户可以打开应用程序并进行呈现立即使用新内容。

所以我尝试实现我的背景推送:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{


    if([[userInfo objectForKey:@"aps"] objectForKey:@"content-available"]){

        NSLog(@"Doing the background refresh");
        UINavigationController *navigationController=(UINavigationController *)[[[UIApplication sharedApplication] keyWindow] rootViewController];

        MyViewController *myViewController = (MyViewController *)[[navigationController viewControllers] objectAtIndex:1];

        [myViewController.currentUser refreshMessagesArrayWithCompletionHandler:^(BOOL successful, BOOL newMiaos) {

            NSLog(@"messages refreshed the array now has %lu messages",(unsigned long)[myViewController.currentUser.messages count]);
            handler(UIBackgroundFetchResultNewData);
        }];
    }
}

调用后台刷新并显示推送,但推送通知不等待后台任务完成。它只是在收到后立即显示。这是正确的功能吗?上面的教程建议在后台任务完成之前不会显示通知。

然后我尝试了无声通知,这会触发应用程序在收到推送时在后台下载邮件,但不会显示任何通知。因此,我通过在下载完成后触发本地通知来执行此操作。这真的是正确的做法吗?传统应用程序(如whatsapp)是否使用静默通知触发后台刷新,然后触发本地应用程序?看起来有点hacky。当然,后台推送的想法是在显示通知之前准备好数据,但它并不像那样工作..

我注意到的另一件事是静默通知速率限制它们的优先级低于典型的推送通知,所以这肯定会妨碍应用程序的效率......

对此的任何指示都会非常感激。如果我正在以正确的方式接近这个问题,那就试着试试。一切看起来都非常hacky ......

2 个答案:

答案 0 :(得分:17)

我在messaging app中一直在努力完成相同的任务。我们希望用户在用户点击通知之前就能看到该消息。 我们面临的是:

  • 有效负载大小限制。 iOS 7只能有256个字节用于有效载荷
  • 单个无提示通知无法启动应用程序(如果未运行)
  • content-available没有提醒机构的通知甚至可能无法发送到设备
  • 后台提取不受您的应用控制,因此您可能永远不会收到所需的信号,因此我们无法依赖此功能。但这可能有助于实现我们想要的另一种方式
  • iOS 8有足够的空间用于有效载荷 - 2KB
  • 如果你发送警报正文 content-available - 它会在大多数情况下发送,应用程序可以处理它

所以我们找到了唯一可接受的解决方案:我们决定仅在ios8 +中使用此功能。我们使用content-available密钥发送可见推送通知,这允许我们在流程正在运行/冻结时处理通知有效负载,并且如果应用程序未运行,则都能够显示通知。如果应用程序收到推送通知,它会将警报文本正文写入本地数据库,因此用户可以在对话中读取它。根据我们的统计数据,消息的平均大小不超过200个符号,因此大多数情况下不需要额外的请求。如果消息长于200个符号,我们使用额外参数扩展有效负载体,该参数用于在推送通知处理中请求文本体。用户将看到文本的裁剪版本,但在请求完成后,我们使用收到的值重写本地数据库中的消息。

因此,该技术允许我们在大多数情况下立即向用户显示收到的消息+如果应用程序未运行,我们请求我们的服务器在应用程序启动后立即获取丢失的消息。这是我们可以在iOS上获得的最快和最可接受的案例。希望我的经验能帮助你实现你想要的。

答案 1 :(得分:9)

你把一些东西混合在一起。

通过快速查看您的链接,这是xamarin的指南。可能有一些正确的信息,但如果你没有使用xamarin,我会搜索另一个教程。

一个好的方法是向用户发送静默通知,并在完成后触发本地通知(根本不是hacky)。

这就是whatsApp的工作方式:

当whatsApp处于后台时,会收到单个推送通知(例如“5”)该消息将不会显示给用户。

whatsApp在方法application:didReceiveRemoteNotification:fetchCompletionHandler:中接收它并检查其服务器是否在用户未收到“5”之前有任何通知。如果是这种情况,他们将从他们的服务器中提取数据并使用本地通知将其呈现给用户,这基本上只是一种呈现数据而与APNS无关的方式。

你可以阅读完整的答案&在我写的另一个答案中的上下文here