Что нужно сделать, чтобы перейти на конкретный экран по диплинку из пуш-уведомления
Что проверяют
Доведёте ли вы данные из пуша до нужного экрана с учётом того, что приложение могли запустить с нуля и интерфейса в этот момент ещё нет. Вопрос про жизненный цикл, а не про парсинг ссылки.
Как отвечать
По шагам:
- маршрут кладут в полезную нагрузку своим ключом рядом с
aps, и он приходит вuserInfo: ссылкой или парой идентификаторов, второе надёжнее; - делегат центра уведомлений назначают внутри
application(_:didFinishLaunchingWithOptions:), до выхода из метода. Иначе тап, которым приложение и запустили, не доедет до обработчика; - тап обрабатывают в
userNotificationCenter(_:didReceive:withCompletionHandler:), показ уведомления в активном приложении вwillPresent; - из
userInfoсобирают типизированный маршрут, а не таскают строку по экранам: разбор отделён от навигации и тестируется без UI; - переход делает один владелец навигации, который знает текущий стек. Если окно ещё не построено, маршрут складывают в отложенное значение и применяют, когда корневой контроллер готов;
- в конце обязателен вызов
completionHandler().
// внутри userNotificationCenter(_:didReceive:withCompletionHandler:)
let info = response.notification.request.content.userInfo
if let route = Route(userInfo: info) {
router.handle(route)
}
done()Схема вида myapp:// из Info.plist нужна для переходов извне, а для ссылок из веба берут universal links с файлом apple-app-site-association.
Где спотыкаются
Навигируют прямо в делегате: достают корневой контроллер и пушат экран. При холодном старте корня ещё нет и переход теряется, а при повторном тапе экран открывается вторым слоем. Маршрут нужно буферизовать и отдавать одному владельцу стека.
Забывают про сцены. В приложении с UISceneDelegate открытие по ссылке приходит в scene(_:openURLContexts:) и scene(_:continue:), а одноимённые методы AppDelegate не вызываются вовсе. Отсюда истории про то, что «на прошлом проекте тот же код работал».
Проверяют только активное приложение. Сценариев три: активное, в фоне и полностью выгруженное, плюс тап по кнопке действия в уведомлении. Пути выполнения у них разные, и ломается обычно именно холодный старт.