I have a counter that plays a "tick" sound everytime its tapped. I tried the app on my physical device and the sound plays even when the phone is in silent mode. How do I make it stop playing the sound when the silent mode is on?
import AVFoundation
struct View1 : View {
@State var player : AVAudioPlayer?
var body: some View {
Button(action: {
playSound()
todoItem.count = 1
}) {
Image("CounterButton")
.resizable()
.scaledToFit()
.frame(width: 70, height: 70)
.foregroundColor(Color.white)
}
}
}
func playSound() {
guard let url = Bundle.main.url(forResource: "tick", 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)
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
CodePudding user response:
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
By setting the category to .playback
, you're specifically asking to not honor silent mode:
When using this category, your app audio continues with the Silent switch set to silent or when the screen locks. (The switch is called the Ring/Silent switch on iPhone.)
You almost certainly want .ambient
:
When you use this category, audio from other apps mixes with your audio. Screen locking and the Silent switch (on iPhone, the Ring/Silent switch) silence your audio.
Possibly you want the default, .soloAmbient
, in which case you don't even need to set the category.
Your audio is silenced by screen locking and by the Silent switch (called the Ring/Silent switch on iPhone). By default, using this category implies that your app’s audio is nonmixable—activating your session will interrupt any other audio sessions which are also nonmixable. To allow mixing, use the ambient category instead.
Note that you generally should not set the category and activate the session on every call to playSound()
. You should generally set the category once (often during program launch). Particularly if you're allowing mixing, you can also just activate the session one time. There's no need to activate it repeatedly. (In fact, calling .play()
already activates it for you, so you don't really need any of that AVAudioSession code.)
You also probably don't want to keep recreating the player. Just create it once, and you can use .play(atTime: 0)
to play the audio again.