Когда вызывается `applicationWillTerminate(_:)` в iOS?

Ответ

Метод applicationWillTerminate(_:) делегата приложения вызывается, когда система полностью завершает работу приложения, а не просто переводит его в фоновый режим.

Типичные сценарии вызова:

  • Пользователь убивает приложение из списка многозадачности.
  • Система завершает приложение для освобождения ресурсов, и оно не находилось в приостановленном (suspended) состоянии.

Когда метод НЕ вызывается:

  • При переходе в фоновый режим (для этого есть applicationDidEnterBackground).
  • При падении (crash) приложения.
  • При принудительном завершении (force kill) из Xcode или во время отладки.
  • При перезагрузке устройства.

Ограничения и best practices:

  • На выполнение метода дается примерно 5 секунд. По истечении этого времени процесс убивается.
  • В современных iOS (начиная с ~iOS 13) система редко вызывает этот метод, предпочитая приостанавливать приложения. Не полагайтесь на него для критически важных операций.
  • Для гарантированного сохранения состояния используйте applicationDidEnterBackground(_:).

Пример использования:

func applicationWillTerminate(_ application: UIApplication) {
    // Сохранение последних изменений данных пользователя
    DataManager.shared.saveContext()
    // Закрытие сетевых соединений
    NetworkClient.shared.cleanup()
}

Ответ 18+ 🔞

А, слушай, вот этот твой applicationWillTerminate(_:) — это как последний звонок, когда тебя уже нахуй выгоняют из школы насовсем, а не просто на перемену. Система тебе говорит: «Всё, браток, концерт окончен, занавес».

Типичные сценарии, когда тебе позвонят и скажут «пиздуй»:

  • Пользователь сам, своими кривыми пальцами, вышвырнул твоё приложение из списка запущенных.
  • Система, такая вся из себя рациональная, решила освободить память, и твоё приложение в этот момент не спало как сурок (то есть не было в suspended).

А вот когда этот звонок НЕ прозвенит, и ты останешься в дураках:

  • Когда приложение просто ушло в фон (для этого есть другой чел — applicationDidEnterBackground).
  • Если приложение накрылось медным тазом и упало.
  • Если ты его придушил в дебаггере Xcode.
  • При перезагрузке айфона — там всем скопом и без церемоний.

Важные нюансы, чтобы не обосраться:

  • Тебе дают примерно 5 секунд на все прощальные дела. Не успел — процесс просто пристрелят на месте. Никаких «ой, я ещё не сохранил».
  • В современных iOS, ёпта, этот метод вызывают реже, чем честного политика. Система любит приложения просто замораживать. Так что не строй на нём всю свою логику спасения мира.
  • Для гарантированного сохранения всякой хуйни — юзай applicationDidEnterBackground(_:). Вот это надёжный мужик.

Пример, как не опозориться в последний момент:

func applicationWillTerminate(_ application: UIApplication) {
    // Срочно пишем все данные пользователя, а то он потом придёт и устроит срач
    DataManager.shared.saveContext()
    // Обрываем все свои долгие соединения, чтобы не висеть как маньяк на проводе
    NetworkClient.shared.cleanup()
}

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