1

I have read this answer and I do not believe it has what I am looking for but I a am beginner and I am happy to have someone point out the answer in this link : dispatch_after - GCD in swift?

My goal: set a function to run at 9 AM in the user's time zone (or system's time zone) every single day.

I've used GCD very briefly to delay a function as follows (it works perfectly fine):

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

So I wanted to fire it daily as I've mentioned above but the first thing I am stuck on is swapping out DISPATCH_TIME_NOW for a time zone relevant value? Do I even need to consider time zones or will simply replacing DISPATCH_TIME_NOW with military 09:00 be sufficient?

Also, any advice on the overall goal, scheduling to fire function same time every day would be much appreciated.

I'm also not married to using GCD for this goal but it was the one I ran into the most doing searches.

Community
  • 1
  • 1
lostinthebits
  • 661
  • 2
  • 10
  • 23

2 Answers2

5

In short, you cannot generally execute some arbitrary function at some arbitrary time unless the app is still running. The dispatch_after presumes that the app is still running at the scheduled time, which is not generally assured. The dispatch_after is great for "do something in x seconds", not "do something tomorrow at 9am".

Yes, dispatch_after can perform some task on some background thread, but that's very different concept from having the app run in the background (i.e., when the app, itself, is no longer in foreground). Please refer to App Programming Guide for iOS: Background Execution, which enumerates all of the various background mechanisms.

The key technologies for performing something when the app is not currently active include:

  • Using background fetch, you can opportunistically check for new data on the server (but not per your schedule, but rather at the discretion of the OS).

  • If your app is serving several very specific tasks (e.g. music app, VOIP, navigation app, etc.) you can register for background operation.

  • You can schedule a local notification to fire at particular time (though it is incumbent on the user to see the notification and tap on it in order for the app to run). For more information see the Local and Remote Notification Programming Guide.

  • You can register for push notifications and then your server could push a notification to clients at some time of your choosing (but that requires server-side development).

There are other background tasks that can be configured (e.g. continue network requests in background, request a few minutes to finish some finite length task even if the app is no longer active, etc.), but those seem unrelated to your question.

If you could clarify what you want the app to do at the scheduled time, we might be able to advise what is possible and what the alternatives are. But, in broad brush strokes, those are the basic options you have.

Rob
  • 371,891
  • 67
  • 713
  • 902
0

Importantly, you should use dispatch_walltime instead of dispatch_time. The difference: If you set a dispatch_time for "1000 seconds from now" it will run 1000 seconds from now (if your app is running). But dispatch_walltime will calculate which time that is on the user's clock, and will run when the user's clock reaches that time.

So if you set up dispatch_time for 9am tomorrow morning, and I set the clock on my device forwards by five minutes, then dispatch_time will run when my clock displays 9:05am. dispatch_walltime will run at 9:00am. (You'll have to experiment what happens if I change the clock from 8:55am to 9:05am because then running when the clock shows 9:00am is obviously impossible).

gnasher729
  • 47,695
  • 5
  • 65
  • 91