Какие есть способы сохранения данных на устройстве?

В Xamarin.Forms существует несколько способов локального сохранения данных на устройстве. Выбор подхода зависит от типа данных (например, простые настройки или сложные структуры), требований к безопасности, частоте доступа, объёму информации и необходимости синхронизации с сервером. Основные подходы включают использование Preferences, FileSystem, SQLite, SecureStorage, а также сторонних библиотек.

1. Preferences (Xamarin.Essentials)

Позволяет сохранять и извлекать небольшие пары "ключ-значение", аналогично SharedPreferences в Android и NSUserDefaults в iOS. Подходит для хранения простых настроек: токенов, флагов, логинов.

Установка:

Подключите Xamarin.Essentials (обычно уже есть в проекте).

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

using Xamarin.Essentials;
// Сохранение значения
Preferences.Set("username", "alex123");
// Чтение значения
string username = Preferences.Get("username", "default_user");
// Удаление
Preferences.Remove("username");
Preferences.Clear(); // Удалить всё

Особенности:

  • Доступно во всех проектах Xamarin.Forms.

  • Персистентно — данные сохраняются между сессиями.

  • Не предназначено для хранения больших объёмов или чувствительных данных.

2. SecureStorage (Xamarin.Essentials)

Используется для хранения конфиденциальной информации, такой как токены, пароли, ключи. Реализует безопасное хранилище через нативные механизмы:

  • Android — Keystore

  • iOS — Keychain

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

using Xamarin.Essentials;
// Сохранение
await SecureStorage.SetAsync("token", "abc123");
// Чтение
string token = await SecureStorage.GetAsync("token");
// Удаление (не напрямую, можно перезаписать null или использовать Preferences как флаг)

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

  • На Android требует включения защиты (PIN/FaceID) и API 23+.

  • Может выбрасывать FeatureNotSupportedException или InvalidOperationException.

3. Файловая система (File Storage)

Позволяет сохранять данные в виде текстовых, JSON, бинарных файлов. Полезно для хранения структурированных данных, кэша, логов и пользовательских документов.

Получение пути к файлу:

string fileName = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "notes.txt");

Запись и чтение:

// Запись
File.WriteAllText(fileName, "Hello, Xamarin!");
// Чтение
string content = File.ReadAllText(fileName);

Для бинарных данных:

File.WriteAllBytes(fileName, byteArray);
byte\[\] bytes = File.ReadAllBytes(fileName);

Особенности:

  • Можно сохранять любые данные: изображения, JSON, сериализованные объекты.

  • Не безопасно без дополнительного шифрования.

  • Подходит для больших объёмов и офлайн-доступа.

4. SQLite

Наиболее мощный способ хранения структурированных данных. SQLite — встраиваемая СУБД, которая работает прямо в приложении. Поддерживает запросы SQL, индексы, фильтрацию, сортировку.

Установка:

Добавьте NuGet-пакет: sqlite-net-pcl

Создание модели:

public class Note
{
\[PrimaryKey, AutoIncrement\]
public int Id { get; set; }
public string Text { get; set; }
public DateTime Created { get; set; }
}

Создание базы данных и таблицы:

string dbPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "notes.db3");
var db = new SQLiteConnection(dbPath);
db.CreateTable<Note>();

CRUD-операции:

// Добавление
db.Insert(new Note { Text = "Пример", Created = DateTime.Now });
// Чтение
List<Note> notes = db.Table<Note>().ToList();
// Обновление
var note = db.Get<Note>(1);
note.Text = "Обновлено";
db.Update(note);
// Удаление
db.Delete(note);

Особенности:

  • Быстрый доступ к большим объёмам структурированных данных.

  • Хорошо интегрируется с MVVM.

  • Требует сериализации/моделей.

  • Можно использовать SQLiteAsyncConnection для асинхронной работы.

5. Serializing (JSON/XML) в файлы

Для хранения сложных объектов, можно сериализовать их в JSON и сохранить как текст.

Пример:

var note = new Note { Id = 1, Text = "Пример", Created = DateTime.Now };
string json = JsonConvert.SerializeObject(note);
// Запись
File.WriteAllText(fileName, json);
// Чтение
string jsonFromFile = File.ReadAllText(fileName);
Note loadedNote = JsonConvert.DeserializeObject<Note>(jsonFromFile);

Особенности:

  • Гибкий способ сохранить произвольные объекты.

  • Требует Newtonsoft.Json или System.Text.Json.

  • Не даёт преимуществ реляционной базы (запросы, индексы и т.д.).

6. Settings Plugin (актуально до Xamarin.Essentials)

Ранее использовался плагин [Xam.Plugin.Settings] для кросс-платформенного доступа к настройкам. Сейчас заменён Xamarin.Essentials.Preferences.

var settings = CrossSettings.Current;
settings.AddOrUpdateValue("email", "test@mail.com");
var email = settings.GetValueOrDefault("email", "");

7. DependencyService и нативное хранилище

Если нужно использовать специфические API каждой платформы (например, Room в Android или NSUserDefaults в iOS), можно создать интерфейс и реализовать его на каждой платформе с помощью DependencyService.

Шаги:

  1. Объявить интерфейс в общем проекте.

  2. Реализовать его в YourApp.Android и YourApp.iOS.

  3. Зарегистрировать через [assembly: Dependency(typeof(YourService))].

  4. Получить через DependencyService.Get<IYourService>().

Этот способ даёт полный контроль, но требует знания нативных SDK.

8. Пути к хранилищам в Xamarin.Forms

Категория Метод получения пути Особенности
Local (только приложение) Environment.SpecialFolder.LocalApplicationData Не синхронизируется, защищено
--- --- ---
Cache Environment.SpecialFolder.Personal или FileSystem.CacheDirectory Может быть очищено системой
--- --- ---
Shared (Android) ExternalStoragePublicDirectory (только Android) Требует разрешения
--- --- ---

9. Безопасность при хранении

  • Никогда не храните токены/пароли в Preferences или File.WriteAllText.

  • Используйте SecureStorage для любых конфиденциальных данных.

  • Для SQLite или JSON можно применить шифрование: AES, SQLCipher и т.п.

  • Не забывайте про Permissions (Android 11+ может требовать MANAGE_EXTERNAL_STORAGE).

Сравнение методов

Метод Тип данных Размер Безопасность Простота Использование
Preferences Простые ключ-значение 🔹 Настройки
--- --- --- --- --- ---
SecureStorage Ключ-значение (секрет) 🔹 Токены, логины
--- --- --- --- --- ---
FileSystem Любые файлы 🔸 ❌/условная Кэш, документы
--- --- --- --- --- ---
SQLite Структурированные 🔸🔸 ❌/шифруется ⚠️ Записи, справочники
--- --- --- --- --- ---
JSON/XML Сложные объекты 🔸 ⚠️ Пользовательские настройки
--- --- --- --- --- ---
DependencyService Любые (платформенные) 🔸 зависит ⚠️ Спец. сценарии
--- --- --- --- --- ---

В Xamarin.Forms сохранение данных может быть реализовано множеством способов в зависимости от задачи: от хранения флагов и токенов до целых баз данных. Разработчику важно понимать, какие данные он сохраняет, насколько они критичны, и какие требования по безопасности и производительности к ним предъявляются.