TheNoiseClock/TheNoiseClock/Features/Alarms/Intents/AlarmIntents.swift

118 lines
2.9 KiB
Swift

//
// AlarmIntents.swift
// TheNoiseClock
//
// Created by Matt Bruce on 2/2/26.
//
import AlarmKit
import AppIntents
import Foundation
// MARK: - Stop Alarm Intent
/// Intent to stop an active alarm from the Live Activity or notification.
struct StopAlarmIntent: LiveActivityIntent {
static var title: LocalizedStringResource = "Stop Alarm"
static var description = IntentDescription("Stops the currently ringing alarm")
@Parameter(title: "Alarm ID")
var alarmID: String
static var supportedModes: IntentModes { .background }
init() {
self.alarmID = ""
}
init(alarmID: String) {
self.alarmID = alarmID
}
func perform() throws -> some IntentResult {
guard let uuid = UUID(uuidString: alarmID) else {
throw AlarmIntentError.invalidAlarmID
}
try AlarmManager.shared.stop(id: uuid)
return .result()
}
}
// MARK: - Snooze Alarm Intent
/// Intent to snooze an active alarm from the Live Activity or notification.
struct SnoozeAlarmIntent: LiveActivityIntent {
static var title: LocalizedStringResource = "Snooze Alarm"
static var description = IntentDescription("Snoozes the currently ringing alarm")
@Parameter(title: "Alarm ID")
var alarmID: String
static var supportedModes: IntentModes { .background }
init() {
self.alarmID = ""
}
init(alarmID: String) {
self.alarmID = alarmID
}
func perform() throws -> some IntentResult {
guard let uuid = UUID(uuidString: alarmID) else {
throw AlarmIntentError.invalidAlarmID
}
// Use countdown to postpone the alarm by its configured snooze duration
try AlarmManager.shared.countdown(id: uuid)
return .result()
}
}
// MARK: - Open App Intent
/// Intent to open the app when the alarm fires.
struct OpenAlarmAppIntent: LiveActivityIntent {
static var title: LocalizedStringResource = "Open TheNoiseClock"
static var description = IntentDescription("Opens the app to the alarm screen")
@Parameter(title: "Alarm ID")
var alarmID: String
static var supportedModes: IntentModes { .foreground(.immediate) }
init() {
self.alarmID = ""
}
init(alarmID: String) {
self.alarmID = alarmID
}
func perform() throws -> some IntentResult {
// The app will be opened due to .foreground(.immediate)
// The alarm screen will be shown based on the active alarm state
return .result()
}
}
// MARK: - Errors
enum AlarmIntentError: Error, LocalizedError {
case invalidAlarmID
case alarmNotFound
var errorDescription: String? {
switch self {
case .invalidAlarmID:
return "Invalid alarm ID"
case .alarmNotFound:
return "Alarm not found"
}
}
}