How to track a schedule?

I am seeking guidance on the most efficient method for tracking a timer. Is the scheduledTimer function the most suitable option? I am currently enhancing an macOS application that incorporates a schedule feature. The scheduling function allows for scheduling a single date and time, which may be several days in advance. When the timer kicks in, the app picks up the next schedule to track... and so on...

Timer might be part of the solution, but it’s not a complete solution. Scheduling work far into the future is tricky because:

  • The time zone might change.

  • The clock might change.

  • The CPU might go to sleep, which prevents low-level clocks from ticking.

  • The user might quit you app.

  • … and then relaunch it.

  • … or not.

  • The computer might be sleep at the time of the event.

  • Or shut down.

Most of the problems have solutions, but:

  • Coming up with a solution means deciding in a policy. For example, does the event ‘exist’ in local time? Or in a specific time zone?

  • Some solutions involve compromise. For example, there may be substantial leeway between the time that the event happens on the time that your code runs.

If you can provide more background, I should be able to point you in the right direction.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like

Hello,

Thank you for your detailed response. I appreciate your prompt assistance.

I am currently developing and maintaining a SwiftUI/Swift-based GUI on top of rsync. My current plan is to integrate a scheduling function. The application, RsyncUI, supports Deep Links (URL links), which facilitates the initiation of estimates and synchronization actions for any profile added.

The graphical user interface (GUI) component is not yet finalized, but it is ready for the commencement of adding schedules and testing. The development of the actual scheduling component has not yet commenced. The scheduling functionality should only schedule one schedule at a time. Once the current schedule is executed and completed, it should transition to tracking the next scheduled schedule.

You may see the GUI here:

Thanks for the info.

First, you’ll want to split this into two processes:

  • Your GUI app, that the user interacts with

  • Some sort of launchd job, that runs the sync

Without that, the sync will only happen if the app is running, which is less than ideal.

You can set up this launchd job using SMAppService.

Second, you need to decide what sort of launchd job to use, that is, a daemon or an agent. That choice is down to privileges:

  • If you want the sync to happen as the user, use an launchd agent.

  • If you want it to happen as root, use a launchd daemon.

This choice is not as clear cut as you might think, because file system permissions on macOS are complex. See On File System Permissions for general info about this.

Finally, there’s a question of how your launchd job gets execution time. My go-to tool for that is XPC activities. This has both high-level (NSBackgroundActivityScheduler) and low-level (xpc_activity_register and friends) interfaces.


This is very macOS specific. While you’ll be using the Swift language, virtually all the APIs and concepts we’re talking about here are tied to Apple platforms, and specifically macOS. Given that, it’s kinda off topic for Swift Forums, where the focus is on the Swift language and it’s built-in libraries. So, if you have follow-up questions, I encourage you to start a thread on on the Apple Developer Forums. Put it in the App & System Services > Processes & Concurrency topic area so I see it go by.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like

Hi Quinn, and again thanks very much for a very detailed answer. I will investigate your suggestions, and any follow up questions will be as adviced on the Apple Developer Forum...

1 Like