使用Grand Central Dispatch每天同一时间安排一项功能

时间:2015-02-22 05:29:48

标签: ios swift grand-central-dispatch

我已经阅读了这个答案,我不相信它有我想要的东西,但我是初学者,我很高兴有人在这个链接中指出答案:dispatch_after - GCD in swift?

我的目标:设置一个功能,每天在用户的时区(或系统的时区)上午9点运行。

我已经非常简短地使用GCD来延迟一个函数,如下所示(它工作得很好):

    var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(10 * Double(NSEC_PER_SEC)))
    dispatch_after(dispatchTime, dispatch_get_main_queue(), {
        let alert = UIAlertView()
        alert.title = "Foo Alert"
        alert.message = "foo."
        alert.addButtonWithTitle("OK")
        alert.show()

        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
    });

所以我想像我上面提到的那样每天开火,但是我坚持的第一件事是将DISPATCH_TIME_NOW换成时区相关值?我是否甚至需要考虑时区或者只是用军队09:00替换DISPATCH_TIME_NOW就足够了?

此外,任何有关总体目标的建议,每天同一时间安排点火功能都会非常感激。

我还没有为使用GCD达成这个目标而结婚,但这是我遇到最多搜索的那个。

2 个答案:

答案 0 :(得分:5)

简而言之,除非应用程序仍在运行,否则通常无法在任意时间执行某些任意功能。 dispatch_after假定应用程序仍在预定时间运行,这通常不会得到保证。 dispatch_after非常适合“在x秒内做某事”,而不是“明天上午9点做某事”。

是的,dispatch_after可以在某些后台线程上执行某些任务,但这与在后台运行应用程序(即应用程序本身不再处于前台)时的概念截然不同。请参阅App Programming Guide for iOS: Background Execution,其中列举了所有各种背景机制。

当应用程序当前未处于活动状态时执行某些操作的关键技术包括:

  • 使用后台获取,您可以机会性地检查服务器上的新数据(但不是根据您的日程安排,而是由操作系统决定)。

  • 如果您的应用正在投放几个非常具体的任务(例如音乐应用,VOIP,导航应用等),您可以注册后台操作。

  • 您可以安排在特定时间触发本地通知(尽管用户有责任查看通知并点击该通知以便应用程序运行)。有关详细信息,请参阅Local and Remote Notification Programming Guide

  • 您可以注册推送通知,然后您的服务器可以在您选择的某个时间向客户端发送通知(但这需要服务器端开发)。

还可以配置其他后台任务(例如,在后台继续网络请求,请求几分钟完成一些有限长度的任务,即使应用程序不再处于活动状态等),但这些似乎与您的问题无关。

如果您可以在预定时间阐明您希望应用程序执行的操作,我们可能会建议可能的内容以及替代方案。但是,在广泛的笔触中,这些是您拥有的基本选项。

答案 1 :(得分:0)

重要的是,您应该使用dispatch_walltime而不是dispatch_time。差异:如果您将dispatch_time设置为“从现在起1000秒”,它将从现在开始运行1000秒(如果您的应用正在运行)。但是dispatch_walltime将计算用户时钟上的时间,并在用户的时钟到达该时间时运行。

因此,如果您在明天上午9点设置dispatch_time,并且我将设备上的时钟设置为5分钟,那么当我的时钟显示在上午9:05时,dispatch_time将会运行。 dispatch_walltime将在上午9:00运行。 (如果我从上午8:55到上午9:05更改时钟,你将不得不试验会发生什么,因为当时钟显示上午9:00时显然是不可能的)。