Как некоторые приложения для будильника, такие как Alarmy, могут воспроизводить звук на iPhone, когда приложение находится в фоновом режиме, а телефон вибрирует

Я работаю над приложением, которое может предупредить пользователей о некоторых важных вещах. Я использую локальные уведомления, чтобы предупредить пользователя. В iOS я обнаружил, что уведомления не будут звонить, если телефон вибрирует. Это решение для многих пользователей приложения, но я до сих пор задавал этот вопрос, так как я думал, что iOS не позволяет приложению воспроизводить звук, если приложение находится в фоновом режиме.

Музыкальные приложения могут воспроизводить песни, даже если телефон вибрирует, включив режим фонового звука, но он не позволяет вам планировать воспроизведение песни в определенное время.

В последнее время я видел, что некоторые приложения могут воспроизводить звук в определенное время, даже если приложение находится в фоновом режиме. Одним из таких приложений является приложение Alarmy alarm. Я не думаю, что они воспроизводят музыку через местное уведомление, когда истекает будильник, потому что музыка продолжает воспроизводиться даже после того, как я очистил уведомление. Из документации локального уведомления я понял, что я не могу запустить какой-либо код, когда локальное уведомление срабатывает, пока пользователь не нажмет на уведомление. Таким образом, я не могу запустить аудиоплеер, который может воспроизводить звук в вибрации.

Как такие приложения могут воспроизводить звук, даже если телефон находится на vibate, а приложение находится в фоновом режиме в iOS?

Ответ 1

Существует несколько методов для реализации такого рода функций. Для справки я рекомендую эту ссылку.

Для фактического воспроизведения звука, когда переключатель звонка устройства настроен на вибрацию

Во-первых, обязательно включите режим аудиофонов в возможностях, чтобы воспроизводить аудио в фоновом режиме.

Затем,

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)")
}

Здесь мы устанавливаем категорию общих аудиосеансов в AVAudioSessionCategoryPlayAndRecord, чтобы мы могли воспроизводить звук, в то время как переключатель звонков устройств настроен на вибрацию.

.................................................................. Вы можете оставить это или использовать другой вариант, если вы предпочитаете другое поведение.

Указатель.defaultToSpeaker указан, так что громкость будет поступать в динамик, где он будет намного громче и должен легко разбудить нашего пользователя.

beginReceivingRemoteControlEvents делает это так, чтобы приложение обрабатывало параметры удаленного управления, такие как кнопки воспроизведения/паузы на экране блокировки, чтобы облегчить для нашего пользователя отключение сигнала тревоги после их пробуждения.

Ответ 2

Это можно сделать (я реализовал это в своем приложении), запустив AVAudioPlayer и указав определенное время воспроизведения. Итак:

  1. Включить фоновый звук в возможностях приложения.

  2. Начните аудио-сеанс в режиме .playback и запустите проигрыватель в удобное для вас время:

    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 {
        ...
        }
    

Это не воспроизводит тишину в фоновом режиме, что нарушает правила Apple. На самом деле он запускает плеер, но звук запускается только в нужное время. Я думаю, что именно так Alarmy реализовал свою тревогу, учитывая, что это не удаленное уведомление, которое запускает звук, и при этом звук не воспроизводится локальным уведомлением (так как оно не ограничивается 30 секундами или отключается переключателем звонка).