iOS后台获取时间限制崩溃 [英] iOS background fetch time limit crash

查看:129
本文介绍了iOS后台获取时间限制崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 NSScreencast第92集中的大纲设置了背景提取。

I've set up background fetch, using outline from 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:失败方法,我正在使用AFNetworking NSURLSessionDataTask

For the fetchBackgroundWithSuccess:failure method, I'm using AFNetworking NSURLSessionDataTask.

不幸的是,有时我会收到错误

Unfortunately, sometimes I get the error

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 
)}

它完全崩溃我的应用程序,退出我的用户,所有用户的数据都被擦干净了。

and it completely crashes my app, logs out my user, and all of the user's data is wiped clean.

不确定如何要解决这个问题,但任何方向都会非常感激。

Not sure how to fix this, but any direction would be much appreciated.

更新:

我存储数据的方式是使用NSKeyedArchiver的 archiveRootObject:toFile unarchiveObjectWithFile 。它会跟踪用户是否已登录,其user_id和其他重要信息。这是使用类用户的单例对象在内存中缓存的。

The way I store data is using NSKeyedArchiver's archiveRootObject:toFile and unarchiveObjectWithFile. It keeps track if the user is logged in, their user_id, and other important info. This is all cached in memory using a singleton object of class User.

archiveRootObject:在

archiveRootObject:toFile is called during


  1. applicationWillResignActive >
  2. applicationDidEnterBackground

  3. applicationWillTerminate

  4. applicationDidReceiveMemoryWarning

  1. applicationWillResignActive
  2. applicationDidEnterBackground
  3. applicationWillTerminate
  4. applicationDidReceiveMemoryWarning

unarchiveObjectWithFile

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

So logged out and wiped clean means the singleton is nil and unarchiveObjectWithFile fails to retrieve any data.

推荐答案

每个后台提取都有一个时间限制,我相信30秒。与正常的后台任务不同,后者可以利用到期处理程序自动清理并执行您在时间不足时需要执行的操作,而后台提取当前没有这种能力。你可以处理这个问题的一种方法是启动一个NSTimer,计划在你的后台获取中运行20-25秒,然后让那个计时器调用一个函数来处理你是否还没有完成你的后台任务来阻止你我正在做并清理所有内容,以便应用程序可以恢复正常的后台运行。来自文档:

Every background fetch has a time limit, which is I believe 30 seconds. Unlike a normal background task that can utilize an expiration handler to automatically clean up and do what you need to do when you run out of time, background fetches currently don't have that ability. One way you can handle this is perhaps start an NSTimer that is scheduled to go off something like 20-25 seconds into your background fetch, and have that timer call a function that handles if you haven't completed your background task to stop whatever you're doing and clean up everything so the app can go back to being backgrounded normally. From the docs:


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

When this method is called, your app has up to 30 seconds of wall-clock time to perform the download operation and call the specified completion handler block. In practice, your app should call the completion handler block as soon as possible after downloading the needed data. If you do not call the completion handler in time, your app is terminated.

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

粗体部分听起来就像是正在发生的事情。无论哪种方式,你需要在30秒内完成你想要完成的任务,否则你需要取消它或你的应用程序将被终止。

The bold part sounds like that's exactly what's happening. Either way, you need to get done what you're trying to get done within the 30 seconds, otherwise you need to cancel it or your app will be terminated.

这篇关于iOS后台获取时间限制崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆