Какие есть способы сохранения данных на устройстве?
В 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.
Шаги:
-
Объявить интерфейс в общем проекте.
-
Реализовать его в YourApp.Android и YourApp.iOS.
-
Зарегистрировать через [assembly: Dependency(typeof(YourService))].
-
Получить через 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 сохранение данных может быть реализовано множеством способов в зависимости от задачи: от хранения флагов и токенов до целых баз данных. Разработчику важно понимать, какие данные он сохраняет, насколько они критичны, и какие требования по безопасности и производительности к ним предъявляются.