Mobile Development 10 min read

Dynamic iOS Push Notification Voice Playback without Releasing a New App Version

This article explains how to play custom voice prompts in iOS push notifications by downloading MP3 files to the app’s Library/Sounds directory or a shared app‑extension group at runtime, avoiding the need to bundle the audio in the app or submit a new version for review.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Dynamic iOS Push Notification Voice Playback without Releasing a New App Version

The iOS API UNNotificationSound(named:) plays a sound file that must exist in one of three locations: the app’s Library/Sounds folder, the shared group’s Library/Sounds folder, or the app bundle. Previously only the third option was used, which required a new app release for any audio change.

To add new voice prompts without updating the app, the sound file can be downloaded at runtime into either the app’s Library/Sounds directory or the shared group’s Library/Sounds directory. Two implementation strategies are discussed:

Download the audio when the push notification is received in the Notification Service Extension and store it in Library/Sounds . This approach fails because the extension’s container differs from the main app’s container, so the file is not found by the playback API.

Provide a separate API that the app calls on launch to pre‑download the audio into Library/Sounds . The push payload then only needs to specify the file name, and the sound will be played if it already exists.

The preferred solution combines the two ideas: create a shared app‑extension group, download the audio in the Notification Service Extension into the group’s Library/Sounds folder, and then play it using UNNotificationSound(named:) . The steps are:

Create a shared App Group for the main app and the Notification Service Extension.

In didReceive(_:withContentHandler:) , extract the download URL from the push payload and download the MP3.

Store the downloaded file in the group’s Library/Sounds directory (creating the directory if necessary).

After a successful download, set bestAttemptContent.sound = UNNotificationSound(named: UNNotificationSoundName(" .mp3")) and call the content handler.

Utility functions are provided to manage the shared directory, check whether a voice file already exists, and perform the download:

static func updateAppMainBundleMP3FileResources() { /* scans the app bundle for .mp3 files and stores their names in UserDefaults of the shared group */ }
static func isVoiceInfoExist(voiceName: String) -> Bool { /* checks bundle, shared Library/Sounds, and group folder for the file */ }
static func getLibrarySoundsDir() -> String? { /* returns the path to the shared Library/Sounds folder, creating it if needed */ }
static func downloadAndSave(url: URL, voiceName: String, handler: @escaping (_ localURL: URL?) -> Void) { /* downloads data and writes it to Library/Sounds */ }

The final notification service class uses these helpers to play the voice or fall back to the default behavior when the file is missing or the download fails.

In summary, iOS voice notification can be made dynamic by storing audio files in Library/Sounds (either app‑local or shared via an App Group) and downloading them on demand, eliminating the need for a new App Store submission for each audio update.

mobile developmentiOSpush notificationsSwiftUNNotificationSoundVoice Playback
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.