From f3c98cedb95e32d3b912e0188ed54a8ea910a9fd Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 2 Feb 2026 13:20:19 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- .../Alarms/Services/AlarmKitService.swift | 90 +++++++------------ .../Features/Clock/Models/ClockStyle.swift | 4 +- 2 files changed, 34 insertions(+), 60 deletions(-) diff --git a/TheNoiseClock/Features/Alarms/Services/AlarmKitService.swift b/TheNoiseClock/Features/Alarms/Services/AlarmKitService.swift index fe9c840..5857761 100644 --- a/TheNoiseClock/Features/Alarms/Services/AlarmKitService.swift +++ b/TheNoiseClock/Features/Alarms/Services/AlarmKitService.swift @@ -5,6 +5,7 @@ // Created by Matt Bruce on 2/2/26. // +import ActivityKit import AlarmKit import Bedrock import Foundation @@ -81,30 +82,20 @@ final class AlarmKitService { } } - // Create the sound for the alarm - let alarmSound = createAlarmSound(for: alarm) - Design.debugLog("[alarmkit] Created alarm sound: \(alarmSound)") - - // Create the alert presentation with stop button and sound + // Create the stop button for the alarm let stopButton = AlarmButton( text: "Stop", textColor: .red, systemImageName: "stop.fill" ) + Design.debugLog("[alarmkit] Created stop button") - let snoozeButton = AlarmButton( - text: "Snooze", - textColor: .blue, - systemImageName: "zzz" - ) - + // Create the alert presentation (sound is in AlarmConfiguration, not here) let alert = AlarmPresentation.Alert( title: LocalizedStringResource(stringLiteral: alarm.label), - sound: alarmSound, - stopButton: stopButton, - snoozeButton: snoozeButton + stopButton: stopButton ) - Design.debugLog("[alarmkit] Created alert with sound and buttons") + Design.debugLog("[alarmkit] Created alert presentation") // Create metadata for the alarm let metadata = NoiseClockAlarmMetadata( @@ -114,7 +105,7 @@ final class AlarmKitService { label: alarm.label, volume: alarm.volume ) - Design.debugLog("[alarmkit] Created metadata: \(metadata)") + Design.debugLog("[alarmkit] Created metadata: alarmId=\(metadata.alarmId), sound=\(metadata.soundName)") // Create alarm attributes let attributes = AlarmAttributes( @@ -124,9 +115,9 @@ final class AlarmKitService { ) Design.debugLog("[alarmkit] Created attributes with tint color") - // Create the schedule + // Create the schedule - use fixed date for one-time alarms let schedule = createSchedule(for: alarm) - Design.debugLog("[alarmkit] Created schedule: \(schedule)") + Design.debugLog("[alarmkit] Created schedule") // Create countdown duration (5 min before alarm, 1 min after) let countdownDuration = AlarmKit.Alarm.CountdownDuration( @@ -135,13 +126,19 @@ final class AlarmKitService { ) Design.debugLog("[alarmkit] Countdown duration: preAlert=300s, postAlert=60s") - // Create the alarm configuration + // Create the sound + let soundName = getSoundNameForAlarmKit(alarm.soundName) + let alarmSound = AlertConfiguration.AlertSound.named(soundName) + Design.debugLog("[alarmkit] Created sound: \(soundName)") + + // Create the alarm configuration with sound let configuration = AlarmManager.AlarmConfiguration( countdownDuration: countdownDuration, schedule: schedule, - attributes: attributes + attributes: attributes, + sound: alarmSound ) - Design.debugLog("[alarmkit] Created configuration") + Design.debugLog("[alarmkit] Created configuration with sound") // Schedule the alarm do { @@ -160,22 +157,12 @@ final class AlarmKitService { // MARK: - Sound Configuration - /// Create an AlarmKit sound from the alarm's sound name. - private func createAlarmSound(for alarm: Alarm) -> AlarmKit.AlertSound { - let soundName = alarm.soundName - Design.debugLog("[alarmkit] Creating sound for: \(soundName)") - - // Check if it's a bundled sound file (has extension) - if soundName.contains(".") { - // Extract filename without extension for named sound - let soundFileName = soundName - Design.debugLog("[alarmkit] Using named sound file: \(soundFileName)") - return .named(soundFileName) - } else { - // Assume it's a named sound resource - Design.debugLog("[alarmkit] Using named sound: \(soundName)") - return .named(soundName) - } + /// Get the sound name for AlarmKit (without extension) + private func getSoundNameForAlarmKit(_ soundName: String) -> String { + // AlarmKit expects the sound name without extension + let nameWithoutExtension = (soundName as NSString).deletingPathExtension + Design.debugLog("[alarmkit] Sound name for AlarmKit: \(nameWithoutExtension) (from: \(soundName))") + return nameWithoutExtension } /// Cancel a scheduled alarm. @@ -240,30 +227,17 @@ final class AlarmKitService { /// Create an AlarmKit schedule from an Alarm model. private func createSchedule(for alarm: Alarm) -> AlarmKit.Alarm.Schedule { - // Extract time components - let calendar = Calendar.current - let components = calendar.dateComponents([.hour, .minute], from: alarm.time) + // Calculate the next trigger time + let triggerDate = alarm.nextTriggerTime() - let hour = components.hour ?? 0 - let minute = components.minute ?? 0 + Design.debugLog("[alarmkit] Creating schedule for: \(triggerDate)") + Design.debugLog("[alarmkit] Current time: \(Date.now)") + Design.debugLog("[alarmkit] Time until alarm: \(triggerDate.timeIntervalSinceNow) seconds") - Design.debugLog("[alarmkit] Creating schedule for \(hour):\(String(format: "%02d", minute))") + // Use fixed schedule for one-time alarms + let schedule = AlarmKit.Alarm.Schedule.fixed(triggerDate) - let time = AlarmKit.Alarm.Schedule.Relative.Time( - hour: hour, - minute: minute - ) - - // For now, create a one-time alarm (non-repeating) - // Future: Support weekly repeating alarms based on alarm.repeatDays - let schedule = AlarmKit.Alarm.Schedule.relative( - AlarmKit.Alarm.Schedule.Relative( - time: time, - repeats: .never - ) - ) - - Design.debugLog("[alarmkit] Schedule created: relative, repeats=never") + Design.debugLog("[alarmkit] Schedule created: fixed at \(triggerDate)") return schedule } } diff --git a/TheNoiseClock/Features/Clock/Models/ClockStyle.swift b/TheNoiseClock/Features/Clock/Models/ClockStyle.swift index 92275cc..1bbe6a1 100644 --- a/TheNoiseClock/Features/Clock/Models/ClockStyle.swift +++ b/TheNoiseClock/Features/Clock/Models/ClockStyle.swift @@ -14,9 +14,9 @@ import Bedrock class ClockStyle: Codable, Equatable { // MARK: - Time Format Settings - var use24Hour: Bool = true + var use24Hour: Bool = false var showSeconds: Bool = false - var showAmPm: Bool = true + var showAmPm: Bool = false var forceHorizontalMode: Bool = false // Force horizontal layout even in portrait // MARK: - Visual Settings