schedule and reschedule local notification

By "schedule" in the title, I mean schedule reliably at a given time, not simply eventually or at some indeterminate future time. By "reschedule" I mean, having triggered one, trigger another.


There are a number of apps on the app store that attempt to simulate a clock which chimes the hour and sometimes the half hour. Think of Big Ben, grandfather clocks, cuckoo clocks, and ships bells. These devices do no good if they only chime when you're looking at them. In the case of an app, the app ought not to need be in the foreground. The point is that they provide a reliable, audible time signal whenever in range of hearing.


Most if not all of these apps are currently broken. My own attempt to write one has run into a wall. At the time of writing, this is the era of iOS 13, most currently iOS 13.4.


Given that background, I'd like to revisit this issue that "has been discussed many many times here on these forums" with a (hopefully) fresh and workable, safe suggestion.


Even better will be if someone chimes in (pardon the pun) to suggest an API or API usage that I've missed, one that doesn't involve requiring the app to be online with the connected world receiving periodic push notifications.


## Prior art

Here is a brief summary of prior forum discussions:


- [App Timer in the background](https://forums.developer.apple.com/thread/132078) April, 2020

- [Can I schedule a task weekly?](https://forums.developer.apple.com/thread/81108?q=schedule%20background%20task*) June, 2017

- [Timer issues whilst backgrounded in iOS 10.3](https://forums.developer.apple.com/thread/75468) April to June, 2017 appears to be the point where keeping a timer when your app goes to background was no longer a solution.

- [How to schedule background tasks?](https://forums.developer.apple.com/thread/72743?q=schedule%20background%20task*) February, 2017 in which the poster definitely means schedule, as in reliably (more or less) at a particular time or interval (i.e. not simply at some time that the background service finds to be prospicious).

- [Re: How do I cause a timer to fire while the app is in the background?](https://forums.developer.apple.com/message/341449#341449) November, 2018 in which the responder complains that the poster is asking the question in too many places; however, the suggested solution is to ping through push notifications from a server.


It really does keep coming up over and over.


## Reference art

Examples of physical devices for sale in the real world, that have these characteristics. All were found on Amazon, but I'm not putting the links here. You'll have to search. (Sorry Jeff.):


- Hermle Ship's Bell Clock Navy Bell Strike, about $800

- Weems & Plath Atlantis Collection Quartz Ship's Bell Clock (Brass), about $570

- Benail Singing Bird Wall Clock 12 Inch of The Bird Names and Songs, about $15

- Bedford Clock Collection Redwood Mantel Clock with Chimes, about $60

- Kieninger Grandfather Clock Walnut, about $6,800

- FCZH Pendulum Wall Clock, Grandfather Mechanical Wood Clock with Westminster Chime, about $3800

- German Cuckoo Clock 8-day-movement Chalet-Style Authentic black forest cuckoo clock by Hönes, about $2,000


which is simply to demonstrate that this is a real thing that people ascribe value to.


## What has been tried at iOS 13.4

Reference GitHub issue [Ring bell when application is in the background](https://github.com/wbreeze/ShipsClock/issue/1) for code and comments. In summary,


- Keeping a timer running.

- The background task mechanisms from the [BackgroundTasks API](https://developer.apple.com/documentation/backgroundtasks), `BGTaskScheduler`, `BGProcessingTaskRequest`, `BGAppRefreshTaskRequest` among other things, such as push and incoming call notifications.

- The notification mechanisms from the [UserNotifications API](https://developer.apple.com/documentation/usernotifications), `UNUserNotificationCenter`, `UNNotificationRequest'.


Not surprisingly, keeping a timer running isn't the way to go.


With BackgroundTasks, both refresh and processing types are run very infrequently. They don't provide the necessary precision to play a clock chime near an hour or half hour.


The UserNotifications API very very nearly has it pegged. It will schedule a notification event with a sound that's played "pretty closely" to the scheduled time. Push notifications even let the app run a little bit of filter code when the notification arrives; however, it's unsatisfactory to have a clock chime that only works if the device is connected to the net. Consider using it at sea!


The local notification works to play a chime one time (and on time) while the app is in background, given a notification scheduled as the app "went to sleep."


What local notifications lack, and this is key, is the ability to run just enough app code to schedule the next notification. The notifications can call an application delegate, which will wake up the application and run some of its code; however, that delegate is only called when and if eyeballs and hands interact with the notification.


## Proposals

One of the following enhancements to the UserNotifications API would enable applications like this one:


- Call the `UserNotificationCenter` `UNUserNotificationCenterDelegate` `userNotificationCenter(_:didReceive:withCompletionHandler:)` with an action similar to [UNNotificationDismissActionIdentifier](https://developer.apple.com/documentation/usernotifications/unnotificationdismissactionidentifier), however always called when the notification triggers.

- Call a new method in the delegate when the notification triggers.

- Allow a service app extension similar to that described in [Modifying Content in Newly Delivered Notifications](https://developer.apple.com/documentation/usernotifications/modifying_content_in_newly_delivered_notifications) which is given a little bit of time to act before any notification (push, local, sound, badging, alert) gets shown.


As a bonus, it would be great if the notification could play a sound without cluttering the notification center with a bunch of visual chime notices.


That's all! Thank you for reading to the end.