如何设置每日重复通知?通知仅触发一次问题求助
Fixing iOS Repeating Notification Issue
Hey there! Let's figure out why your notification only fires once—this is a super common gotcha with iOS UserNotifications. From the code snippet you shared, it looks like you're missing a few critical pieces to make the notification repeat reliably. Let's break this down and fix it step by step.
Common Culprits for One-Time Notifications
Before jumping into code, let's cover the most likely reasons your repeat logic isn't working:
- You didn't set
repeats: trueon your notification trigger (the #1 mistake here) - You're reusing the same notification identifier without removing old requests, causing new ones to overwrite the old (and broken) ones
- Your date components are too specific (like including a fixed day/year) instead of targeting just hour/minute for daily repeats
Corrected Full Code
Here's the updated version of your function with all the necessary fixes:
static func scheduleNotification(hour: Int, minutes: Int, completion: @escaping (Bool) -> ()) { // 1. Build out your notification content let notificationContent = UNMutableNotificationContent() notificationContent.title = "Hello!" notificationContent.body = "Time for your daily check-in!" // Add a body so users know what it's for notificationContent.sound = UNNotificationSound.default // Ensure users get an audio cue (optional but helpful) // 2. Set up date components to target the specific hour/minute every day var dateComponents = DateComponents() dateComponents.hour = hour dateComponents.minute = minutes // Leave out day/month/year so it repeats daily // 3. Create the trigger with REPEATS ENABLED (this is the key!) let trigger = UNCalendarNotificationTrigger( dateMatching: dateComponents, repeats: true ) // 4. Use a unique identifier (or fixed ID if you want to update this same notification later) let notificationId = "DailyReminder_\(hour)_\(minutes)" // 5. First remove any existing pending notifications with the same ID // This prevents overwriting issues if you re-schedule with a new time UNUserNotificationCenter.current().removePendingNotificationRequests( withIdentifiers: [notificationId] ) // 6. Build the notification request let request = UNNotificationRequest( identifier: notificationId, content: notificationContent, trigger: trigger ) // 7. Add the request to the notification center UNUserNotificationCenter.current().add(request) { error in if let error = error { print("Notification scheduling failed: \(error.localizedDescription)") completion(false) } else { print("Daily notification scheduled successfully!") completion(true) } } }
Key Fixes Explained
Let's call out the most important changes:
repeats: trueon the trigger: This tells iOS to fire the notification every time the date components match (in this case, every day at your specified hour/minute). Without this, it only fires once.- Removing old pending requests: If you ever re-run this function to update the notification time, removing the old request first ensures the new trigger takes effect immediately.
- Simplified date components: By only setting
hourandminute, we ensure the trigger matches that time every day. If you added a specificdayoryear, it would only fire once on that exact date.
Additional Checks to Ensure It Works
Don't forget these critical steps outside the function:
- Request notification permissions: You need to ask the user for permission to send notifications before anything will show up. Add this to your app's launch code (like
AppDelegateorSceneDelegate):UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in if granted { print("Notification permission approved!") } else { print("Notification permission denied—user won't see alerts.") } } - Verify device settings: Double-check that your app has notifications enabled in the device's Settings > [Your App] > Notifications.
- Test with a near-future time: If you set the time to a past hour (e.g., 9 AM when it's currently 10 AM), iOS will wait until the next day at 9 AM to fire it. Test with a time 5 minutes from now to see it work immediately.
内容的提问来源于stack exchange,提问作者codechef
相关产品推荐
相关产品推荐

