Play reminder sound SwiftUI
try this:
import AVFoundation
AudioServicesPlaySystemSound(1026)
where the number 1026 is the SystemSound id.
SwiftUI add sound effect when a button is pressed
from answer:
Play reminder sound SwiftUI
you can use this simple method:
import AVFoundation
AudioServicesPlaySystemSound(1026)
where the number 1026 is the SystemSound id.
How to play a sound using Swift?
Most preferably you might want to use AVFoundation.
It provides all the essentials for working with audiovisual media.
Update: Compatible with Swift 2, Swift 3 and Swift 4 as suggested by some of you in the comments.
Swift 2.3
import AVFoundation
var player: AVAudioPlayer?
func playSound() {
let url = NSBundle.mainBundle().URLForResource("soundName", withExtension: "mp3")!
do {
player = try AVAudioPlayer(contentsOfURL: url)
guard let player = player else { return }
player.prepareToPlay()
player.play()
} catch let error as NSError {
print(error.description)
}
}
Swift 3
import AVFoundation
var player: AVAudioPlayer?
func playSound() {
guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
let player = try AVAudioPlayer(contentsOf: url)
player.play()
} catch let error {
print(error.localizedDescription)
}
}
Swift 4 (iOS 13 compatible)
import AVFoundation
var player: AVAudioPlayer?
func playSound() {
guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
/* The following line is required for the player to work on iOS 11. Change the file type accordingly*/
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
/* iOS 10 and earlier require the following line:
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
Make sure to change the name of your tune as well as the extension.
The file needs to be properly imported (Project Build Phases
>Copy Bundle Resources
). You might want to place it inassets.xcassets
for
greater convenience.
For short sound files you might want to go for non-compressed audio formats such as .wav
since they have the best quality and a low cpu impact. The higher disk-space consumption should not be a big deal for short sound files. The longer the files are, you might want to go for a compressed format such as .mp3
etc. pp. Check the compatible audio formats of CoreAudio
.
Fun-fact: There are neat little libraries which make playing sounds even easier. :)
For example: SwiftySound
Local notification sound not playing while app in background - Swift
So I've discovered something.
As the question is stated, it is not currently possible to play sound in a local notification when the phone is on silent mode.
However, great news!
There is actually a different way to achieve the same result; and it's how apps like Alarmy do it.
Note: I (FINALLY) discovered this solution from this wonderful SO answer, but I'll summarize it here for reference.
In short, the local notification will not be playing the sound, but instead, the app will play it (while in the background).
STEPS
You must enable the app to play sound in the background. To do this, navigate to your
.plist
file and add the String valueApp plays audio or streams audio/video using AirPlay
to the array keyRequired background modes
. (This can also be achieved in your app'sCapabilities
- it does the same thing).In your App Delegate, set your AVAudioSession's category to
.playBack
so sound will still play even when the phone is locked or in the background.
do {
try AVAudioSession.sharedInstance().setCategory(.playAndRecord)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error.localizedDescription)
}
- Start your AVAudioPlayer at the time you would like it to play (in my case, at the time of my local notification).
let timeInterval = 60.0 // 60.0 would represent 1 minute from now
let timeOffset = audioPlayer.deviceCurrentTime + timeInverval
audioPlayer.play(atTime: timeOffset) // This is the magic function
// Note: the `timeInterval` must be added to the audio player's
// `.deviceCurrentTime` to calculate a correct `timeOffset` value.
In conclusion, as the SO answer I linked to above so aptly summarizes:
This does not play silence in the background, which violates Apple's rules. It actually starts the player, but the audio will only start at the right time. I think this is probably how Alarmy implemented their alarm, given that it's not a remote notification that triggers the audio nor is the audio played by a local notification (as its not limited to 30 seconds or silenced by the ringer switch).
Related Topics
How to Add a Show More/Show Less Uibutton to Control Uitextview
Adding Index List and Section Headers to Translated Tableview
How to Restrict an Enum to Certain Cases of Another Enum
Swift: Differencebetween a Typealias and an Associatedtype with a Value in a Protocol
Xcframework Issue, a Library with the Identifier "Ios-Armv7_Arm64" Already Exists
Generic Within a Generic in Swift
Saving a Codable Struct to Userdefaults with Swift
Playing Hls (M3U8) in Cocoa Os X Avplayer - Swift
How to Check If Dark Appearance Is Enabled Tvos
Swift Vscode Class in Other File Not Recognized
Saving Coredata to a Web Server with Swift 3.0
Adding Animation to Tabviews in Swiftui When Switching Between Tabs
How to Switch to Swift 4.0 in Xcode 9.3
Behaviour of Protocols with Self
Using Decodable with Inheritance Raises an Exception
Swift- How to Display Image Over Button