Какое состояние будет при получении пуша от незапущенного приложения?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Состояние при получении пуша от незапущенного приложения в iOS
Когда приложение не запущено (т.е. не находится в памяти устройства и не выполняется), получение push-уведомления вызывает определенный sequence событий, который зависит от типа уведомления и действий пользователя.
Типы уведомлений и их влияние
Push-уведомления в iOS можно разделить на две категории:
- Стандартные (Notification) уведомления – содержат только данные для отображения в UI.
- Сил-уведомления (Silent Push Notifications) – содержат специальный ключ
content-available: 1и предназначены для обновления данных в приложении без показа пользователю.
Процесс обработки пуша для незапущенного приложения
1. Стандартное уведомление
Когда приложение не запущено, система iOS получает push, отображает его в виде баннера/алерта (если пользователь разрешил уведомления) и хранит его в своей внутренней очереди. Приложение не запускается автоматически.
Запуск происходит только если пользователь взаимодействует с уведомлением:
- Тап на баннер
- Выбор действия из быстрых действий (Quick Actions)
- Открытие из Notification Center
После тапа система:
- Запускает приложение (переходит в состояние
active) - Передает уведомление в метод
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)илиuserNotificationCenter(_:didReceive:)(если используется UNUserNotificationCenter)
Пример кода обработки:
// AppDelegate (старый подход)
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Обработка данных уведомления
print("Received push: \(userInfo)")
completionHandler(.newData)
}
// UNUserNotificationCenterDelegate (новый подход)
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Обработка действий пользователя
print("User interacted with push: \(userInfo)")
completionHandler()
}
}
2. Сил-уведомления (content-available: 1)
Для незапущенного приложения поведение отличается:
- Система iOS может запустить приложение в фоновом режиме для обработки уведомления.
- Приложение переходит в состояние
backgroundи получает ограниченное время (обычно ~30 секунд) для выполнения задач. - Уведомление не показывается пользователю, если не содержит
alert,sound,badge.
Однако есть критические ограничения:
- iOS не гарантирует запуск приложения для каждого силhttp://push-a (особенно если приложение часто использует фоновый режим).
- Система может отложить или игнорировать уведомление для сохранения энергии.
Пример силhttp://push-a:
{
"aps": {
"content-available": 1,
"sound": "",
"priority": 5
},
"custom_data": "refresh_content"
}
Состояние приложения при получении пуша
Если приложение полностью не запущено, его состояние изменяется следующим образом:
| Действие | Состояние приложения | Методы вызываются |
|---|---|---|
| Пуш получен системой | Not running | Нет |
| Пуш показан пользователю | Not running | Нет |
| Пользователь тапает на пуш | Not running → Active | application(_:willFinishLaunchingWithOptions:), application(_:didFinishLaunchingWithOptions:), затем методы обработки уведомлений |
| Сил-пуш с content-available | Not running → Background | application(_:didReceiveRemoteNotification:fetchCompletionHandler:) (если система решила запустить) |
Особенности и лучшие практики
- Незапущенное приложение не имеет контекста – все данные должны быть восстановлены из уведомления или сервера.
- Критично обрабатывать launch options – в
application(_:didFinishLaunchingWithOptions:)нужно проверять наличие уведомления:
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let remoteNotification = launchOptions?[.remoteNotification] as? [AnyHashable: Any] {
// Приложение запустилось по тапу на пуш
handlePushFromLaunch(remoteNotification)
}
return true
}
- Учитывать ограничения фонового режима – силhttp://push-ы для незапущенного приложения имеют низкий priority.
- Тестировать сценарии – важно тестировать получение пуша после:
- Перезагрузки устройства
- Force-close приложения (удаления из multitasking)
- Долгого времени без запуска
Проблемы и решения
Проблема: Приложение не запускается для силhttp://push-a после долгого времени без использования. Решение: Использовать Background App Refresh и правильно настраивать pushes с важными данными, комбинировать с local notifications для важных событий.
Проблема: Пользовательские данные не доступны при запуске из push. Решение: Минимально необходимые данные передавать в payload push-а, остальные загружать после запуска.
Таким образом, состояние при получении пуша от незапущенного приложения зависит от типа уведомления и действий пользователя. Система iOS стремится к энергоэффективности, поэтому автоматический запуск происходит только для силhttp://push-ов в оптимальных условиях, либо после явного взаимодействия пользователя с стандартным уведомлением.