Как управлять восстановлением государства приложения в приложениях Ios

Введение

Восстановление состояния является фундаментальной основой современной разработки iOS, которая напрямую влияет на то, как пользователи воспринимают надежность и полировки вашего приложения. Когда пользователь переключается на другое приложение, получает телефонный звонок или питание вниз устройство, они ожидают вернуться именно туда, где они остановились - не к пустому экрану или потерянной форме. Внедрение надлежащего восстановления состояния приложения обеспечивает эту непрерывность, уменьшая разочарование и создавая доверие. Помимо базового удобства пользователя, восстановление состояния также играет ключевую роль в поддержании бесшовного опыта после системного прекращения, например, когда iOS нуждается в восстановлении памяти. Без восстановления пользователи могут потерять несохраненную работу, навигационный контекст или частично выполненные задачи, что приводит к высоким показателям отказа. Эта статья предоставляет всеобъемлющее руководство по обработке восстановления состояния приложения в приложениях iOS, охватывающих подходы UIKit и SwiftUI, лучшие практики, общие подводные камни и практические стратегии для кода на уровне производства.

Понимание процесса восстановления государства

Ключевые концепции и обзор API

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

Реставрация на основе сцены в современной iOS

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

Осуществление охраны государства

Присвоение идентификаторов восстановления

Первым шагом к сохранению состояния является назначение идентификаторов восстановления каждому контроллеру просмотра, который вы хотите восстановить. Эти идентификаторы могут быть установлены в конструкторе интерфейса через поле Restoration ID или программно с использованием свойства . Например, контроллер просмотра настроек может иметь идентификатор . Идентификатор должен быть уникальным в контексте сцены или приложения, в зависимости от вашей архитектуры. UIKit использует идентификатор восстановления для создания иерархии объектов во время восстановления. Если идентификаторы отсутствуют или дублируются, восстановление не удастся или даст неправильные результаты. Хорошая практика заключается в определении идентификаторов восстановления как констант в выделенном числе или структуре.

Государство кодирования с помощью encodeRestorableState

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

override func encodeRestorableState(with coder: NSCoder) {
 super.encodeRestorableState(with: coder)
 coder.encode(selectedSegmentIndex, forKey: "selectedSegmentIndex")
 coder.encode(searchQuery, forKey: "searchQuery")
}

Сохранение государства приложения в приложении или делегате сцены

В дополнение к кодированию контроллера просмотра вы должны сообщить UIKit, следует ли сохранять состояние на уровне приложения или сцены. Для приложений, использующих жизненный цикл делегата приложения, реализовать и вернуть . Для приложений на основе сцены использовать метод делегата сцены , который несет легкую информацию о восстановлении. Тяжелый подъем — состояние контроллера полного просмотра — автоматически сохраняется UIKit, когда он кодирует всю иерархию восстановления. Однако вы можете настроить, какие метаданные хранятся путем реализации или эквивалент делегата сцены. Этот метод позволяет добавлять состояние приложения или состояние сцены в целом до того, как UIKit напишет архив.

Реализация государственной реставрации

Декодируемое государство с декодируемым государством

Когда приложение запускается и UIKit определяет, что должно произойти восстановление (на основе обратного значения или его аналога сцены), он восстанавливает иерархию контроллера просмотра с помощью раскадровки или программной инстанциации, затем вызывает на каждом восстанавливаемом контроллере просмотра. В этом методе вы читаете закодированные значения с помощью , и т. д. и применяете их для восстановления пользовательского интерфейса в его прежнее состояние. Всегда обрабатывайте отсутствующие ключи изящно — архив восстановления может быть неполным или из предыдущей версии приложения. Используйте необязательное связывание и обеспечивайте разумные по умолчанию.

override func decodeRestorableState(with coder: NSCoder) {
 super.decodeRestorableState(with: coder)
 selectedSegmentIndex = coder.decodeInteger(forKey: "selectedSegmentIndex")
 searchQuery = coder.decodeObject(forKey: "searchQuery") as? String ?? ""
}

Восстановление иерархии контроллера просмотра

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

Устойчивость обработки данных

Восстановление состояния может быть хрупким, когда зависимости данных меняются между запусками приложений. Например, пользователь мог перейти к детальному просмотру элемента, который позже был удален с сервера. Всегда подтверждайте, что восстановленное состояние все еще имеет смысл, прежде чем применять его. Если закодированные данные относятся к объекту модели, который больше не существует, вернитесь к состоянию по умолчанию — например, показывая пустой вид или свежий список. Аналогично, избегайте восстановления состояния, которое зависит от сетевых запросов или больших заборов базы данных, которые могут не завершиться вовремя. Вместо этого восстановите состояние заполнителя и асинхронно загрузите фактические данные. Используйте или , чтобы запустить эти обновления.

Продвинутые темы

Реставрация штата с помощью SwiftUI

SwiftUI предоставляет декларативную альтернативу восстановлению состояния UIKit. Ключевой API — это обертка свойств , которая автоматически сохраняет небольшие объемы данных на сцену в UserDefaults. Например, вы можете хранить выбранный индекс вкладок или поисковый термин. Для более сложного состояния SwiftUI интегрируется с протоколом и API . Используйте модификатор для обработки восстановления из операций передачи или системы. SwiftUI также поддерживает восстановление состояния для и автоматически, когда вы используете соответствующие идентификаторы. Однако имейте в виду, что восстановление состояния SwiftUI более ограничено, чем у UIKit — оно не автоматически сохраняет и восстанавливает иерархию контроллера полного обзора. Вы должны явно сохранять важное состояние, используя , или пользовательский уровень персистентности.

Восстановление в сложных иерархиях взглядов

Когда ваше приложение содержит вложенные разделенные виды, контроллеры просмотра страниц или контроллеры контейнеров, восстановление состояния становится более сложным. Каждый контроллер просмотра ребенка должен иметь свой собственный идентификатор восстановления и кодировать свое собственное состояние. Кроме того, родительский контейнер должен правильно управлять восстановлением своих детей. Например, должен реализовать для хранения индекса текущей страницы и использовать путь идентификатора восстановления для воссоздания заказанных детей. Аналогично, и автоматически обрабатывают восстановление своих контроллеров просмотра ребенка, если правильно назначены идентификаторы восстановления. Всегда тестируйте эти иерархии, принудительно устраняя приложение и перезапуска; используйте «Предупреждение о треггерной памяти» симулятора для имитации прекращения.

Асинхронная загрузка данных

Распространенной ловушкой является попытка восстановить состояние, зависящее от асинхронных данных, например, представление таблицы, которое показывало результаты сетевого запроса. Процесс восстановления происходит синхронно во время запуска, до того, как вызовы сети инициируются. Если вы попытаетесь заполнить контроллер просмотра сохраненными данными, которые еще не доступны, восстановление будет казаться неполным или пустым. Решение состоит в том, чтобы восстановить только метаданные , необходимые для переопределения данных (например, идентификатор последнего просматриваемого элемента или строку запроса). Затем в или , инициировать асинхронный вывод и обновление пользовательского интерфейса после поступления данных. Вы также можете объединить восстановление состояния с фоновыми задачами для предварительного нагрева кэша, но поддерживать пользовательский интерфейс отзывчивым.

Тестирование восстановления государства

Тщательное тестирование восстановления состояния необходимо, но часто упускается из виду. Самый простой способ тестирования - использовать симулятор iOS: запустить приложение, перейти в определенное состояние, нажать кнопку «Домой», затем остановить приложение от Xcode. Перезапустить приложение и проверить, что состояние восстановлено. Для более реалистичных сценариев включить опцию «Имитация предупреждения о памяти» в меню отладки симулятора, пока приложение находится в фоновом режиме. Это заставляет систему прекратить приложение, и при повторном запуске должно начаться восстановление состояния. Кроме того, тест с различными ориентациями устройства, многозадачностью, разделенными просмотрами и после перерывов, таких как телефонные звонки. Используйте журналы консоли для проверки предупреждений или ошибок, связанных с восстановлением, таких как отсутствующие идентификаторы восстановления.

Лучшие практики для восстановления сильного государства

Обычные подводные камни и как их избежать

Внешние ресурсы и дальнейшее чтение

For an in-depth understanding of UIKit’s state restoration, start with Apple’s official documentation on Preserving Your App’s UI. The WWDC 2014 session “State Restoration in Practice” covers many real-world scenarios. For SwiftUI-specific guidance, refer to the SceneStorage documentation. A comprehensive third-party tutorial can be found on Сайт Рэя Вендерлиха. Наконец, руководство по программированию контроллера просмотра Apple (архивировано, но все еще актуально) содержит подробные рекомендации по идентификаторам восстановления и процессу неархивирования.

Заключение

Восстановление состояния приложения не является дополнительной функцией — это ожидаемая часть хорошо продуманного приложения iOS. Пользователи вкладывают время в навигацию по вашему интерфейсу, заполнение форм и изучение контента; возможность беспрепятственно возобновлять этот опыт после перерыва напрямую влияет на удовлетворенность и удержание пользователей. Понимая API восстановления состояния UIKit, внедряя правильные идентификаторы восстановления, кодируя только необходимые данные и обрабатывая крайние случаи, такие как изменения данных и асинхронные операции, вы можете предоставить надежный опыт, который кажется надежным и отполированным. Независимо от того, поддерживаете ли вы устаревшее приложение UIKit или создаете новый интерфейс SwiftUI, принципы остаются теми же: предвидеть контекст пользователя, тщательно сохранять его и восстанавливать его изящно. При тщательном планировании и тщательном тестировании восстановление состояния становится естественной частью вашего рабочего процесса разработки, а не запоздалой мыслью.

Помните, что цель состоит не в том, чтобы воспроизвести каждый пиксель предыдущей сессии, а в том, чтобы воссоздать намерение пользователя . . Успешное восстановление состояния заставляет пользователя задуматься о том, действительно ли приложение когда-либо закрывалось — и это самый высокий комплимент.