warm_alarm_ios

style: very good analysis License: BSD-3-Clause

The iOS implementation of warm_alarm.

This package is endorsed, which means you do not add it directly to your pubspec.yaml. It is automatically included when you depend on warm_alarm.


Platform capabilities

Feature Support Notes
Notification scheduling ✅ Full UNUserNotificationCenter
Exact alarm scheduling ⚠️ Limited Notification-based; system may throttle background launch
Background audio playback ⚠️ Limited AVAudioSession .playback category; Silent mode bypass
Full-screen presentation ❌ None Full-screen intent is not supported; notification only
Wake-check ❌ None iOS cannot self-trigger background wakes after dismissal

⚠️ Limited means the alarm fires via a UNUserNotificationCenter notification. The app is not guaranteed to launch automatically in the background — audio plays only after the user interacts with the notification (or if the app is already in the foreground).


Native implementation

Scheduling

Alarms are scheduled as UNNotificationRequest objects via UNUserNotificationCenter. The UNCalendarNotificationTrigger fires at the exact scheduledAt time (subject to the operating system's throttling policy for background notification delivery).

Audio

When the notification action is handled, WarmAlarmDelegate starts AVAudioPlayer with the configured audio source (a local file path or a Flutter asset). If neither is provided, no in-app audio is played — the notification itself still plays the bundled alarm_ring.caf (or the system default) sound. The AVAudioSession category is set to .playback (with .mixWithOthers) so the audio continues even when the device is in Silent mode. An optional fade-in is applied by scheduling discrete volume steps as DispatchWorkItems (via DispatchQueue.main.asyncAfter), not a periodic timer.

Recurrence

Weekly recurrence is delivered natively: one UNCalendarNotificationTrigger(repeats: true) is registered per selected weekday, matching DateComponents(weekday, hour, minute), keyed "{id}#{isoWeekday}". The series recurs without any re-arm and survives app termination. ISO weekdays (1 = Mon … 7 = Sun) are mapped to Apple's Calendar weekdays (1 = Sun … 7 = Sat). Dismissing an alarm ends only the current occurrence; cancelAlarm(id) removes every per-weekday request and tears down the series. Note: each recurring alarm consumes up to 7 of iOS's 64 pending-notification slots.

Kill warning

setKillWarning(title, body) stores a warning message. If the app is backgrounded while an alarm is ringing, the plugin posts a non-actionable notification warning the user not to force-quit the app. clearKillWarning() removes the stored message; the pending notification is auto-dismissed when the app returns to the foreground.

Events emitted

iOS emits a subset of the full event hierarchy — only events that are achievable within the notification delivery model:

  • WarmAlarmScheduled
  • WarmAlarmFired
  • WarmAlarmStopped
  • WarmAlarmSnoozed
  • WarmAlarmFailed

Wake-check events (WarmAlarmWakeCheckShown, WarmAlarmWakeCheckDismissed, WarmAlarmWakeCheckExpired, WarmAlarmRetriggered) are not emitted on iOS.


Pigeon wire layer

All Dart ↔ Swift communication is generated by Pigeon. The schema lives in pigeons/messages.dart; generated outputs (Messages.g.swift, lib/src/messages.g.dart) are never hand-edited. Run melos run generate after any schema change.


License

BSD-3-Clause — Copyright (c) 2026, Dongmin Yu. See LICENSE for details.

Libraries

warm_alarm_ios