AppStorage и SceneStorage: сохранение данных в SwiftUI iOS 22.03.2022

В SwiftUI существует два способа сохранения небольших объектов данных между перезапусками приложения (@AppStorage и @SceneStorage). Например, настройки пользователя на уровне всего приложения или данные из регистрационной формы на уровне сцены (scene).

SceneStorage

Обертка @SceneStorage подходит для сохранения и восстановления состояния экрана между запусками приложения или для хранения небольших объемов данных в рамках отдельных экземпляров сцены приложения, например, приложение прерывается телефонным звонком или текстовым сообщением и помещает приложение на задний план.

Следующий код объявляет @SceneStorage переменную для хранения значения String с использованием comment как имя ключа, значением по умолчанию - пустая строка.

@SceneStorage("comment") var comment: String = ""

После объявления, переменную можно использоваться в сочетании с TextEditor следующим образом

var body: some View {
    TextEditor(text: $comment).padding()
}

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

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

AppStorage

Обертка @SceneStorage позволяет каждой отдельной сцене иметь собственную копию данных. Другими словами, данные, хранящиеся в одной сцене, недоступны для других сцен в приложении.

Обертка @AppStorage используется для хранения данных, которые доступны во всем приложении. Для этого используется UserDefaults которая уже много лет доступна в iOS. И позволяет сохранять пользовательские настройки по умолчанию (например, языковые настройки или выбор темы).

Обертка @AppStorage так использует строковую переменную для ключа.

@AppStorage("language") var language: String = ""

По умолчанию данные будут сохраненны в стандартном хранилище UserDefaults. Однако возможно указать App Group, в которой будут храниться данные.

Сохранение произвольного типа данных

Обертка @AppStorage и @SceneStorage позволяют сохранять значения только определенных типов. В частности, типы Bool, Int, Double, String, URL и Data. Это означает, что любой другой тип, который необходимо сохранить, должен быть сначала закодирован как Data для сохранения и последующего декодирования при извлечении.

Следующее пример демонстрирует объявление структуры и ее инициализацию

struct Movie {
    var title: String
    var year: Int
}

var cinema = Movie(title: "The Godfather", year: 1972)

Экземпляр должен быть закодирован и инкапсулирован в экземпляр Data, прежде чем его можно будет сохранить. Ключевым требованием является соответствие Encodable и Decodable протоколам или Codable.

struct Movie: Codable {
    var title: String
    var year: Int
}

Следующий примере использует JSON encoder для кодирования экземпляра cinema и его сохранения с помощью обертки @AppStorage.

@AppStorage("cinema") var cinemaStore: Data = Data()

let encoder = JSONEncoder()

if let data = try? encoder.encode(cinema) {
    cinemaStore = data
}

Для извлечения данных из хранилища используем JSON decoder.

let decoder = JSONDecoder()

if let movie = try? decoder.decode(Movie.self, from: cinemaStore) {
    cinema = movie
}
Цитата
Электронный мозг будет думать за нас точно так же, как электрический стул за нас умирает.
Станислав Ежи Лец
Категории
Архив