Our watchOS app uses CMFallDetectionManager (with the proper entitlement) to help alert our users and their caregivers when a fall occurs. We have had a simple implementation in our app for a couple of years now and it seems to work fine.
Recently, we received a report of delayed fall alerts and have traced back the root cause to a failure from the system to call func fallDetectionManager(_ fallDetectionManager: CMFallDetectionManager, didDetect event: CMFallDetectionEvent, completionHandler handler: @escaping () -> Void)
promptly when a fall occurs.
Our implementation of this method begins with the following logging statement: "Fall detected at \(event.date) with status \(event.resolution.rawValue) at \(Date())"
When we check our logs, we see a number of events that occur as expected, for example: Fall detected at DATE_AND_HOURS:42:09 +0000 with status 1 at DATE_AND_HOURS:42:51 +0000
However, many events show a period of several minutes from fall detection to a report: Fall detected at DATE_AND_HOURS:28:09 +0000 with status 0 at DATE_AND_HOURS:32:42 +0000
or Fall detected at DATE_AND_HOURS:44:26 +0000 with status 1 at DATE_AND_HOURS:48:14 +0000
And in the instance from our customer, we had a fall detected that evidently wasn't reported for 5 hours and 4 minutes (I'm not sharing exact timestamps publicly to maintain user privacy).
We are aware of the documentation regarding the delegate and have programmed it appropriately not to receive duplicate events:
Additionally, each time the user launches your app, the system checks to see if a fall event has occurred during the recent past. If one has occurred, it calls this method.
Note that your app may receive the same event multiple times, for example, if the app crashes and relaunches. Always check the event’s date property to determine whether your app has already received the event. The system guarantees that different fall events have different date values.
Moreover, our logger persists logs when there is no network access, and the delegate callback also requests a network post to our servers that, again, is preserved in a background queue until connectivity is restored if it's not available. Our app's other updates (watchOS complication, etc.) from this user's Watch also show that our app was running in the background and communicating with our servers during that time. We have very high confidence that the watch and our app did not miss any more timely calls to that delegate method.
While this one five-hour delay was an exceptionally bad occurrence, we also find the other delays of several minutes to be concerning, considering the time-sensitive nature of falls. Does Apple or do any developers have any insights about what's going on and what expectations we should be setting for our users?