【问题标题】:iPhone app background downloadsiPhone应用后台下载
【发布时间】:2014-12-10 23:42:45
【问题描述】:

我正在制作一个接收持续更新(可能每天数百次)的应用,为了提供更好的用户体验,最好在后台下载这些更新。

查看 Apple 的[1] 文档,我需要将后台模式设置为“后台获取”。深入探索,您可以阅读application:performFetchWithCompletionHandler[2] 函数,该函数指出:

当调用此方法时,您的应用程序有最多 30 秒的挂钟时间来执行下载操作并调用指定的完成处理程序块...如果您的应用程序需要很长时间才能调用完成处理程序,它将来获取数据的机会可能会减少。

问题是我们的下载需要超过 30 秒才能下载,因此宁愿不面对 Apple 发送更新越来越少的愤怒,因此加剧问题!

那么,我能以某种方式做到这一点吗?

另外,我创建了一个粗略的实验,我创建了一个NSTimer:scheduledTimerWithTimeInterval 来运行每分钟记录到控制台的日志。这在模拟的 iPhone 上(已经运行了 30 分钟以上)以及当我将它放在手机上(一周以上)时都成功运行......为什么会这样!?

【问题讨论】:

  • 如果您的下载时间真的超过 30 秒,可能每天数百次,那么您可能会首先面对没有无限数据或内存的用户的愤怒。您也可以在您的应用程序中使用 performSelectorInBackground 来执行基本相同的操作(从您的描述中可以看出),而无需处理后台获取。

标签: ios objective-c iphone xcode


【解决方案1】:

由于 Apple 30 年代的义务,这可能很难做到。他们决定这样做是为了最终防止发生大下载,以免耗尽电池和数据计划。

您必须确定您确实需要在后台下载这么多数据(因为它需要这么长时间),而且每天要下载数百次!

我的意思是,当您的应用程序在(长时间)后台运行后进入前台时,它可能不会更新,这是正常情况。因此,您需要在应用程序进入前台时进行更新;只需要一次更新。否则,您应该退后一步,重新考虑更新过程。

【讨论】:

  • 我们将提供增量更新,因此每次下载将相对较小(几个 k,并且需要不到 30 秒)。但是,如果用户没有一致的连接,那么这些更新将缓慢增长,下载/处理时间将超过 30 秒。正是这些我们不想受到惩罚,因为这意味着更新过程的调用频率会降低,从而导致这些更大的下载量。
  • 好的,现在不同了。您需要设置一些机制来调用您的 backgroundWork 方法,例如 NSTimer。 self.backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:100.0 target:self selector:@selector(backgroundWork) userInfo:nil repeats:YES];[self.backgroundTimer fire]; 在此示例中,您每 100 秒重复一次 backgroundWork。在事件didEnterBackground 上调用它,它将起作用。不过,应用程序将在进入后台几分钟后被操作系统终止(我说的是 4")。这就是为什么应该检查 Background fetch
  • 那么,如果我们计划每 5 分钟更新一次,那么 NSTimer 将永远不会真正触发第二次(假设应用程序在 4 分钟后“终止”)?另外,我在 Apple 的文档中读到您应该 stop all timers when entering the background?
  • 不,它不应该终止,因为您在 plist 中指定您需要后台任务。我读到停止所有计时器:这不是义务。您可能想看看这个:link。另外,我不知道您通过更新收到的数据类型,但也许 Newsstand Kit 框架可以为您解决问题(在该链接中引用)。
  • 刚刚尝试在applicationDidEnterBackground 中设置NSTimer 以每20 秒运行一次。它第一次成功,但随后不再注册。似乎 30 秒的应用暂停开始了!
【解决方案2】:

找到解决办法:

您可以绕过 Apple 的 application:performFetchWithCompletionHandler 功能并设置自己的计时器。为此,请确保执行以下操作:

  1. 已在您的应用设置 >“功能”>“后台模式”下选择 Background fetch

  2. AppDelegate.mapplication:didFinishLaunchingWithOptions内,添加以下代码:

    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        // Nothing
    }];
    
  3. 您现在可以在AppDelegate 中添加NSTimer,它会在后台继续运行。例如,

    _timerBg = [NSTimer scheduledTimerWithTimeInterval:1800
                                                target:self
                                              selector:@selector(bgFunction)
                                              userInfo:nil
                                               repeats:YES];
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    相关资源
    最近更新 更多