One of the features of the app I'm working on is an "idle timeout" - basically if the user doesn't interact with the app for more than five minutes, their session ends for privacy / security reasons.
This is currently implemented by overriding sendEvent(_ event: UIEvent)
in the app delegate and resetting a timer.
However, what I've noticed is that sendEvent(_ event: UIEvent)
isn't called at all when a user is interacting with the app using VoiceOver.
It is called when the user double-taps to activate a control, but it isn't called for focus changes, interacting with .adjustable
controls, and so on.
This means that if a user is swiping through a long list of rows in a table view, for example, sendEvent(_ event: UIEvent)
isn't called and a user may be timed-out of the app, even though they were interacting with it.
Is there a way to detect VoiceOver focus changes or interactions at the UIApplication
or UIWindow
level, or a notification that can be subscribed to for a clean solution?
The closest solution I've found suggests using the UIAccessibilityFocus
protocol on individual views, but this feels like it could be quite messy and involve a lot of subclassing (https://stackoverflow.com/a/20712889).
Any different suggestions for an idle timeout that works for VoiceOver and non-VoiceOver users would also be much appreciated - there could well be something I've missed.
So I figured out the solution here and I'm now kicking myself.
UIAccessibility.elementFocusedNotification
is the key (https://developer.apple.com/documentation/uikit/uiaccessibility/1620210-elementfocusednotification).
So a solution could look something like:
NotificationCenter.default.addObserver(self,
selector: #selector(self.accessibilityElementFocussed(notification:)),
name: UIAccessibility.elementFocusedNotification,
object: nil)
@objc private func accessibilityElementFocussed(notification: NSNotification) {
// Reset your idle timer here.
}
Hopefully this helps someone out - I've seen a lot of solutions for idle timers online that don't take into account VoiceOver users.