如何在特定时间点进行后台提取,比如在午夜

时间:2014-01-21 09:50:00

标签: ios objective-c ios7 background fetch

我有一个应用程序可以同步地址簿中的联系人,我只需要检查新的联系人,并在每个午夜自动将此联系人同步到我的应用程序数据库中。

我已经通过了iOS7新功能"Background Fetch",但这与我的要求不符,在这种情况下,操作系统会根据用户的活动触发后台提取。

然而,我的数据在上午12点之前就已过时,如果此活动未在此特定时间实例启动,我的应用将变得无用。

有没有办法实现我的需要,以便我可以使用后台进程每隔午夜将数据库与地址簿同步。

由于

4 个答案:

答案 0 :(得分:3)

您无法配置进行后台提取的时间。相反,您可能想要查看iOS 7的新远程通知功能。

远程通知本质上是推送通知,但它们包含content-available属性。当其中一个通知到达时,系统将唤醒您的应用并调用应用委托方法:

         - (void)application:(UIApplication *)application 
didReceiveRemoteNotification:(NSDictionary *)userInfo 
      fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

在此方法中,您可以执行后台提取以检索新数据。

您必须将服务器设置为在刷新数据后向您的应用发送远程通知,以提示他们自行更新。

有关远程通知的详情,请参阅this issue of objc.io'Using Push Notifications to Initiate a Download'

答案 1 :(得分:1)

您可以订阅ABAddressBookRegisterExternalChangeCallback以在修改通讯簿数据库时接收通知。我认为它比成熟的同步更好,但是只有当应用程序在前台时它才会起作用。 但是,当应用程序被暂停时,它无法直接唤醒任何东西。它之前无法安排NSTimer,它无法使用performSelector:afterDelay之类的内容,依此类推。应用程序再次变为活动状态的唯一方式是,如果用户执行某些操作以使其处于活动状态,例如收到本地或远程通知并且启动了警报。只有当应用程序具有后台模式时,才允许在后台模式下长时间执行应用程序,这些模式为:voipaudiolocationnewstand。即使它具有这些类型中的一种,应用程序也不能在没有某些限制的情况下执行其代码。

所以唯一的方法是iOS 7功能:background task execution if content avaliable正如James Frost所建议的那样,但为此您需要外部服务器将推送通知发送到您的应用程序。

你说:"...is not started at this particular time instance my app will be rendered useless."但谁会检查这个,直到应用程序再次启动?如果时间值之间的差值大于某个值,为什么不能在每个应用程序运行期间使用地址簿进行所有关键更新。我的意思是你可以(当应用程序返回到applicationDidFinishLaunching中的前台时)计算[NSDate now]和您在NSUserDefaultsplist之后存储的上一个同步日期值之间的差值同步完成。如果增量更大,例如超过24小时再调用同步mehtod。

答案 2 :(得分:1)

您真的需要在午夜准确更新数据吗?或者它必须在午夜之后更新?

您仍然可以使用后台获取功能。只需让操作系统唤醒您进行检查,如果已经过了午夜,请执行更新。即使操作系统在下次启动应用程序之前不会执行此操作,您也可以在下次启动时执行此操作。如果用户在这段时间内没有启动应用程序,是否真的有必要在某个特定时间更新数据?

答案 3 :(得分:0)

詹姆斯的回答是最正确的。如果您将后端设置为在午夜向所有设备发送推送通知,则可以在此时完成触发后台提取。这样,用户很可能看不到加载对话框。只是不要100%确定用户已经收到推送并正确获取,因为在此过程中可能出现问题。

您可以设置脚本来执行推送,然后让cron作业调用该脚本。我过去曾使用https://www.setcronjob.com来做这样的事情而且效果非常好。

设置服务来处理推送通知管理也许是一个好主意。如果你选择去那条路线,我推荐Parse(http://www.parse.com)。

另一个更简单的选项可能是将应用程序的后台获取间隔设置为最小值。

[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];

在大多数情况下,这应该足以满足您的目的。