I am trying to create a reminder app using the alarm plugin (version 4.1.1) /packages/alarm. The alarm is working fine, but I'm facing an issue where notifications are not appearing on the iOS simulator when the alarm triggers. The alarm rings as expected, but the notification doesn't show. Here is my full code—please check and help me resolve this issue.
import 'package:alarm/alarm.dart';
import 'package:alarm/model/alarm_settings.dart';
import 'package:alarm/model/notification_settings.dart';
import 'package:alarm/model/volume_settings.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:permission_handler/permission_handler.dart';
class AlarmHomeScreen extends StatefulWidget {
@override
_AlarmHomeScreenState createState() => _AlarmHomeScreenState();
}
class _AlarmHomeScreenState extends State<AlarmHomeScreen> {
List<AlarmData> alarms = [];
@override
void initState() {
// TODO: implement initState
super.initState();
requestNotificationPermission();
}
// Request notification permission
Future<void> requestNotificationPermission() async {
final status = await Permission.notification.request();
if (status.isGranted) {
// Permission granted
print("Notification Permission Granted!");
} else {
// Permission denied
print("Notification Permission Denied!");
}
}
void _addAlarm(DateTime dateTime, String label) async {
int id = alarms.length + 1;
final alarmSettings = AlarmSettings(
id: id,
dateTime: dateTime,
assetAudioPath: 'assets/marimba.mp3',
loopAudio: true,
vibrate: true,
volumeSettings: VolumeSettings.fixed(
volume: 0.8,
volumeEnforced: true,
),
androidFullScreenIntent: true,
notificationSettings: const NotificationSettings(
title: 'Alarm',
body: 'Time to wake up!',
stopButton: 'Stop',
icon: 'notification_icon',
),
);
await Alarm.set(alarmSettings: alarmSettings);
setState(() {
alarms.add(AlarmData(
id: id,
dateTime: dateTime,
label: label,
isEnabled: true,
));
});
}
void _removeAlarm(int index) async {
await Alarm.stop(alarms[index].id); // Stop the alarm using its ID
setState(() {
alarms.removeAt(index);
});
}
void _toggleAlarm(int index, bool value) async {
setState(() {
alarms[index].isEnabled = value;
});
if (value) {
// Re-enable the alarm
final alarmSettings = AlarmSettings(
id: alarms[index].id,
dateTime: alarms[index].dateTime,
assetAudioPath: 'assets/marimba.mp3',
loopAudio: true,
vibrate: true,
volumeSettings: VolumeSettings.fixed(
volume: 0.8,
volumeEnforced: true,
),
warningNotificationOnKill: Platform.isIOS,
androidFullScreenIntent: true,
notificationSettings: const NotificationSettings(
title: 'Alarm',
body: 'Time to wake up!',
stopButton: 'Stop',
icon: 'notification_icon',
),
);
await Alarm.set(alarmSettings: alarmSettings);
} else {
// Disable the alarm
await Alarm.stop(alarms[index].id);
}
}
void _showAddAlarmDialog() async {
DateTime selectedTime = DateTime.now();
DateTime selectedDate = DateTime.now();
String label = 'Alarm';
// Step 1: Show Time Picker
await showCupertinoModalPopup(
context: context,
builder: (context) => Container(
height: 350, // Increased height
color: CupertinoColors.systemBackground.resolveFrom(context),
child: Column(
children: [
SizedBox(
height: 250, // Increased height
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.time,
use24hFormat: false,
onDateTimeChanged: (DateTime newDateTime) {
selectedTime = newDateTime;
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CupertinoButton(
child: Text(
"Cancel",
style: TextStyle(fontSize: 18, color: CupertinoColors.destructiveRed),
),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
"Next",
style: TextStyle(fontSize: 18, color: CupertinoColors.activeBlue),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
],
),
),
);
// Step 2: Show Date Picker
await showCupertinoModalPopup(
context: context,
builder: (context) => Container(
height: 350, // Increased height
color: CupertinoColors.systemBackground.resolveFrom(context),
child: Column(
children: [
SizedBox(
height: 250, // Increased height
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: selectedDate,
onDateTimeChanged: (DateTime newDateTime) {
selectedDate = newDateTime;
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CupertinoButton(
child: Text(
"Cancel",
style: TextStyle(fontSize: 18, color: CupertinoColors.destructiveRed),
),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
"Next",
style: TextStyle(fontSize: 18, color: CupertinoColors.activeBlue),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
],
),
),
);
// Step 3: Show Label Input Dialog
await showCupertinoModalPopup(
context: context,
builder: (context) => Container(
height: 250, // Increased height
padding: EdgeInsets.all(20),
color: CupertinoColors.systemBackground.resolveFrom(context),
child: Column(
children: [
CupertinoTextField(
placeholder: 'Enter Alarm Label',
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey5,
borderRadius: BorderRadius.circular(12),
),
onChanged: (value) {
label = value;
},
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CupertinoButton(
child: Text(
"Cancel",
style: TextStyle(fontSize: 18, color: CupertinoColors.destructiveRed),
),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
"Set Alarm",
style: TextStyle(fontSize: 18, color: CupertinoColors.activeBlue),
),
onPressed: () {
final combinedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
_addAlarm(combinedDateTime, label);
Navigator.pop(context);
},
),
],
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(top: 20, left: 15, right: 15, bottom: 80),
child: alarms.isEmpty
? Center(
child: Text(
"No Alarms Set",
style: TextStyle(fontSize: 20, color: CupertinoColors.systemGrey),
),
)
: ListView.builder(
itemCount: alarms.length,
itemBuilder: (context, index) {
final alarm = alarms[index];
return Container(
padding: EdgeInsets.all(16),
margin: EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [CupertinoColors.systemGrey5, CupertinoColors.systemGrey6],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: CupertinoColors.systemGrey.withOpacity(0.2),
blurRadius: 8,
spreadRadius: 2,
offset: Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
alarm.label,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
),
SizedBox(height: 8),
Text(
'${alarm.dateTime.hour}:${alarm.dateTime.minute.toString().padLeft(2, '0')} - ${alarm.dateTime.day}/${alarm.dateTime.month}/${alarm.dateTime.year}',
style: TextStyle(fontSize: 16, color: CupertinoColors.systemGrey),
),
SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
CupertinoSwitch(
value: alarm.isEnabled,
onChanged: (value) => _toggleAlarm(index, value),
),
SizedBox(width: 10),
CupertinoButton(
padding: EdgeInsets.zero,
child: Icon(
CupertinoIcons.delete,
color: CupertinoColors.destructiveRed,
),
onPressed: () => _removeAlarm(index),
),
],
),
],
),
);
},
),
),
// Floating Action Button
Positioned(
bottom: 30,
right: 30,
child: GestureDetector(
onTap: _showAddAlarmDialog,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [CupertinoColors.systemBlue, CupertinoColors.systemTeal],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: CupertinoColors.systemGrey.withOpacity(0.4),
blurRadius: 8,
spreadRadius: 2,
offset: Offset(0, 4),
),
],
),
child: Icon(
CupertinoIcons.add,
size: 30,
color: CupertinoColors.white,
),
),
),
),
],
),
);
}
}
class AlarmData {
final int id;
final DateTime dateTime;
final String label;
bool isEnabled;
AlarmData({
required this.id,
required this.dateTime,
required this.label,
this.isEnabled = true,
});
}
import 'package:alarm/alarm.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'alarm/AlarmHomeScreen.dart';
import 'alarm/alarm.dart';
import 'alarm/reminder.dart';
import 'calender/CalendarScreen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Alarm.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
debugShowCheckedModeBanner: false,
// Adding the localization delegates here
localizationsDelegates: const [
DefaultMaterialLocalizations.delegate, // Ensures Material Localizations are available
DefaultCupertinoLocalizations.delegate, // Ensures Cupertino Localizations are available
DefaultWidgetsLocalizations.delegate,
],
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _selectedIndex = 0;
final List<Widget> _pages = [
CalendarScreen(),
AlarmHomeScreen(),
//AlarmScreen(), // Ensure that AlarmScreen is styled with Cupertino widgets
StopwatchScreen(),
NotesScreen(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const [
BottomNavigationBarItem(icon: Icon(CupertinoIcons.calendar), label: 'Calendar'),
BottomNavigationBarItem(icon: Icon(CupertinoIcons.alarm), label: 'Alarm'),
BottomNavigationBarItem(icon: Icon(CupertinoIcons.timer), label: 'Stopwatch'),
BottomNavigationBarItem(icon: Icon(CupertinoIcons.book), label: 'Notes'),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
tabBuilder: (context, index) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(_getTitle(index)),
),
child: SafeArea(child: _pages[index]),
);
},
);
}
String _getTitle(int index) {
switch (index) {
case 0:
return 'Calendar';
case 1:
return 'Alarm';
case 2:
return 'Stopwatch';
case 3:
return 'Notes';
default:
return '';
}
}
}
class StopwatchScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Stopwatch Page'));
}
}
class NotesScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Notes Page'));
}
}
import UIKit
import Flutter
import UserNotifications
import alarm
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
UNUserNotificationCenter.current().delegate = self
SwiftAlarmPlugin.registerBackgroundTasks()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound])
}
}
here is my debug console Launching lib/main.dart on iPhone 13 in debug mode... Running Xcode build... Xcode build done. 62.6s Debug service listening on ws://127.0.0.1:49939/Aqn1-dEHduw=/ws Syncing files to device iPhone 13... flutter: Notification Permission Denied! flutter: [Alarm] Alarm with id 1 scheduled successfully at 2025-02-06 11:00:00.000 flutter: [Alarm] Alarm with id 1 stopped flutter: [Alarm] Alarm with id 1 scheduled successfully at 2025-02-06 11:00:00.000 flutter: [Alarm] Alarm with id 1 stopped
and yes example code is working fine talking about giving notification permission it always return flutter: Notification Permission Denied! prompt is not appear for allowing notification
I am trying to create a reminder app using the alarm plugin (version 4.1.1) https://pub.dev/packages/alarm. The alarm is working fine, but I'm facing an issue where notifications are not appearing on the iOS simulator when the alarm triggers. The alarm rings as expected, but the notification doesn't show. Here is my full code—please check and help me resolve this issue.
import 'package:alarm/alarm.dart';
import 'package:alarm/model/alarm_settings.dart';
import 'package:alarm/model/notification_settings.dart';
import 'package:alarm/model/volume_settings.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:permission_handler/permission_handler.dart';
class AlarmHomeScreen extends StatefulWidget {
@override
_AlarmHomeScreenState createState() => _AlarmHomeScreenState();
}
class _AlarmHomeScreenState extends State<AlarmHomeScreen> {
List<AlarmData> alarms = [];
@override
void initState() {
// TODO: implement initState
super.initState();
requestNotificationPermission();
}
// Request notification permission
Future<void> requestNotificationPermission() async {
final status = await Permission.notification.request();
if (status.isGranted) {
// Permission granted
print("Notification Permission Granted!");
} else {
// Permission denied
print("Notification Permission Denied!");
}
}
void _addAlarm(DateTime dateTime, String label) async {
int id = alarms.length + 1;
final alarmSettings = AlarmSettings(
id: id,
dateTime: dateTime,
assetAudioPath: 'assets/marimba.mp3',
loopAudio: true,
vibrate: true,
volumeSettings: VolumeSettings.fixed(
volume: 0.8,
volumeEnforced: true,
),
androidFullScreenIntent: true,
notificationSettings: const NotificationSettings(
title: 'Alarm',
body: 'Time to wake up!',
stopButton: 'Stop',
icon: 'notification_icon',
),
);
await Alarm.set(alarmSettings: alarmSettings);
setState(() {
alarms.add(AlarmData(
id: id,
dateTime: dateTime,
label: label,
isEnabled: true,
));
});
}
void _removeAlarm(int index) async {
await Alarm.stop(alarms[index].id); // Stop the alarm using its ID
setState(() {
alarms.removeAt(index);
});
}
void _toggleAlarm(int index, bool value) async {
setState(() {
alarms[index].isEnabled = value;
});
if (value) {
// Re-enable the alarm
final alarmSettings = AlarmSettings(
id: alarms[index].id,
dateTime: alarms[index].dateTime,
assetAudioPath: 'assets/marimba.mp3',
loopAudio: true,
vibrate: true,
volumeSettings: VolumeSettings.fixed(
volume: 0.8,
volumeEnforced: true,
),
warningNotificationOnKill: Platform.isIOS,
androidFullScreenIntent: true,
notificationSettings: const NotificationSettings(
title: 'Alarm',
body: 'Time to wake up!',
stopButton: 'Stop',
icon: 'notification_icon',
),
);
await Alarm.set(alarmSettings: alarmSettings);
} else {
// Disable the alarm
await Alarm.stop(alarms[index].id);
}
}
void _showAddAlarmDialog() async {
DateTime selectedTime = DateTime.now();
DateTime selectedDate = DateTime.now();
String label = 'Alarm';
// Step 1: Show Time Picker
await showCupertinoModalPopup(
context: context,
builder: (context) => Container(
height: 350, // Increased height
color: CupertinoColors.systemBackground.resolveFrom(context),
child: Column(
children: [
SizedBox(
height: 250, // Increased height
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.time,
use24hFormat: false,
onDateTimeChanged: (DateTime newDateTime) {
selectedTime = newDateTime;
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CupertinoButton(
child: Text(
"Cancel",
style: TextStyle(fontSize: 18, color: CupertinoColors.destructiveRed),
),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
"Next",
style: TextStyle(fontSize: 18, color: CupertinoColors.activeBlue),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
],
),
),
);
// Step 2: Show Date Picker
await showCupertinoModalPopup(
context: context,
builder: (context) => Container(
height: 350, // Increased height
color: CupertinoColors.systemBackground.resolveFrom(context),
child: Column(
children: [
SizedBox(
height: 250, // Increased height
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: selectedDate,
onDateTimeChanged: (DateTime newDateTime) {
selectedDate = newDateTime;
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CupertinoButton(
child: Text(
"Cancel",
style: TextStyle(fontSize: 18, color: CupertinoColors.destructiveRed),
),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
"Next",
style: TextStyle(fontSize: 18, color: CupertinoColors.activeBlue),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
],
),
),
);
// Step 3: Show Label Input Dialog
await showCupertinoModalPopup(
context: context,
builder: (context) => Container(
height: 250, // Increased height
padding: EdgeInsets.all(20),
color: CupertinoColors.systemBackground.resolveFrom(context),
child: Column(
children: [
CupertinoTextField(
placeholder: 'Enter Alarm Label',
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey5,
borderRadius: BorderRadius.circular(12),
),
onChanged: (value) {
label = value;
},
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CupertinoButton(
child: Text(
"Cancel",
style: TextStyle(fontSize: 18, color: CupertinoColors.destructiveRed),
),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
"Set Alarm",
style: TextStyle(fontSize: 18, color: CupertinoColors.activeBlue),
),
onPressed: () {
final combinedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
_addAlarm(combinedDateTime, label);
Navigator.pop(context);
},
),
],
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(top: 20, left: 15, right: 15, bottom: 80),
child: alarms.isEmpty
? Center(
child: Text(
"No Alarms Set",
style: TextStyle(fontSize: 20, color: CupertinoColors.systemGrey),
),
)
: ListView.builder(
itemCount: alarms.length,
itemBuilder: (context, index) {
final alarm = alarms[index];
return Container(
padding: EdgeInsets.all(16),
margin: EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [CupertinoColors.systemGrey5, CupertinoColors.systemGrey6],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: CupertinoColors.systemGrey.withOpacity(0.2),
blurRadius: 8,
spreadRadius: 2,
offset: Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
alarm.label,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
),
SizedBox(height: 8),
Text(
'${alarm.dateTime.hour}:${alarm.dateTime.minute.toString().padLeft(2, '0')} - ${alarm.dateTime.day}/${alarm.dateTime.month}/${alarm.dateTime.year}',
style: TextStyle(fontSize: 16, color: CupertinoColors.systemGrey),
),
SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
CupertinoSwitch(
value: alarm.isEnabled,
onChanged: (value) => _toggleAlarm(index, value),
),
SizedBox(width: 10),
CupertinoButton(
padding: EdgeInsets.zero,
child: Icon(
CupertinoIcons.delete,
color: CupertinoColors.destructiveRed,
),
onPressed: () => _removeAlarm(index),
),
],
),
],
),
);
},
),
),
// Floating Action Button
Positioned(
bottom: 30,
right: 30,
child: GestureDetector(
onTap: _showAddAlarmDialog,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [CupertinoColors.systemBlue, CupertinoColors.systemTeal],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: CupertinoColors.systemGrey.withOpacity(0.4),
blurRadius: 8,
spreadRadius: 2,
offset: Offset(0, 4),
),
],
),
child: Icon(
CupertinoIcons.add,
size: 30,
color: CupertinoColors.white,
),
),
),
),
],
),
);
}
}
class AlarmData {
final int id;
final DateTime dateTime;
final String label;
bool isEnabled;
AlarmData({
required this.id,
required this.dateTime,
required this.label,
this.isEnabled = true,
});
}
import 'package:alarm/alarm.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'alarm/AlarmHomeScreen.dart';
import 'alarm/alarm.dart';
import 'alarm/reminder.dart';
import 'calender/CalendarScreen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Alarm.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
debugShowCheckedModeBanner: false,
// Adding the localization delegates here
localizationsDelegates: const [
DefaultMaterialLocalizations.delegate, // Ensures Material Localizations are available
DefaultCupertinoLocalizations.delegate, // Ensures Cupertino Localizations are available
DefaultWidgetsLocalizations.delegate,
],
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _selectedIndex = 0;
final List<Widget> _pages = [
CalendarScreen(),
AlarmHomeScreen(),
//AlarmScreen(), // Ensure that AlarmScreen is styled with Cupertino widgets
StopwatchScreen(),
NotesScreen(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const [
BottomNavigationBarItem(icon: Icon(CupertinoIcons.calendar), label: 'Calendar'),
BottomNavigationBarItem(icon: Icon(CupertinoIcons.alarm), label: 'Alarm'),
BottomNavigationBarItem(icon: Icon(CupertinoIcons.timer), label: 'Stopwatch'),
BottomNavigationBarItem(icon: Icon(CupertinoIcons.book), label: 'Notes'),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
tabBuilder: (context, index) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(_getTitle(index)),
),
child: SafeArea(child: _pages[index]),
);
},
);
}
String _getTitle(int index) {
switch (index) {
case 0:
return 'Calendar';
case 1:
return 'Alarm';
case 2:
return 'Stopwatch';
case 3:
return 'Notes';
default:
return '';
}
}
}
class StopwatchScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Stopwatch Page'));
}
}
class NotesScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Notes Page'));
}
}
import UIKit
import Flutter
import UserNotifications
import alarm
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
UNUserNotificationCenter.current().delegate = self
SwiftAlarmPlugin.registerBackgroundTasks()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound])
}
}
here is my debug console Launching lib/main.dart on iPhone 13 in debug mode... Running Xcode build... Xcode build done. 62.6s Debug service listening on ws://127.0.0.1:49939/Aqn1-dEHduw=/ws Syncing files to device iPhone 13... flutter: Notification Permission Denied! flutter: [Alarm] Alarm with id 1 scheduled successfully at 2025-02-06 11:00:00.000 flutter: [Alarm] Alarm with id 1 stopped flutter: [Alarm] Alarm with id 1 scheduled successfully at 2025-02-06 11:00:00.000 flutter: [Alarm] Alarm with id 1 stopped
and yes example code is working fine talking about giving notification permission it always return flutter: Notification Permission Denied! prompt is not appear for allowing notification
Please share debug logs. Are you able to show the notification running the example app of the plugin ?
Also, 5.0.0
was just released. It might fix your issue.