Post

Replies

Boosts

Views

Activity

Reply to Persist and deliver scheduled local notifications after app update
Hi Apple Engineer - I hate to post this message because I really wanted to be mistaken in my original post, but I just deployed an updated version of my app and previously scheduled local notifications were NOT delivered after the update. I carefully tested this with the user who originally brought this issue to my attention, by asking him to: 1) schedule a notification right before the version update and then 2) allow the app to update silently in the background. After the update, the local notification was NOT delivered. I did NOT change the app's bundle ID, nor am I using any sort of third party tool. The user who reported this issue has an iPhone 14 Pro Max, iOS 18.2.1, and allowed the app to update silently in the background. After re-launching the app, local notifications continued as before. So, it does appear to be the case that the update breaks previously scheduled local notifications until the app is relaunched. I've included my code to schedule local notifications below. I'm running this code when my app changes phase and moves to the .background. If the issue I'm describing with scheduled local notifications is NOT the expected behavior, do you see anything in my code that would cause this? func createLocalNotifications() { UNUserNotificationCenter.current().removeAllDeliveredNotifications() // Clear all the old notifications to replace them with newly scheduled notifications in this function UNUserNotificationCenter.current().removeAllPendingNotificationRequests() let context = sharedModelContainer.mainContext var query = FetchDescriptor<Item>(predicate: #Predicate { item in item.reminder == true}, sortBy: [SortDescriptor(\Item.reminderDate, order: .forward)]) query.fetchLimit = 60 do { let items = try context.fetch(query) for notificationItem in items { if notificationItem.reminder == true { let content = UNMutableNotificationContent() content.title = "Reminder" content.body = notificationItem.name content.sound = .default // Local notification trigger let calendar = Calendar.current var triggerDate = calendar.dateComponents([Calendar.Component.day, Calendar.Component.month, Calendar.Component.year], from: notificationItem.reminderDate!) triggerDate.hour = Calendar.current.component(.hour, from: userSettings.reminderTimeOfDay) triggerDate.minute = Calendar.current.component(.minute, from: userSettings.reminderTimeOfDay) let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false) // Local notification request with content and trigger let notificationUUID = "\(notificationItem.id)" + "-localNotificationID" let request = UNNotificationRequest(identifier: notificationUUID, content: content, trigger: trigger) // Schedule the request UNUserNotificationCenter.current().add(request) { error in guard error == nil else { return } } } // End of notificationItem.reminder == true } // End of notificationItem in items } catch { print("Local notification error") } // End of catch } // End of createLocalNotifications() In case this is relevant, I also have an AppDelegate file with this code: class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { UNUserNotificationCenter.current().delegate = self return true } // End of func didFinishLaunchingWithOptions } // End of AppDelegate // Show local notification in foreground extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.list, .banner, .badge]) } }
Jan ’25