iOS每天运行一次
这个应用程序背后的想法是非常简单的:下载一个文件。 然而,这个应用程序将为那些不总是在互联网访问范围内的人,所以我需要它知道,在上午9:00,下载文件到硬盘驱动器。 应用程序中会有一个button来手动执行,但是我已经有了这个工作。
据我所知,如果可能的话,这将是困难的。 我知道iOS不喜欢多任务处理,但我也意识到它确实允许后台计时器function。 我愿意接受任何人可能需要完成的build议,即使这意味着要编写一个单独的应用程序。 谢谢。
编辑:我看到有可能与通知,甚至可能是日历。 这一类的想法也受到欢迎。
编辑2:我也读了一些关于启动应用程序的外部服务器,但没有给出任何描述。
以下是关于后台执行和通知以及定时器等与应用程序有关的情况,这些应用程序会定期发生某些活动。
-
一个应用程序不能在后台执行,除非:
-
它要求操作系统有额外的时间来这样做。 这是使用
beginBackgroundTaskWithExpirationHandler
完成的。 苹果没有特意指定这个额外的时间,但实际上大概是10分钟。 -
一个应用程序有一个背景模式,模式是:VoIP,audio,位置,报价。 即使它有这些types之一,应用程序不能执行没有一些限制。 本讨论的其余部分假设应用程序没有背景模式。
-
-
当一个应用程序被暂停,它不能做任何直接唤醒自己。 它以前不能预定一个NSTimer,它不能使用像performSelector:afterDelay。 等等
该应用程序可以再次激活的唯一方式是,如果用户做了一些事情,使其活跃。 用户可以通过以下途径完成此操作:
-
直接从其图标启动应用程序
-
启动应用程序,以响应应用程序以前预定的本地通知。
-
启动应用程序以响应服务器发送的远程通知。
-
其他一些:如URL启动,如果应用程序注册,以处理通过url启动; 或者其注册能够处理某种types的内容。
-
如果应用程序在本地/远程通知触发时位于前台,则应用程序将直接收到该应用程序。
如果当本地/远程通知触发时,应用程序当前不在前台,则应用程序不会收到它。 通知触发时没有执行的代码!
只有当用户select通知时,应用程序才会被激活并执行。
请注意,用户可以禁用整个设备的通知,或仅针对特定的应用程序,在这种情况下用户将永远不会看到它们。 如果设备在发生通知时被closures,则会丢失。
我很确定这是不可能的,至多你可以做的是发送推送通知给用户,以便他们手动更新时,需要。
你可以使用本地通知。 他们在用户打开呈现的通知时执行代码。 您可以设置本地通知以指定的时间间隔(例如每天,每小时,每周等)重复发生。 这仍然需要用户打开应用程序来启动进程。
UILocalNotification类参考
一旦委托方法触发,您只需几秒钟即可执行代码。 注册一个长时间运行的后台任务,并下载你需要做的任何事情。 如果在10分钟内无法完成下载任务,则需要重新考虑下载策略。
苹果多任务和背景
我们正在iOS应用程序上使用这个相同的概念,所以如果你把它设置正确的话,这将起作用。
UPDATE
对于那些好奇的人来说,你只需要实现UILocalNotification委托方法。 他们从应该已经到位的UIApplicationDelegateinheritance。
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { // start your long running bg task here and update your file }
**更新2 **
马丁H的回答是迄今为止最正确的答案。 但是这引出了一个问题,如果用户从不打开应用程序,那么下载数据的目的是什么? 提醒他们打开应用程序和更新的周期性本地通知可能是最好的方法,但仍然需要用户与您的应用程序进行交互,如果他们希望它保持最新和最新状态。
背景应用程序有一个设定的时间限制(我相信10分钟,但不要引用我,这可能会less一些)来完成他们正在工作的任何东西。 你将无法使用后台任务来做你想做的事情。
你可以做的是设置NSUserDefault与上次下载的date。 启动时检查保存的date,如果date不是当前date,并且在上午9点以后,请以编程方式启动下载。
你有没有尝试过以下?
if ([[[UIDevice currentDevice] systemVersion] floatValue] >=7.0) [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:600]; - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { completionHandler(UIBackgroundFetchResultNewData); }