iOS doesn't report when an app will be suspended (placed from background into a non-processing state) nor does it seem to fire a notification once the app has resumed. There is some confusion about this as there is a notification when the app becomes "active" or will resign the "active" state, however this is not always the right value needed. iOS Apps have a number of states:
- Active: App is in the foreground (frontmost) and there are no notifications or menu's pulled over it. Pulling a menu down or getting an external notification or text message will cause the app to "resign" active, and resume active once the alert has been dealt with.
- Background: App is not in the foreground but still processing. This happens briefly before suspend if there are no background tasks running, or can be a permanent state if there is a long running background mode (audio, location, etc) running.
- Suspended: App is in memory, but run loops and processing is paused
- Terminated: App is not running or in memory, has been quit either by user (force quit) or OS (to free up memory) or was never launched
All the other states have NotificationCenter notifications when they occur, but suspend has nada. To resolve this, I've made a helper class that can roughly estimate when a suspend will and did occur, as well as when the app unsuspends. It does this by watching for background state with finite time remaining (suspend will occur), and then looking for a "gap" in run loop processing (suspend did occur, did unsuspend) and firing the related notifications.
let recorder = SuspendStatusRecorder()
recorder.start()
Recorder will stop if de-initialized, or recorder.stop()
is called
Subscribe to the notifications to capture and act on events.