В каком методе AppDelegate следует останавливать воспроизведение видео: applicationWillResignActive или applicationDidEnterBackground?

Ответ

Лучше использовать applicationWillResignActive.

Почему?

  • applicationWillResignActive вызывается немедленно при любом переходе приложения в неактивное состояние (входящий звонок, открытие Control Center, перетягивание шторки уведомлений). Это обеспечивает мгновенную реакцию.
  • applicationDidEnterBackground вызывается только после полного сворачивания приложения (пользователь нажал Home или переключил приложение). Между этими событиями может быть задержка, в течение которой видео продолжит воспроизводиться.

Пример реализации:

func applicationWillResignActive(_ application: UIApplication) {
    // Немедленная остановка при потере фокуса
    videoPlayer.pause()
}

func applicationDidBecomeActive(_ application: UIApplication) {
    // Возобновление, если приложение снова в фокусе
    if shouldResumePlayback {
        videoPlayer.play()
    }
}

Исключение: Если ваше приложение имеет право на воспроизведение аудио/видео в фоне (например, музыкальный плеер), логику паузы следует перенести в applicationDidEnterBackground и проверять тип контента.

Ответ 18+ 🔞

Да ты посмотри, какая дичь! Сидит человек, пишет приложение, а там видео на главном экране. И тут — бац! — звонок входящий. Или шторку уведомлений потянул. А видео-то, сука, продолжает играть! Звук из динамиков несётся, картинка мелькает. Позор на всю деревню, да? Пользователь уже трубку к уху подносит, а у него из телефона: «О, бля, смотри какая попа!».

Так вот, чтобы такого пиздеца не случилось, надо слушать не того сторожа, который спит на посту.

Есть у нас два таких сторожа в AppDelegate:

  1. applicationWillResignActive — это бдительный хуй. Как только приложение начинает терять фокус (звонок, шторка, даже запрос на Face ID), он сразу орёт: «Ёбта, тревога! Мы теряем контроль!».
  2. applicationDidEnterBackground — это уже запоздалый мудак. Он просыпается и докладывает только после того, как приложение уже полностью свернули в фон. А между «начали терять фокус» и «полностью свернули» может пройти секунда-другая. Целая вечность, блядь! За это время можно и опозориться, и косяк получить.

Вывод, пизда: чтобы остановить видео мгновенно, как только пользователь потянул шторку, надо вешать логику на первого сторожа, на applicationWillResignActive. Это железно.

Вот, смотри, как это выглядит в коде, тут всё просто:

func applicationWillResignActive(_ application: UIApplication) {
    // Как только фокус начал уплывать — хватаем видеоплеер за яйца и ставим на паузу.
    videoPlayer.pause()
}

func applicationDidBecomeActive(_ application: UIApplication) {
    // А когда приложение снова вылезло на передний план — можно и возобновить,
    // если, конечно, мы этого хотим.
    if shouldResumePlayback {
        videoPlayer.play()
    }
}

Но! Есть один нюанс, ёпта. Если твоё приложение — музыкальный плеер или подкастёр, и у него есть официальное право играть звук в фоне, то тут уже другая история. Тогда тебе надо быть умнее и перенести логику паузы в applicationDidEnterBackground, да ещё и проверить, а что, собственно, играет — фоновая музыка или стриминг порнухи. Первое можно не останавливать, а второе — лучше придушить нахуй сразу. Но это уже совсем другой разговор, про особые разрешения.

А для обычного приложения с видео — ставь на WillResignActive и спи спокойно. Никаких неожиданных звуков в самый неподходящий момент.