media-play-system-sound-on-mac | ios-app-dev-memo
swift
@State var selectedSoundEffect: SoundEffect? = nil
SoundEffectPicker(selection: $selectedSoundEffect)
swift
import AudioToolbox
struct SoundEffect: Hashable {
let id: SystemSoundID
let name: String
func play() {
AudioServicesPlaySystemSoundWithCompletion(id, nil)
}
}
extension SoundEffect {
static let systemSoundEffects: [SoundEffect] = {
guard let systemSoundFiles = getSystemSoundFileEnumerator() else { return [] }
return systemSoundFiles.compactMap { item in
guard let url = item as? URL, let name = url.deletingPathExtension().pathComponents.last else { return nil }
var soundId: SystemSoundID = 0
AudioServicesCreateSystemSoundID(url as CFURL, &soundId)
return soundId > 0 ? SoundEffect(id: soundId, name: name) : nil
}.sorted(by: { $0.name.compare($1.name) == .orderedAscending })
}()
}
func getSystemSoundFileEnumerator() -> FileManager.DirectoryEnumerator? {
guard let libraryDirectory = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .systemDomainMask, true).first,
let soundsDirectory = NSURL(string: libraryDirectory)?.appendingPathComponent("Sounds"),
let soundFileEnumerator = FileManager.default.enumerator(at: soundsDirectory, includingPropertiesForKeys: nil) else { return nil }
return soundFileEnumerator
}
import SwiftUI
struct SoundEffectPicker: View {
@Binding var selection: SoundEffect?
var body: some View {
Picker(selection: $selection, label: Text("Sound:")) {
Text("None").tag(nil as SoundEffect?)
ForEach(SoundEffect.systemSoundEffects, id: \.self) { sound in
Text(sound.name).tag(sound as SoundEffect?)
}
}.onChange(of: selection) { _, sound in
sound?.play()
}
}
}
func applicationDidFinishLaunching(_: Notification) {
_ = SoundEffect.systemSoundEffects
}