iOSSystemSoundsLibrary: a typed map of the sounds iOS already ships with
List of all system sounds used in iOS
At a glance
- What is it?
- TUNER88/iOSSystemSoundsLibrary is a reference list of the system sounds built into iOS, packaged as a Swift 6 library that plays them by name. The mappings are unofficial, were collected on iOS 7, and Apple documents none of them.
- Who is it for?
- Adopt SystemSoundsLibrary when you need a device notification sound on iOS and want a typed name instead of a magic number, especially in a codebase that also targets tvOS, visionOS or Mac Catalyst. Do not treat its table as a contract, because Apple does not document these identifiers and the mappings were collected on iOS 7, so they may differ, be missing or be added on the versions you support.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An unofficial table of identifiers Apple never published
iOS ships with a set of system sounds, and until recently there was no dependable way to find out which ones exist or what identifier plays them. This repository is a reference list of those sounds, assembled by reading them off a device, plus a small demo app that lists every file in /System/Library/Audio/UISounds and plays it when you tap it.
The table at the centre of the README is the payload. It maps a SystemSoundID to a file name and a category, running from 1000 for new-mail.caf in the MailReceived category through the SIM Toolkit tones, the call tones, the screen lock and unlock sounds, the camera shutter, the recording beeps and the JBL set. The demo app is not a toy: it is the only practical way to hear what is actually installed on the version of iOS you are targeting.
The caveat is stated at the top of the README and it is the most important sentence in the project. Apple does not officially document these SystemSoundIDs or file names, the mappings were collected on iOS 7, and they may differ, be missing, or be added on other iOS versions. The instruction that follows is to always test on the iOS versions you support.
So the correct mental model is a field guide rather than an API contract. The identifiers are useful because they are consistent enough to have survived many releases, not because anybody promised they would. A team shipping a notification sound should treat any entry as a candidate and verify it on each OS version in its support matrix, which is exactly what the README tells you to do.
Two mechanisms: a numeric identifier or a file in UISounds
The documentation shows two ways to make noise, and they have different failure modes.
The first is by identifier, through the AudioToolbox framework and System Sound Services, which is linked automatically in a modern Xcode project once you import it:
import AudioToolbox
AudioServicesPlaySystemSound(1003) // SMSReceived (see the table below)That is one line and it plays the sound. The risk is that 1003 has no meaning at runtime, so a wrong or retired identifier fails silently, and the value is a magic number in your source unless you wrap it.
The second is by file, resolving a path inside the system audio directory and creating a sound identifier from the URL, then disposing of it when playback finishes:
import AudioToolbox
func playSystemSoundFile(named fileName: String) {
let url = URL(fileURLWithPath: "/System/Library/Audio/UISounds/\(fileName)")
var soundID: SystemSoundID = 0
guard AudioServicesCreateSystemSoundID(url as CFURL, &soundID) == kAudioServicesNoError else { return }
AudioServicesPlaySystemSoundWithCompletion(soundID) {
AudioServicesDisposeSystemSoundID(soundID)
}
}The file route fails in a different way. If the file name does not exist on that OS version, the create call returns something other than kAudioServicesNoError and the guard returns without playing anything, which is a checkable failure rather than a silent one. That difference matters when you are writing code that has to degrade quietly on an OS version where a particular sound was removed.
The completion variant of the API needs iOS 9 or later, which the README notes, and the same pattern is shown in Objective-C for projects that are not Swift, using the AudioToolbox header and a bridged CFURLRef.
The SystemSoundsLibrary package replaces the magic number with a name
The Swift package, called SystemSoundsLibrary, exists to fix the readability problem in the raw API. The README describes it as wrapping these sounds in a typed Swift 6 API with availability information for iOS 15 and later, tvOS, visionOS and Mac Catalyst.
It is added the standard way, through File > Add Package Dependencies in Xcode, or as a package dependency:
dependencies: [
.package(url: "https://github.com/TUNER88/iOSSystemSoundsLibrary", from: "2.0.0"),
],And the call site reads as a name rather than a number, with an async variant that waits for the sound to finish:
import SystemSoundsLibrary
SystemSoundPlayer.play(.smsReceived) // 1003
await SystemSoundPlayer.playAndWait(.mailReceived)The comment next to the first call is the important part: the typed case still carries the numeric identifier, so the mapping remains visible and verifiable. The package has not hidden the underlying table, it has given it a name and attached availability metadata to it.
The availability information is what a typed API earns its keep on. A sound that exists on iOS but not on one of the other platforms in your target list is a compile-time question in this package, and the README lists the platforms explicitly, so you can see what the wrapper claims to support before you adopt it.
For SwiftUI there is a compact example too, where the same AudioToolbox call is bound to a button:
import SwiftUI
import AudioToolbox
struct ContentView: View {
var body: some View {
Button("Play “Tink”") {
AudioServicesPlaySystemSound(1103) // KeyPressed (Tink.caf)
}
}
}And the repository points at Examples/SoundBrowser, a SwiftUI app that browses and plays every sound, which is the fastest way to confirm what a given device actually has.
Version drift is tracked as data, not as a promise
The README keeps separate file listings per iOS version, including the list of all system audio files in iOS 7.0.2, a section for SystemSoundIDs added after iOS 7, and lists for iOS 26 and iOS 27, followed by a changes since iOS 7 section.
That structure is the real contribution of the project. Anyone who has shipped an iOS app that plays a system sound knows the failure mode: the sound worked, then an OS update changed the file name or the identifier, and the app went quiet on a subset of devices. A per-version inventory turns that into a diff you can read.
The identifiers in the table are also reused for different file names in places, and the table shows that, listing sms-received1.caf for both 1007 and 1012, and Tock.caf for both 1104 and 1105, with 1015 and 1102 showing a dash where no file name is given. Those are the entries where a lookup by identifier and a lookup by file name give different answers, and they are exactly the cases where a hardcoded value in an app is most likely to break.
The demo app closes the loop. It enumerates the actual contents of /System/Library/Audio/UISounds at runtime, so running it on a device tells you the truth for that device, and the README is explicit that the demo project must be run on a real device because the iOS Simulator does not play system sounds. That single hardware requirement is the practical testing procedure for the whole library.
What the project does not offer is a programmatic guarantee. There is no supported API, no stability commitment from Apple, and no automated check that a mapping still holds, so the version lists are a snapshot that a maintainer refreshes by hand.
The names do not match, and that trips people up
The repository is called iOSSystemSoundsLibrary. The Swift package is SystemSoundsLibrary. The Xcode project in the root is SystemSoundLibrary.xcodeproj, and there is a SystemSoundLibrary/ directory alongside Sources/, Tests/ and SystemSoundLibraryTests/. The demo lives in Examples/SoundBrowser/.
Three different spellings for one project is a real trap when you are searching, when you are adding a package dependency, and when you are trying to work out whether a file belongs to the package or to the demo. The package dependency URL points at the repository, and the import in your code is SystemSoundsLibrary, so the two names you actually type are different from the repository name. Anyone writing documentation or a blog post about it should get this right the first time, because a reader who pastes the wrong import gets a module not found error and no hint about which of the three names is the right one.
The rest of the layout follows a normal Swift package shape, with Package.swift at the root, Sources/ for the library, Tests/ and SystemSoundLibraryTests/ for tests, data/ for the reference data that presumably backs the tables, and scripts/ for tooling. There is a CHANGELOG.md and the release tooling is release-please, with a release-please-config.json and a .release-please-manifest.json, which is a conventional setup for a package published from a single main branch.
The single release is v2.0.0 on 2026-10-18, and the last push was on 2026-10-18, with the repository not archived. The MIT licence is in the LICENSE file with a NOTICE file beside it. The version jump to 2.0.0 on a package that previously would have been 1.x suggests the API was reshaped rather than extended, so an existing adopter should read CHANGELOG.md before bumping, and the from: "2.0.0" requirement in the dependency line is the practical guard against silently landing on the old API.
When a system sound is the wrong choice
This library is for one job: playing a sound that iOS already provides. There are several situations where that is the wrong answer.
The first is when the sound is part of your product. A system sound is Apple's asset, not yours. If a notification is part of your brand, or if you need a sound that is identical on every device, you need to ship your own audio file and play it with your own audio stack, not borrow a system identifier. Borrowing also means the sound changes meaning over time, since a system sound is associated with a system event that Apple can repurpose.
The second is when the identifier matters to the user. These are the sounds iOS itself plays for mail, SMS, alarms, low power, screen lock and the camera shutter. Using them inside an app, where they are not attached to their original event, tends to read as a system glitch to anyone who recognises them.
The third is the case the README keeps warning about, where you depend on a mapping and an OS update changes it. If the sound is cosmetic and you can live without it, that is a tolerable risk. If the sound is the confirmation that a payment went through, a system sound is the wrong foundation for it, because there is no contract behind it.
The alternative approach for the cases where you do need a dependable sound is to bundle the audio and play it yourself, which trades the zero bytes of a system identifier for a file you control and a playback API with predictable behaviour. The SystemSoundsLibrary package is the right tool for the narrower job of using a system sound, and the wrong tool for anything a user would notice missing.
Editorial conclusion
Adopt SystemSoundsLibrary when you need a device notification sound on iOS and want a typed name instead of a magic number, especially in a codebase that also targets tvOS, visionOS or Mac Catalyst. Do not treat its table as a contract, because Apple does not document these identifiers and the mappings were collected on iOS 7, so they may differ, be missing or be added on the versions you support. Do not reach for it when you need a custom or branded sound, since a system sound is not yours to ship. Before you ship, add the package at version 2.0.0 or later, play every sound you depend on on a real device because the Simulator does not play them, and check the iOS 26 and iOS 27 file lists in the README for the identifiers you use.
Frequently asked questions
How do I play an iOS system sound from Swift?
Import AudioToolbox and call AudioServicesPlaySystemSound with the identifier, for example AudioServicesPlaySystemSound(1003) for the SMS received sound. To play by file name, resolve a path under /System/Library/Audio/UISounds, create the sound identifier with AudioServicesCreateSystemSoundID and dispose of it in the completion handler.
How do I add the SystemSoundsLibrary package to a project?
Use File > Add Package Dependencies in Xcode, or add the dependency in Package.swift with the package url for TUNER88/iOSSystemSoundsLibrary from version 2.0.0. The API is a typed Swift 6 interface with availability for iOS 15 and later, tvOS, visionOS and Mac Catalyst.
Why does the demo app not play sounds in the iOS Simulator?
The README states that the iOS Simulator does not play system sounds, so the demo project has to be run on a real device. It enumerates the files in /System/Library/Audio/UISounds and plays each one when you tap it.
Are the system sound identifiers in iOSSystemSoundsLibrary official?
No. The README says Apple does not officially document these SystemSoundIDs or file names, that the mappings were collected on iOS 7, and that they may differ, be missing, or be added on other iOS versions, so you should test on the iOS versions you support.
What licence does iOSSystemSoundsLibrary use?
The project is MIT licensed, with a LICENSE file and a NOTICE file in the repository root. The package release is v2.0.0 from 2026-10-18, and the repository is not archived, with the last push on 2026-10-18.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tuner88-iossystemsoundslibrary)Was this useful?