Other App Audio Handling (v3.3.1)
No code changes are required to upgrade from 3.3.0 to 3.3.1. The public API is unchanged, and the new callback didDetectOtherAppAudioActive() has a default implementation, so implement it only if you need it.
1. Behavior while another app is using audio
When another app such as a call, VoIP or an alarm uses audio, tracking pauses (didInterrupt()). The SDK tries to resume automatically, and from 3.3.1 it no longer ends tracking while the other app keeps using audio; it waits instead.
| Situation | 3.3.0 | 3.3.1 |
|---|---|---|
| Another app keeps using audio and all 3 automatic resume attempts are blocked | didFail(error: .interruptionRecoveryFailed) (as soon as a call lasted longer than 17 seconds) | Tracking does not end; the SDK checks again every 30 seconds, resumes automatically once audio is released, and calls didResume() |
| Notifying the app that resume is blocked | None | didDetectOtherAppAudioActive() once |
| Resume still fails after the other app releases audio | interruptionRecoveryFailed | interruptionRecoveryFailed (same) |
didResume() on resume | Could be called twice, and if resuming failed, didInterrupt() came again after didResume() | Usually called once, after recording has actually restarted. It can occasionally be called twice, so handle repeated calls safely |
stopTracking() after interruptionRecoveryFailed | The session closed but recording stayed on, so the microphone turned on again after the call | Recording stops as well |
2. didDetectOtherAppAudioActive()
protocol AsleepSleepTrackingManagerDelegate {
// ...
func didDetectOtherAppAudioActive() // optional (v3.3.1)
}- Called when the SDK tried to resume after an interruption but could not, because another app is still using audio.
- Audio from another app is playing, as with a call or VoIP
- Activating the audio session was refused, as with an alarm
- It is called only once per interruption.
- It is not guaranteed to run on the main thread. Update the UI on the MainActor.
We recommend letting the user knowWhile your app is in the background, iOS may block recording from resuming. If the pause lasts, let the user know, for example with a local notification.
The example below shows a local notification only if the pause lasts more than 5 minutes, and cancels it when tracking resumes or ends. Request notification permission in advance, for example when tracking starts.
import UserNotifications
final class TrackingViewModel: AsleepSleepTrackingManagerDelegate {
private let pausedNotificationId = "otherAppAudioActive"
func didDetectOtherAppAudioActive() {
let content = UNMutableNotificationContent()
content.title = "Sleep tracking is paused"
content.body = "Another app has been using audio for 5 minutes. Tracking resumes automatically once it ends."
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5 * 60, repeats: false)
let request = UNNotificationRequest(identifier: pausedNotificationId, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)
}
func didResume() {
cancelPausedNotification()
}
func didClose(sessionId: String) {
cancelPausedNotification()
}
private func cancelPausedNotification() {
UNUserNotificationCenter.current()
.removePendingNotificationRequests(withIdentifiers: [pausedNotificationId])
}
// ... other delegate methods
}3. Other changes
- Crash fixes
- Calling
startTracking(),stopTracking(),resumeTracking()and similar methods beforecreateSleepTrackingManagerused to crash the app. It now reportsdidFail(error: .configurationError)and does nothing. - Fixed a crash when the audio format converter could not be created.
- Calling
- Token authentication: Fixed a failed request when cleaning up an unfinished previous session during init, because the request was sent without authentication.
- SDK logs
- Logs are saved immediately so they are not lost when the app is force-quit or an error occurs during tracking.
- Large log files (over 2MB) are uploaded instead of discarded, and a failed upload is retried later.
- The SDK deletes
AsleepSDK.logandAsleepSDK_send.logthat 3.2.x left in the app'sDocumentsfolder. Other files inDocumentsare not touched.
- Cleaned up SDK debug output in the Xcode console.
Updated about 15 hours ago
