Background Audio Transitions Not Working Properly with Spotify Integration

I’m working on an iOS app that connects to Spotify and plays custom playlists. Everything works fine when the app is active, but I’m having trouble with automatic song switching when the app goes to the background.

My playlist has songs with custom start times and durations. When a song hits its time limit, it should automatically jump to the next track. This works great in the foreground but fails completely in background mode.

I tried using different dispatch queues but nothing seems to work reliably when the app isn’t visible. Has anyone solved similar background audio scheduling issues?

private func setupTrackTransition(waitTime: TimeInterval? = nil) async {
    let upcomingIndex = playlistPosition + 1
    let currentTrack = trackList[playlistPosition]
    let playDuration = waitTime ?? TimeInterval(currentTrack.trackLength)

    guard upcomingIndex < trackList.count else {
        transitionTask?.cancel()
        transitionTask = DispatchWorkItem {
            self.notifyPlaylistComplete()
        }
        if let transitionTask = transitionTask {
            DispatchQueue.main.asyncAfter(deadline: .now() + playDuration, execute: transitionTask)
        }
        return
    }

    transitionTask?.cancel()
    transitionTask = DispatchWorkItem {
        self.playlistPosition += 1
        Task { await self.startCurrentTrack() }
    }

    if let transitionTask = transitionTask {
        DispatchQueue.main.asyncAfter(deadline: .now() + playDuration, execute: transitionTask)
    }
}

had this exact problem last year! iOS suspends dispatch timers when your app goes to background. switch to AVAudioPlayerNode with scheduled buffers - it keeps running even when backgrounded. also call beginBackgroundTask before scheduling to grab extra execution time. fixed it for my podcast app with custom segments.

iOS kills background execution for regular apps after about 30 seconds, so your DispatchWorkItem gets suspended. I ran into this same issue building a meditation app with custom audio segments. What fixed it for me: ditch the timers and use Spotify’s actual playback position instead. Check the current position with SPTAppRemotePlayerAPI and trigger your transitions based on that. Works because Spotify has background audio privileges. Make sure you’ve got audio background mode enabled in Info.plist and use AVAudioSession to keep audio focus. Bottom line - piggyback on Spotify’s background capabilities instead of fighting iOS with custom scheduling.

Background audio scheduling sucks because iOS doesn’t trust apps to behave when they’re not visible. Been through this hell with multiple projects.

The problem is you’re managing timing logic inside your iOS app when it has zero execution guarantees in the background. Every solution mentioned here still needs your app to somehow stay alive.

Move the scheduling logic outside your app completely. Set up a workflow that monitors Spotify’s playback position through their API and triggers track changes from a server that’s always running. Your iOS app becomes a simple interface talking to this external system.

Built something similar for a client needing precise audio cue timing for fitness classes. The iOS app would die in someone’s pocket, but external automation kept everything running perfectly. Users never knew because music transitions happened exactly when they should.

Send the playlist with custom timing to the automation service when it starts. The service handles the heavy lifting and your app just shows current status when active.

Check out Latenode for workflow automation. It can poll Spotify’s API, track timing, and trigger song transitions without depending on your iOS app staying alive in the background.

Yeah, background processing limitations are killing you here. DispatchQueue timers get throttled hard when your app goes to background. Ditch the timer approach. Instead, pre-calculate all your transition timestamps when the playlist starts. Then use NSTimer with a short interval (like 0.5 seconds) to constantly check Spotify’s playback position against your markers. It’s more resource-heavy but actually works when switching between foreground and background. Don’t forget to handle the app delegate callbacks - pause your transition logic in applicationDidEnterBackground and restart it in applicationWillEnterForeground. Otherwise, you’ll get weird behavior when users come back to your app.