Swift Task Scheduler for iOS/macOS: EventKit and DispatchSource

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Swift Task Scheduler for iOS and macOS: Complete Guide



In modern iOS and macOS development, a task scheduler is a key component for creating efficient and responsive applications. Swift provides several powerful tools for implementing scheduling: from simple timers to integration with the system calendar via EventKit and low-level DispatchSource mechanisms. In this article, we will thoroughly examine how to create a reliable task scheduler in Swift for both platforms.



Core Components of a Swift Task Scheduler



Before writing code, it's important to understand what tools are available to a Swift developer:



  • Timer — a basic class for executing code at specified intervals or with a delay.
  • DispatchSourceTimer — a more performant timer based on Grand Central Dispatch (GCD).
  • EventKit — a framework for working with the calendar and reminders on iOS/macOS.
  • UNUserNotificationCenter — a local notification system for delayed user alerts.
  • Background Tasks — for executing background tasks on iOS 13+.


Basic Timer Using Timer



The simplest way to create a task scheduler is to use Timer. However, remember that it runs on the main thread unless specified otherwise.



import Foundation

class SimpleTaskScheduler { var timer: Timer? func scheduleTask(interval: TimeInterval, repeats: Bool, task: @escaping () -> Void) { timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: repeats) { _ in task() } } func cancel() { timer?.invalidate() timer = nil }}

// Usage examplelet scheduler = SimpleTaskScheduler()scheduler.scheduleTask(interval: 5.0, repeats: true) { print("Task executed after 5 seconds")}


Advanced Scheduler with DispatchSourceTimer



For more precise and performant scheduling, use DispatchSourceTimer. It runs on background queues and does not block the UI.



import Foundation

class AdvancedTaskScheduler { private var timer: DispatchSourceTimer? private let queue = DispatchQueue(label: "com.pythonlib.scheduler", qos: .background) func scheduleTask(deadline: DispatchTime, interval: DispatchTimeInterval? = nil, leeway: DispatchTimeInterval = .seconds(1), task: @escaping () -> Void) { timer?.cancel() timer = DispatchSource.makeTimerSource(queue: queue) if let interval = interval { timer?.schedule(deadline: deadline, repeating: interval, leeway: leeway) } else { timer?.schedule(deadline: deadline, leeway: leeway) } timer?.setEventHandler { [weak self] in guard self?.timer != nil else { return } task() } timer?.activate() } func cancel() { timer?.cancel() timer = nil }}

// Usagelet advancedScheduler = AdvancedTaskScheduler()advancedScheduler.scheduleTask(deadline: .now() + 2.0, interval: .seconds(10)) { print("Background task runs every 10 seconds")}


Integration with EventKit for Calendar Tasks



EventKit allows you to create tasks that sync with the system calendar. This is ideal for scheduler applications.



import EventKit

class CalendarTaskScheduler { let eventStore = EKEventStore() func requestAccess(completion: @escaping (Bool) -> Void) { eventStore.requestAccess(to: .event) { granted, error in completion(granted) } } func creat

Recommendations