WatchBackgroundDemoApp.swift ``` import SwiftUI import WatchKit import os import UserNotifications extension Logger { private static var subsystem = Bundle.main.bundleIdentifier ?? "WatchBackgroundDemo" static let background = Logger(subsystem: subsystem, category: "BackgroundRefresh") } // MARK: - WKApplicationDelegate implementation class ApplicationDelegate: NSObject, WKApplicationDelegate, UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions { return [.banner, .list, .sound, .badge] } func applicationDidFinishLaunching() { Logger.background.info("[ApplicationDelegate] finish launching") NotificationManager.shared.requestPermission() UNUserNotificationCenter.current().delegate = self BackgroundRefreshManager.shared.scheduleBackgroundRefresh(BackgroundRefreshManager.backgroundRefreshDelay) } func applicationDidBecomeActive() { Logger.background.info("[ApplicationDelegate] become active") } func applicationWillResignActive() { Logger.background.info("[ApplicationDelegate] resign active") } func applicationWillEnterForeground() { Logger.background.info("[ApplicationDelegate] enter foreground") } func applicationDidEnterBackground() { Logger.background.info("[ApplicationDelegate] enter background, applicationState: \(WKApplication.shared().applicationState.rawValue)") } func handle(_ backgroundTasks: Set) { let size = backgroundTasks.count Logger.background.info("[ApplicationDelegate] task size: \(size)") for task in backgroundTasks { Logger.background.info("[ApplicationDelegate] task type: \(type(of: task)), identifier: \(String(describing: task.userInfo))") switch task { case let refreshTask as WKApplicationRefreshBackgroundTask: Logger.background.info("[ApplicationDelegate] app refreshTask") BackgroundRefreshManager.shared.handleBackgroundRefresh() refreshTask.setTaskCompletedWithSnapshot(false) case let snapshotTask as WKSnapshotRefreshBackgroundTask: Logger.background.info("[ApplicationDelegate] snapshotTask, reason: \(snapshotTask.reasonForSnapshot.rawValue)") snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil) default: task.setTaskCompletedWithSnapshot(false) } } } } @main struct WatchBackgroundDemo_Watch_AppApp: App { @WKApplicationDelegateAdaptor(ApplicationDelegate.self) var delegate var body: some Scene { WindowGroup { ContentView() } } } ``` BackgroundRefreshManager.swift ``` import WatchKit import os class BackgroundRefreshManager { /// task delay time public static let backgroundRefreshDelay: TimeInterval = 60 * 15 static let shared = BackgroundRefreshManager() private init() {} func scheduleBackgroundRefresh(_ interval: TimeInterval) { let date = Date(timeIntervalSinceNow: interval) WKApplication.shared().scheduleBackgroundRefresh( withPreferredDate: date, userInfo: "CHECK_CONNECTION" as NSSecureCoding & NSObjectProtocol ) { error in if let error = error { Logger.background.error("[BackgroundRefresh] schedule failed: \(error.localizedDescription)") } else { Logger.background.info("[BackgroundRefresh] schedule success, will execute at: \(date)") } } } func handleBackgroundRefresh() async { NotificationManager.shared.sendNotification() // reschedule scheduleBackgroundRefresh(Self.backgroundRefreshDelay) } } ``` NotificationManager.swift ``` import UserNotifications import os class NotificationManager { static let shared = NotificationManager() private init() {} func requestPermission() { UNUserNotificationCenter.current().requestAuthorization( options: [.alert, .sound, .badge] ) { granted, error in if granted { Logger.background.info("notification permission granted") } else { Logger.background.info("notification permission denied") } } } func sendNotification() { Logger.background.info("sendNotification") let content = UNMutableNotificationContent() content.title = "BackgroundRefresh" content.body = "watchOS backgroud task" content.sound = .default let request = UNNotificationRequest( identifier: UUID().uuidString, content: content, trigger: nil ) UNUserNotificationCenter.current().add(request) { error in if let error = error { Logger.background.error("notification send error: \(error.localizedDescription)") } else { Logger.background.info("notification sent successfully") } } } } ```