How to implement a podcast player in an iOS application? (part 1/2)

Florian Hardy
Ideas by Idean
Published in
5 min readMar 19, 2021

Since 2018, Idean has been developing Oscar, a Capgemini application that features articles, offers, experts, and podcasts related to tech and Capgemini.

Oscar is an app UI/UX design based, you can download it on the store here:

In this short series of 2 articles, we will discover how to create and add an audio player in an existing application (built for iPhone portrait only):

  • This first article focuses on the technical part (audio, notifications, controls…).
  • The second article is about the views creation and implementation.

The code is in Swift, and there might be some better solutions out there.

Requirements

  • Playing a playlist of audio files (from stream urls) in a persistent way across the application, even when the app is in background (with notifications and command center).
  • This feature has to coexist with the already implemented feature that allows to play a video inside a page of the application (not persistent, and no picture-in-picture wanted). That is to say: the audio (podcast) should not be played over the video, and vice versa.

Introducing the views

The full screen player, named PlayerDetailsViewController, is the root controller of a UIWindow, displayed on top of other screens in the app. In this way, it can be shown on top of any screen.

The Command Center and Notifications are explained later in this article.

The full screen player (PlayerDetailsViewController) — The command center — The notification

This view goes in pair with a small view (FloatingButtonController) that can display the state of the audio (loading, playing or paused), and can open the full screen player. It is also displayed inside a UIWindow that is on top of the app. Keep in mind that when the full screen is displayed, the small circle needs to be hidden. The small circle can be moved around the screen, on the left and right side. There’s the possibility to shut down everything by dragging toward the cross icon (to close the player and stop the audio).

The small player (FloatingButtonController)

Project configuration

Before starting to code, if you want the player to be persistent outside of your application, you need to check ✅ the Audio, AirPlay, and Picture in Picture and the Background fetch boxes in Background Modes.

Imports

No external dependencies are required, we just need AVKit and MediaPlayer.

Models

The data models that we created are:

  • Audio (contains the URL to stream, and some information to display)
  • Playlist (contains an array of Audio, and the index of the audio to play).

Singleton

In our app, we have created a persistent manager (a singleton, named PlayerManager). This manager has an AVPlayer that will play our audio stream. In order to meet the second requirement (to make the audio coexisting with the video), we moved all the code of the AVPlayer for video into the PlayerManager. So now, we have two instances of AVPlayer inside the Manager. Here is how the singleton is created:

Audio Session

It is necessary to set up an audio session if you want to play some audio inside your app. These two methods, named setupAVAudioSession and removeAVAudioSession are very important.

State Management

To know the current state of the player, we created an enum.

To observe the change of state, we needed to create a variable inside of the PlayerManager.

On the didSet of this variable, the observers are notified.

Each controller can become an observer that will be notified of any changes regarding the player by conforming to this protocol. For example, the FloatingButtonController and the PlayerDetailsViewController, can update the controls. Also, any ViewController with a video being played can be notified when an audio is also being played and react to it.

It is better to observe in viewWillAppear and un-observe in viewWillDisappear.

Controls

Dealing with media, you can imagine a lot of interactions, controls and editing… But for our needs, we had to implement these:

  • Play / Pause
  • Use the navigation slider
  • Go 10 seconds forward / backward
  • Modify the audio rate (speed)
  • Navigate through the playlist
  • Close and open the full screen player
  • Stop and close the audio

To get this done, we created some methods:

Command center

The command center is what allows the user to control the current audio session on the device. It is reachable via a swipe-up gesture on the device.

Load audio and notification

Like most of the applications that can play audio, you may need to handle the notification when the device is locked. The code to achieve that is placed inside the loadPodcast method.

The other method important here is updateInfoCenter.

Then, we need these 3 methods to set the current information inside the notification center.

What about the playlist ?

To load and launch a playlist, we created the launchPodcastPlaylist method. The Playlist has a current index, in case you need to launch the playlist on a specific Audio.

Close and stop everything

This method, to dismiss and stop the audio player is called when the floating button is dragged into the cross icon in the middle of the screen.

You should also think about the AppDelegate and call two methods to be sure that everything is ok when your application becomes active again and will terminate.

Did I forget about the videos ?

In the beginning of this article, I said that the videos are now handled in the PlayerManager. You need to use the videoPlayer of our PlayerManager. So, this is how to load a video from any ViewController of your application.

And inside the PlayerManager, we need to remove the audio session (if there is one), because we don’t want the notification to be displayed for the videos.

Recap

In this article, I described the main steps to implement an audio player in an existing application. There are a lot of things to consider.

You can find the entire code of the mini-serie here (of course, you can adapt it to fit your needs).

Don’t forget to check the other part of this article, focused on the two ViewControllers (the small player and the full screen player).

Feel free to share your feedback in the comments! And don’t hesitate to tell me if this was helpful.

Thank you for reading.

--

--