How are some alarm apps such as Alarmy able to play a sound on iPhone when the app is in the background and the phone is on vibrate

前端 未结 2 1655
南旧
南旧 2021-02-12 17:34

I am working on app that can alert users for some critical things. I use local notifications to alert the user. On iOS, I find that the notifications will not ring if the phone

相关标签:
2条回答
  • 2021-02-12 18:13

    There are few methods to implement this kind of functionality.For reference I recommend this link.

    For actually playing the sound while the device’s ringer switch is set to vibrate

    First off make sure to include the audio background mode in the capabilities, in order to play audio in the background.

    Then,

    Swift 4

    do {
      try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: [.duckOthers, .defaultToSpeaker])
      try AVAudioSession.sharedInstance().setActive(true)
      UIApplication.shared.beginReceivingRemoteControlEvents()
    } catch {
      NSLog("Audio Session error: \(error)")
    }
    

    Here we set the shared audio session’s category to AVAudioSessionCategoryPlayAndRecord, so that we can play sound, while the device’s ringer switch is set to vibrate.

    The .duckOthers is specified to make other audio quieter, if there’s any mixable audio playing, so that our alarm can be heard. You can leave that out or use another option, if you prefer a different behavior.

    The .defaultToSpeaker is specified, so that the volume would go to the speaker, where it’ll be much louder and should wake up our user with ease.

    beginReceivingRemoteControlEvents makes it so that the app handles the remote control options, like the play/pause buttons on the lock screen, in order to make it easier for our user to mute their alarm, once they wake up.

    0 讨论(0)
  • 2021-02-12 18:20

    The way this can be done (I have implemented this in my app) is by starting an AVAudioPlayer and specifying a specific time to play. So:

    1. Enable background audio in the app capabilities.

    2. Start and audio session with .playback mode, and start a player at the time you like it to play:

      do {
            //set up audio session
            try AVAudioSession.sharedInstance().setCategory(.playback, options: [.defaultToSpeaker, .duckOthers])
            try AVAudioSession.sharedInstance().setActive(true)
      
            //Start AVAudioPlayer
            player.play(at: time) //time is a TimeInterval after which the audio will start
          }
          catch {
          ...
          }
      

    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).

    0 讨论(0)
提交回复
热议问题