我已经使用NSScreencast episode #92的轮廓设置了背景提取。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ...
  [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
  ...
}

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    if ([[MyAppAPIClient manager] reachable] && [[Session manager] userSignedIn])
    {
        [[[Session manager] user] fetchBackgroundWithSuccess:^(NSURLSessionDataTask *task, NSDictionary *responseObject) {
            completionHandler(UIBackgroundFetchResultNewData);
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            completionHandler(UIBackgroundFetchResultFailed);
        }];
    }
    else
        completionHandler(UIBackgroundFetchResultNoData);
}

对于fetchBackgroundWithSuccess:failure方法,我使用的是AFNetworking NSURLSessionDataTask

不幸的是,有时我会得到错误
MyApp[3344] has active assertions beyond permitted time:
{(
    <BKProcessAssertion: 0x178279c00> identifier: Background Content Fetching (1596) process: MyApp[3344] permittedBackgroundDuration: 30.000000 reason: backgroundContentFetching owner pid:16 preventSuspend      preventThrottleDownUI  preventIdleSleep  preventSuspendOnSleep
)}

它完全崩溃了我的应用程序,注销了我的用户,所有用户的数据都被清除干净。

不知道如何解决此问题,但是任何方向将不胜感激。

更新:

我存储数据的方式是使用NSKeyedArchiver的archiveRootObject:toFileunarchiveObjectWithFile。它会跟踪用户是否已登录,用户名和其他重要信息。所有这些都使用User类的单例对象缓存在内存中。
archiveRootObject:toFile
  • applicationWillResignActive
  • applicationDidEnterBackground
  • applicationWillTerminate
  • applicationDidReceiveMemoryWarning

  • 如果单例为nil,则根据需要调用unarchiveObjectWithFile

    因此注销并清除干净意味着单例为nil,且unarchiveObjectWithFile无法检索任何数据。

    最佳答案

    每个后台抓取都有一个时间限制,我相信是30秒。与正常的后台任务不同,该后台任务可以利用到期处理程序来自动清理并在时间用尽时执行所需的操作,而后台获取当前不具备该功能。解决此问题的一种方法可能是启动一个NSTimer,该NSTimer计划在后台抓取20到25秒后开始运行,并让该计时器调用一个函数来处理您尚未完成的后台任务以停止任何操作正在清理所有内容,以便该应用可以恢复正常的后台运行。从文档:

    调用此方法时,您的应用最多需要30秒的时间
    挂钟时间执行下载操作并致电
    指定的完成处理程序块。实际上,您的应用应该调用
    下载完成后尽快完成处理程序块
    所需的数据。 如果您未及时调用完成处理程序,则您的
    应用已终止。


    https://developer.apple.com/library/ios/documentation/uikit/reference/uiapplicationdelegate_protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:performFetchWithCompletionHandler:

    粗体部分听起来确实就是这种情况。无论哪种方式,您都需要在30秒内完成您要完成的工作,否则您需要取消它,否则您的应用将被终止。

    10-08 05:53
    查看更多