Перейти к содержимому

Как хранить данные в с

  • автор:

Как хранить данные в программе?

Допустим, у меня есть программа, которая использует некоторые данные, такие как зависимость ускорения свободного падения от широты. Я создаю статический класс, со статическим словарём, в котором «вбиты» все эти данные. Является ли такой подход правильным и рациональным? Если нет, как лучше хранить данные в таком случае?

Отслеживать
задан 21 ноя 2016 в 14:02
91 1 1 серебряный знак 3 3 бронзовых знака

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

21 ноя 2016 в 14:09

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

21 ноя 2016 в 14:12
Если вам дан исчерпывающий ответ, отметьте его как верный (галка напротив выбранного ответа).
22 ноя 2016 в 5:56

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

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

Основная и самая весомая причина для этого — если вдруг у вас поменяются данные, а они зашиты (захардкоджены) в программу, то в случае изменения данных программу придется перекомпилировать. Если же данные хранятся отдельно, то их можно поменять тоже отдельно, без перекомпиляции программы.

Смотрите сами на характер ваших данных — если это преимущественно константы, т.е. значения по типу числа пи, ускорения свободного падения и т.д., то да, вероятно, имеет смысл объявить их в коде. Либо можно записать их в ресурсы программы, в этом случае они будут как бы отдельно, но вшиты в тело сборки (в бинарник ваш).

В противном случае вы можете хранить данные в XML-файле, в файле App.config, в простом текстовом или INI-файле, даже в реестре Windows, или в таблице (таблицах) базы данных (например, в SQLite).

Рекомендуемый способ — XML и App.config (тоже XML по сути), но вы вольны выбрать то, с чем вам проще и удобнее работать.

UPD. Уже после ответа отыскалась статья на Хабре, посвященная хранению настроек приложения.

Отслеживать
ответ дан 21 ноя 2016 в 14:13
BlackWitcher BlackWitcher
2,756 14 14 серебряных знаков 33 33 бронзовых знака

На первых порах подход хороший, и вам не нужно предусматривать заранее все возможные случаи. (Попытка учесть вообще всё на начальном этапе называется overengineering.)

Я бы всё же посоветовал использовать не статический класс, а экземпляр, доступный в статическом месте, потому что это позволит легче изменять код, если нужно (и не стоит практически ничего).

Возможные направления развития:

  1. У вас появятся разные планеты? Тогда у вас будут несколько таких классов, по одному для планеты.
  2. Вам нужно конфигурировать это на машине клиента? Тогда нужно будет считывать данные из конфигурационного файла.

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

Отслеживать
ответ дан 21 ноя 2016 в 14:12
207k 28 28 золотых знаков 293 293 серебряных знака 526 526 бронзовых знаков

Если по данными вы подразумеваете некоторые относительно постоянные физические величины и законы (относительно постоянные, потому что иногда вносятся уточнения в константы, да и законы иногда пересматривают, в истории науки примеров достаточно) то в принципе вы на правильном пути, но я делал немного иначе в проекте по моделированию вакуумных процессов.

  1. Статический класс по аналогии System.Math , это у вас уже есть.
  2. Константы задаются в виде свойств, не констант или полей, а именно свойств, почему станет понятно позже.
  3. Этот класс или набор классов, для логической группировки величин и законов, компилируются в виде отдельной библиотеки, которую подключаем к программе.

Теперь о константах заданных свойствами. На первый взгляд, разницы между константным свойством и константой нет, но это только на первый взгляд. Вспоминаем что свойство это метод, в случае с константами один, условно get . Это дает одно, но существенное преимущество. Константа при компиляции намертво встраивается в код в тех местах, где вы к ней обращаетесь. Поэтому даже если вы замените константу в библиотеке, то для того, чтобы она попала в код, использующий эту библиотеку, придется его повторно компилировать. В случае со свойствами перекомпиляция не потребуется, вы можете безболезненно заменить устаревшую библиотеку на обновленную, если сигнатуры публичных методов и список методов остались неизменными (список методов может быть расширен в новой версии). Т.о. у вас появляется возможность вносить уточнения в точность констант и алгоритмы вычисления величин, а также заменить константное свойство на вычисляемое, без необходимости пересобирать всю программу.

Вариант хранить подобные величины в БД или файле конфигурации конечно можно применить, но не думаю что давать пользователю возможность править физические законы будет хорошей идеей, особенно если последний плохо знаком с предметной областью.

Другие возможные варианты уже описаны в соседних ответах.

Хранение и получение параметров и других данных приложения

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

Важно отметить данные приложения: время существования данных приложения привязано к времени существования приложения. Если приложение удалено, все данные приложения будут потеряны в результате. Не используйте данные приложения для хранения пользовательских данных или каких-либо данных, которые пользователи могут воспринимать как ценные и незаменимые. Мы рекомендуем использовать библиотеки пользователя и Microsoft OneDrive для хранения таких сведений. Данные приложения идеально подходят для хранения пользовательских настроек, параметров и избранного для конкретного приложения.

Типы данных приложения

Существует два типа данных приложения: параметры и файлы.

Настройки

Используйте параметры для хранения параметров пользователя и сведений о состоянии приложения. API данных приложения позволяет легко создавать и извлекать параметры (мы рассмотрим некоторые примеры далее в этой статье).

Ниже приведены типы данных, которые можно использовать для параметров приложения:

  • UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double
  • Boolean
  • Char16, String
  • DateTime, TimeSpan
    • Для C#/.NET используйте: System.DateTimeOffset, System.TimeSpan

    Files

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

    Хранение данных приложения в хранилищах данных приложения

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

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

    Данные локального приложения

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

    Получение локального хранилища данных приложения

    Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; 

    Создание и извлечение простого локального параметра

    Чтобы создать или записать параметр, используйте свойство ApplicationDataContainer.Values для доступа к параметрам в контейнере localSettings , который мы получили на предыдущем шаге. В этом примере создается параметр с именем exampleSetting .

    // Simple setting localSettings.Values["exampleSetting"] = "Hello Windows"; 

    Чтобы получить этот параметр, используйте то же свойство ApplicationDataContainer.Values , которое использовалось для создания параметра. В этом примере показано, как получить только что созданный параметр.

    // Simple setting Object value = localSettings.Values["exampleSetting"]; 

    Создание и получение локального составного значения

    Чтобы создать или записать составное значение, создайте объект ApplicationDataCompositeValue . В этом примере создается составной параметр с именем exampleCompositeSetting и добавляется в localSettings контейнер.

    // Composite setting Windows.Storage.ApplicationDataCompositeValue composite = new Windows.Storage.ApplicationDataCompositeValue(); composite["intVal"] = 1; composite["strVal"] = "string"; localSettings.Values["exampleCompositeSetting"] = composite; 

    В этом примере показано, как получить только что созданное составное значение.

    // Composite setting Windows.Storage.ApplicationDataCompositeValue composite = (Windows.Storage.ApplicationDataCompositeValue)localSettings.Values["exampleCompositeSetting"]; if (composite == null) < // No data >else < // Access data in composite["intVal"] and composite["strVal"] >

    Создание и чтение локального файла

    Чтобы создать и обновить файл в локальном хранилище данных приложения, используйте API-интерфейсы файлов, такие как Windows.служба хранилища. служба хранилища Folder.CreateFileAsync и Windows.служба хранилища. FileIO.WriteTextAsync. В этом примере создается файл с именем dataFile.txt в контейнере localFolder и записывается текущая дата и время в файл. Значение ReplaceExisting из перечисления CreationCollisionOption указывает, чтобы заменить файл, если он уже существует.

    async void WriteTimestamp()

    Чтобы открыть и прочитать файл в локальном хранилище данных приложения, используйте API-интерфейсы файлов, такие как Windows.служба хранилища. служба хранилища Folder.GetFileAsync, Windows.служба хранилища. служба хранилища File.GetFileFromApplicationUriAsync и Windows.служба хранилища. FileIO.ReadTextAsync. В этом примере файл, dataFile.txt созданный на предыдущем шаге, считывает дату из файла. Дополнительные сведения о загрузке файлового ресурса из различных расположений см. в разделе «Загрузка файлового ресурса».

    async void ReadTimestamp() < try < StorageFile sampleFile = await localFolder.GetFileAsync("dataFile.txt"); String timestamp = await FileIO.ReadTextAsync(sampleFile); // Data is contained in timestamp >catch (Exception) < // Timestamp not found >> 

    Перемещаемые данные

    Перемещаемые данные и параметры больше не поддерживаются в Windows 11. Рекомендуемая замена — Служба приложений Azure. Служба приложений Azure широко поддерживается и хорошо описана. Это надежное решение, которое поддерживает сценарии с использованием разных платформ и экосистем, включая iOS, Android и интернет-решения.

    Следующая документация относится к Windows 10 версии 1909 и более низкой.

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

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

    Перемещаемые данные выполняются и не выполняются

    • Используйте роуминг для пользовательских настроек и настроек, ссылок и небольших файлов данных. Например, используйте роуминг для сохранения предпочтения цвета фона пользователя на всех устройствах.
    • Используйте перемещение, чтобы пользователи продолжали задачу на разных устройствах. Например, перемещайте данные приложения, такие как содержимое черновика электронной почты или недавно просматриваемую страницу в приложении чтения.
    • Обработайте событие DataChanged , обновив данные приложения. Это событие возникает, когда данные приложения только что завершили синхронизацию из облака.
    • Перемещайте ссылки на содержимое, а не необработанные данные. Например, перемещайте URL-адрес, а не содержимое веб-статьи.
    • Для важных параметров времени используйте параметр HighPriority, связанный сроумингом Параметры.
    • Не перемещайте данные приложения, относящиеся к устройству. Некоторые сведения имеют отношение только локально, например имя пути к локальному ресурсу файла. Если вы решите перемещать локальную информацию, убедитесь, что приложение может восстановиться, если сведения не действительны на дополнительном устройстве.
    • Не перемещайте большие наборы данных приложения. Существует ограничение на объем данных приложения, которые может перемещать приложение; используйте свойство Roaming служба хранилища Quota, чтобы получить это максимальное значение. Если приложение достигает этого ограничения, данные не могут перемещаться до тех пор, пока размер хранилища данных приложения больше не превышает предел. При разработке приложения рассмотрите, как поместить привязку к большим данным, чтобы не превышать предел. Например, если для сохранения игрового состояния требуется 10 КБ каждой из них, приложение может разрешить только 10 игр.
    • Не используйте роуминг для данных, основанных на мгновенной синхронизации. Windows не гарантирует мгновенной синхронизации; Перемещение может быть значительно отложено, если пользователь находится в автономном режиме или в сети с высокой задержкой. Убедитесь, что пользовательский интерфейс не зависит от мгновенной синхронизации.
    • Не используйте перемещение для часто изменяющихся данных. Например, если ваше приложение отслеживает часто изменяющиеся сведения, например положение в песне на секунду, не сохраняйте это как перемещаемые данные приложения. Вместо этого выберите менее частое представление, которое по-прежнему обеспечивает хороший пользовательский интерфейс, как и в настоящее время играющая песня.

    Предварительные требования для роуминга

    Любой пользователь может воспользоваться перемещаемыми данными приложения, если он использует учетную запись Майкрософт для входа на свое устройство. Однако пользователи и администраторы групповой политики могут отключить перемещаемые данные приложения на устройстве в любое время. Если пользователь принимает решение не использовать учетную запись Майкрософт или отключает возможности перемещения данных, он по-прежнему сможет использовать данные вашего приложения, но данные приложения будут локальными на каждом устройстве.

    Данные, сохраненные в PasswordVault, перемещаются, только если пользователь присвоил своему устройству статус доверенного. Если устройство не является доверенным, данные, защищенные в этом хранилище, не будут перемещаться.

    Разрешение конфликтов

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

    Когда записывать данные

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

    Чрезмерная защита использования

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

    Управление версиями

    Данные приложения могут использовать управление версиями для обновления одной структуры данных до другой. Номер версии отличается от версии приложения и может быть задан. Хотя и не применяется, настоятельно рекомендуется использовать дополнительные номера версий, так как нежелательные осложнения (включая потерю данных)могут возникнуть при попытке перейти на более низкий номер версии данных, представляющий новые данные.

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

    Тестирование и средства

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

    • Перемещаемые данные не превышают максимальный размер (см. сведения о роуминге служба хранилища Quota).
    • Файлы закрыты и освобождены должным образом.
    • Существует по крайней мере два устройства с одной и той же версией приложения.

    Регистрация для получения уведомления при изменении перемещаемых данных

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

    1. Зарегистрируйтесь для получения уведомления при изменении перемещаемых данных. Событие DataChanged уведомляет вас об изменении перемещаемых данных. Этот пример задает DataChangeHandler обработчик для изменения перемещаемых данных.
    void InitHandlers() < Windows.Storage.ApplicationData.Current.DataChanged += new TypedEventHandler(DataChangeHandler); > void DataChangeHandler(Windows.Storage.ApplicationData appData, object o) < // TODO: Refresh your data >
    Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings; Windows.Storage.StorageFolder roamingFolder = Windows.Storage.ApplicationData.Current.RoamingFolder; 

    Создание и получение параметров роуминга

    Используйте свойство ApplicationDataContainer.Values для доступа к параметрам в контейнере roamingSettings , который мы получили в предыдущем разделе. В этом примере создается простой параметр с именем exampleSetting composite и составным значением.

    // Simple setting roamingSettings.Values["exampleSetting"] = "Hello World"; // High Priority setting, for example, last page position in book reader app roamingSettings.values["HighPriority"] = "65"; // Composite setting Windows.Storage.ApplicationDataCompositeValue composite = new Windows.Storage.ApplicationDataCompositeValue(); composite["intVal"] = 1; composite["strVal"] = "string"; roamingSettings.Values["exampleCompositeSetting"] = composite; 

    В этом примере извлекаются только что созданные параметры.

    // Simple setting Object value = roamingSettings.Values["exampleSetting"]; // Composite setting Windows.Storage.ApplicationDataCompositeValue composite = (Windows.Storage.ApplicationDataCompositeValue)roamingSettings.Values["exampleCompositeSetting"]; if (composite == null) < // No data >else < // Access data in composite["intVal"] and composite["strVal"] >

    Создание и извлечение перемещаемых файлов

    Чтобы создать и обновить файл в хранилище данных перемещаемого приложения, используйте API-интерфейсы файлов, такие как Windows.служба хранилища. служба хранилища Folder.CreateFileAsync и Windows.служба хранилища. FileIO.WriteTextAsync. В этом примере создается файл с именем dataFile.txt в контейнере roamingFolder и записывается текущая дата и время в файл. Значение ReplaceExisting из перечисления CreationCollisionOption указывает, чтобы заменить файл, если он уже существует.

    async void WriteTimestamp()

    Чтобы открыть и прочитать файл в хранилище данных перемещаемого приложения, используйте API-интерфейсы файлов, такие как Windows.служба хранилища. служба хранилища Folder.GetFileAsync, Windows.служба хранилища. служба хранилища File.GetFileFromApplicationUriAsync и Windows.служба хранилища. FileIO.ReadTextAsync. В этом примере открывается dataFile.txt файл, созданный в предыдущем разделе, и считывается дата из файла. Дополнительные сведения о загрузке файлового ресурса из различных расположений см. в разделе «Загрузка файлового ресурса».

    async void ReadTimestamp() < try < StorageFile sampleFile = await roamingFolder.GetFileAsync("dataFile.txt"); String timestamp = await FileIO.ReadTextAsync(sampleFile); // Data is contained in timestamp >catch (Exception) < // Timestamp not found >> 

    Временные данные приложения

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

    Получение временного контейнера данных

    Используйте свойство ApplicationData.TemporaryFolder для получения файлов. Следующие шаги используют temporaryFolder переменную из этого шага.

    Windows.Storage.StorageFolder temporaryFolder = ApplicationData.Current.TemporaryFolder; 

    Создание и чтение временных файлов

    Чтобы создать и обновить файл во временном хранилище данных приложения, используйте API-интерфейсы файлов, такие как Windows.служба хранилища. служба хранилища Folder.CreateFileAsync и Windows.служба хранилища. FileIO.WriteTextAsync. В этом примере создается файл с именем dataFile.txt в контейнере temporaryFolder и записывается текущая дата и время в файл. Значение ReplaceExisting из перечисления CreationCollisionOption указывает, чтобы заменить файл, если он уже существует.

    async void WriteTimestamp()

    Чтобы открыть и прочитать файл во временном хранилище данных приложения, используйте API-интерфейсы файлов, такие как Windows.служба хранилища. служба хранилища Folder.GetFileAsync, Windows.служба хранилища. служба хранилища File.GetFileFromApplicationUriAsync и Windows.служба хранилища. FileIO.ReadTextAsync. В этом примере файл, dataFile.txt созданный на предыдущем шаге, считывает дату из файла. Дополнительные сведения о загрузке файлового ресурса из различных расположений см. в разделе «Загрузка файлового ресурса».

    async void ReadTimestamp() < try < StorageFile sampleFile = await temporaryFolder.GetFileAsync("dataFile.txt"); String timestamp = await FileIO.ReadTextAsync(sampleFile); // Data is contained in timestamp >catch (Exception) < // Timestamp not found >> 

    Упорядочение данных приложения с помощью контейнеров

    Для организации параметров и файлов данных приложения можно создавать контейнеры (представленные объектами ApplicationDataContainer ), а не работать непосредственно с каталогами. Контейнеры можно добавлять в локальные, перемещаемые и временные хранилища данных приложения. Контейнеры можно вложить до 32 уровней глубоко.

    Чтобы создать контейнер параметров, вызовите метод ApplicationDataContainer.CreateContainer . В этом примере создается локальный контейнер параметров с именем exampleContainer и добавляется параметр с именем exampleSetting . Значение Always из перечисления ApplicationDataCreateDisposition указывает, что контейнер создается, если он еще не существует.

    Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; // Setting in a container Windows.Storage.ApplicationDataContainer container = localSettings.CreateContainer("exampleContainer", Windows.Storage.ApplicationDataCreateDisposition.Always); if (localSettings.Containers.ContainsKey("exampleContainer"))

    Удаление параметров и контейнеров приложений

    Чтобы удалить простой параметр, который больше не требуется приложению, используйте ApplicationDataContainer Параметры. Удалить метод. В этом примере удаляется локальный exampleSetting параметр, созданный ранее.

    Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; // Delete simple setting localSettings.Values.Remove("exampleSetting"); 

    Чтобы удалить составной параметр, используйте метод ApplicationDataCompositeValue.Remove . В этом примере удаляется локальный exampleCompositeSetting составной параметр, созданный в предыдущем примере.

    Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; // Delete composite setting localSettings.Values.Remove("exampleCompositeSetting"); 

    Чтобы удалить контейнер, вызовите метод ApplicationDataContainer.DeleteContainer . В этом примере удаляется созданный ранее контейнер локальных exampleContainer параметров.

    Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; // Delete container localSettings.DeleteContainer("exampleContainer"); 

    Управление версиями данных приложения

    Связанные статьи

    • Windows.Storage.ApplicationData
    • Windows.Storage.ApplicationData.RoamingSettings
    • Windows.Storage.ApplicationData.RoamingFolder
    • Windows.Storage.ApplicationData.RoamingStorageQuota
    • Windows.Storage.ApplicationDataCompositeValue

    Хранение данных в полях типа ХранилищеЗначения

    В 1С:Предприятии 8 существует возможность хранения различных данных в полях типа ХранилищеЗначения . В этих полях могут храниться значения типа ХранилищеЗначения . Сам тип ХранилищеЗначения предназначен, прежде всего, для хранения значений различных типов в сериализованном виде, то есть в том виде, который позволяет записывать данные и потом восстанавливать их. В документации по встроенному языку в описании объектов возможность сериализации указывается отметкой «Сериализуется». Эти значения, а также значения примитивных типов, могут помещаться в хранилище значения и таким образом могут записываться в поля базы данных с типом ХранилищеЗначения . Важной особенностью хранилища значений является возможность хранения данных в сжатом виде. Это позволяет существенно сократить объем хранимой информации для больших объектов.

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

    Соответственно поля типа ХранилищеЗначения следует использовать только в тех случаях, когда это соответствует их назначению и технологическим особенностям.

    Одним из основных применений полей типа ХранилищеЗначения является хранение изображений и образов файлов. Для этого используются типа Картинка и ДвоичныеДанные . Это позволяет сохранять в базе данных фотографии сотрудников, документы созданные в различных форматах и т.д. При реализации хранения такой информации можно рекомендовать создавать структуры данных, которые обеспечат отдельное хранение этих полей от основной информации. Например, для хранения фотографий сотрудников можно реализовать отдельный справочник или регистр сведений, а не помещать поля типа ХранилищеЗначения в сами объекты, хранящие список физических лиц. Следует учитывать, что объекты (например, элементы справочника) считываются системой всегда целиком. Поэтому хранение больших объемов информации непосредственно в полях объектов может существенно замедлить работу системы.

    В полях типа ХранилищеЗначения допускается, например, хранение таблиц значений и структур. При этом в таблицах значений и структурах могут храниться любые типы данных, в том числе и ссылочные типы. Заметим, что в ХранилищеЗначения коллекция может быть помещена, если в ней содержатся только сериализуемые значения. Однако следует учитывать, что этот вариант хранения данных существенно отличается, от явного хранения значений в отдельных полях и от хранения информации в табличных частях или регистрах сведений. Система не будет поддерживать для таких полей ссылочную целостность, не будет обеспечивать поиск данных в запросах и т.д. Таким образом, хранение коллекций в таких полях нельзя применять для реализации существенных частей прикладного решения отвечающих за бизнес логику. Такое хранение может допускаться только для вспомогательных данных, не имеющих существенного значения для бизнес-логики прикладного решения, например, для хранения каких-либо настроек работы пользователей.

    Хотя в системе не существует явного ограничения на размер данных, хранящихся в полях типа ХранилищеЗначения , следует все-таки осмотрительно относиться к объемам хранимой информации. Следует учитывать, что помещение больших объемов в такие поля увеличивает общий объем информационной базы, и это будет негативно сказываться на работе системы при выполнении различных административных операций, таких как создание резервной копии базы данных. Например, при хранении образов файлов, можно рекомендовать хранить в таких полях данные, действительно необходимые в работе, но не использовать их для хранения больших объемов файлов, не используемых в решаемой прикладной задаче.

    Как хранить данные в iOS: UserDefaults, Keychain и сэндвичи

    Хранение данных — одна из самых ведущих тем в разработке. Очень важно уметь выбирать подходящий инструмент для разных ситуаций и знать, как хранить данные безопасно и максимально эффективно, не замедляя приложение. Старший iOS-разработчик red_mad_robot Аня Кочешкова рассказывает о механизмах хранения, способах работы с ними, а также плюсах и минусах каждого подхода.

    Зачем вообще хранить данные? Например, если нужно кешировать какую-то информацию для ускорения работы, работать в офлайн-режиме или сохранить пользовательские настройки. Выбор механизма зависит от поставленной задачи, объёма данных, которые нужно хранить, и множества других факторов. Данные можно хранить в UserDefaults, Keychain, Property Lists или же базах данных и NSCache.

    UserDefaults — для хранения пользовательских настроек и флагов.
    Keychain — для безопасного хранения данных.
    Property Lists — для хранения конфигурации приложения или его библиотек.
    Базы данных — для хранения большого объёма различных данных.
    NSCache — для хранения временных данных.

    А теперь подробнее: как работать с каждым инструментом, сколько хранятся данные и в чём плюсы и минусы каждого подхода.

    UserDefaults

    Что хранить

    Самый простой и часто используемый способ хранения данных — это UserDefaults. Данные хранятся в виде пары «ключ-значение», где значением может быть любой примитив: булевая переменная, строка или даже массив данных.

    Обычно в UserDefaults хранят небольшие объёмы данных: флаги, пользовательские настройки, иногда не очень объемный кеш. Не стоит хранить здесь большие объёмы данных — UserDefaults загружается при запуске приложения, и это может повлиять на время запуска.

    Работа с данными в UserDefaults потокобезопасна — то есть с ним можно работать из разных потоков.

    Жизненный цикл данных

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

    Работа с UserDefaults

    Самый простой способ — использовать UserDefaults.standard, без всяких оберток:

    let defaults = UserDefaults.standard

    Задать значение

    Чтобы задать значение, используется метод set:

    defaults.set(22, forKey: «userAge»)

    Считать значение

    Чтобы считать значение, можно использовать специфичные для типа методы чтения:

    let darkModeEnabled = defaults.bool(forKey: «darkModeEnabled»)

    let toggleStates = defaults.dictionary(forKey: «toggleStates»)

    Либо обобщающий геттер:

    let favoriteFruits = defaults.object(forKey: «favoriteFruits»)

    В отличие от остальных, этот метод вернет nil в случае, если по указанному ключу ничего не найдено. Специфичные для типа методы в этом случае вернут дефолтное значение, например, false в случае с bool или 0 в случае с integer.

    Сохранять кастомные объекты

    Можно сохранять и кастомные объекты. Для этого нужно архивировать их в тип Data:

    let user = User(name: "Swift Guide", age: 22) let encoder = JSONEncoder() if let encodedUser = try? encoder.encode(user)
    if let savedUserData = defaults.object(forKey: "user") as? Data < let decoder = JSONDecoder() if let savedUser = try? decoder.decode(User.self, from: savedUserData) < . >>

    Сохранение данных в файл

    У каждого приложения есть своя document-директория, где хранятся файлы приложения и кеш. Работа с файлами осуществляется через FileManager. Также можно хранить какие-то данные, которые не будут изменяться, в папке приложения. Это может быть json-файл, plist или, например, обычный текстовый файл.

    Работа с файлами

    Учтите, что потокобезопасность при работе с файлами вам придется обеспечивать самим.

    let folderURL = try FileManager.default.url( for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false ) let fileURL = folderURL.appendingPathComponent(documentName) . try data.write(to: fileURL)

    Property lists

    Что хранить

    Plist — это обычный XML-файл с данными, который, как правило, хранится в бандле приложения. Обычно нам приходится работать с файлом Info.plist, который содержит настройки приложения: идентификатор, версию, название, разрешения и прочее.

    Plist-файлы также использует, например, Firebase. Он хранит там конфигурацию Firebase-приложения. Хранить можно любые примитивные типы данных, такие как bool, string, массивы, словари и прочее. Кстати, в UserDefaults, о котором мы говорили выше, данные под капотом хранятся в plist-файле, только бинарного формата.

    Пример проперти-листа

    Жизненный цикл данных

    Данные, хранимые в проперти-листе, переживают перезапуск приложения. Но если вы хотите изменять их, нужно будет создать свой проперти-лист в document-папке приложения. Изменять данные, которые находятся в бандле вашего приложения, например в Info.plist, нельзя.

    Работа с Plists

    Получить доступ к данным проперти-листа можно через бандл, используя Bundle.main.

    Чтобы считать данные из стандартного Info.plist, можно вызвать Bundle.main.infoDictionary, а затем обратиться по необходимому ключу.

    Можно воспользоваться также таким API: object(forInfoDictionaryKey: «key»)

    Если же нужно считать данные из кастомного проперти-листа, можно получить его вот так:

     if let path = Bundle.main.path(forResource: name, ofType: “plist”), let xml = FileManager.default.contents(atPath: path)

    Keychain

    Что хранить

    Keychain использует шифрование и позволяет хранить данные безопасно. Обычно здесь сохраняют токены, пароли, сертификаты и другие конфиденциальные данные.

    Работа с данными в Keychain потокобезопасна

    Жизненный цикл данных

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

    Данные можно чистить, если того требует бизнес-логика. Например, если нужно сбросить логин пользователя при удалении приложения. Для этого существует несколько стратегий — к примеру, добавление уникального UUID к хранимым в Keychain ключам. Этот UUID, в свою очередь, хранится в UserDefaults и очищается при удалении приложения.

    Также можно реализовать логику очистки всего Keychain при первом запуске приложения, но это потребует довольно запутанной логики с флагами.

    Работа с Keychain

    У Keychain довольно сложное API, потому что приходится работать с типами из языка С, сложная и запутанная документация и конструкции. Поэтому обычно для работы с ним используются сторонние библиотеки, такие как KeychainAccess.

    Пример инициализации кейчейна:

    let keychain = Keychain(service: serviceName).accessibility(.whenUnlocked)

    Можно разносить Keychain в разные сервисы для удобства работы. Отдельным сервисом может быть, например, кейчейн-расширения приложения. Если расширению приложения нужно хранить данные в Keychain, можно вывести работу с ним в отдельный сервис, чтобы отделить кейчейн основного приложения от кейчейна расширения.

    Также можно задать стратегию доступа к данным. Например, whenUnlocked говорит о том, что данные можно будет считать, только если устройство разблокировано.

    Можно задать синхронизацию Keychain с iCloud. Она будет работать, если в настройках устройства синхронизация Keychain с iCloud включена:

    keychain.synchronizable(false)

    Чтение данных (на выходе тип Data):

    try keychain.getData(key)

    Запись и удаление:

    try keychain.set(data, key: key)

    try keychain.remove(key)

    NSCache

    Для кеширования данных в iOS есть механизм под названием NSCache.

    Что хранить

    В таком кеше хранятся данные, которые довольно долго получать, но не страшно потерять. Часто NSCache используется, например, для кеширования большого объёма картинок.

    Работа с данными в NSCache потокобезопасна.

    Жизненный цикл данных

    Данные хранятся в памяти (in-memory), а при выгрузке приложения из памяти — либо при её нехватке — удаляются. Также можно задать дополнительные правила очистки кеша в рамках сессии, о которой расскажем ниже.

    Работа с NSCache

    При создании нужно указать тип ключа и значения, например:

    let cache = NSCache()

    Сохраняем и достаём данные:

    let webImage = UIImage(named: "banner.png") cache.setObject(webImage, forKey: "banner") . let image = cache.object(forKey: "banner")

    Можно задать некоторые ограничения, например, максимальное число объектов в кеше: cache.countLimit = 10

    Размер кеша также можно отграничивать при помощи цены, а при сохранении объектов задавать цену каждого из них. Её можно ограничивать и задавать при сохранении объекта.

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

    cache.totalCostLimit = 50_000_000 // bytes . cache.setObject(webImage, forKey: "banner", cost: bannerData.count)

    Базы данных

    Базы данных бывают реляционными и нереляционными. В реляционных данные хранятся в формате таблиц, они связаны между собой. Пример такого языка работы с базами данных — SQL. Такие базы данных соответствуют требованиям ACID.

    ACID — это набор требований к базе данных, обеспечивающий наиболее надёжную и предсказуемую её работу. Сформулированы в конце 1970-х годов Джимом Греем, учёным в области теории вычислительных систем.

    1. Атомарность (Atomicity) — ни одна транзакция (один или несколько запросов к базе данных, объединённых в одну пачку) не будет зафиксирована частично. Либо выполняются все её подоперации, либо ни одной.
    2. Согласованность (Consistency) — транзакция должна быть валидной, а её результаты должны быть допустимыми.
    3. Изолированность (Isolation) — при выполнении транзакции параллельно выполняемые транзакции никак не должны влиять на её результат.
    4. Устойчивость (Durability) — в системе не должно быть сбоев, транзакция, которая помечена как выполненная, действительно должна быть выполнена.

    Для работы с такими базами данных используется язык запросов (query language), позволяющий описывать набор данных, который мы хотим получить.

    Нереляционные базы данных не имеют чёткой связи и структуры. В них может храниться множество различных документов, изображений, видео и т. д. Их также называют nosql.

    Они хорошо подходят для хранения больших объёмов информации, для быстрой разработки и тестирования гипотез.

    Существуют колончатые нереляционные базы данных, например системы аналитики, сбора метрик, крашлитика. Есть также документоориентированные базы данных, работающие с документами, например MongoDB.

    Такие базы данных соответствуют требованиям BASE.

    1. Базовая доступность (Basic Availability) — каждый запрос гарантированно завершится (успешно или безуспешно).
    2. Гибкое состояние (Soft State) — состояние системы может изменяться со временем, даже без ввода новых данных, для достижения согласования данных.
    3. Согласованность в конечном счёте (Eventual Consistency) — какое-то время данные могут быть рассогласованы, но приходят к согласованию через некоторое время.

    В iOS можно работать с разными системами управления базами данных (СУБД). Подробнее остановимся на трёх:

    1. Core Data — фреймворк от Apple, позволяющий работать с sql, xml-файлами, либо хранить данные в памяти.
    2. Realm — нереляционная кроссплатформенная СУБД.
    3. SQLite — СУБД для базы данных sql.

    Core Data

    Core Data — фреймворк, позволяющий взаимодействовать с различными хранилищами. Официальное решение от Apple.

    Работа с моделями данных происходит в графическом редакторе. Данные можно синхронизировать с iCloud. Как правило, используется как обертка над SQLite, но есть и другие типы хранилища.

    Core Data позволяет использовать четыре типа хранилища:

    • SQLite,
    • Binary,
    • In-Memory,
    • XML (только для MacOS).
    Структура: модель, контекст, контейнер

    Для понимания структуры важно знать, какую роль играют модель, контекст и контейнер.

    1. Модель — XML-файл, описывающий структуру данных.
    2. Контекст — менеджер транзакций.
    3. Контейнер — основной класс для работы с Core Data.
    Модель данных

    Модель данных хранится в файле с расширением .xcdatamodeld. По сути, это просто XML-файл, но его можно изменять в графическом редакторе Xcode. Модель описывает объекты, их свойства и связи между ними.

    Затем эти сущности превращаются в соответствующие классы, которые наследуются от NSManagedObject. Можно либо позволить Xcode сгенерировать их, либо создать свой собственный файл вручную.

    Контекст

    NSManagedObjectContext — по сути, менеджер транзакций. База данных может иметь несколько разных контекстов, по умолчанию используется viewContext. Также можно создавать контексты, которые выполняются в фоне (бэкграунд-контексты) для загрузки объёмных данных. У контекста есть методы save и rollback, позволяющие управлять транзакциями.

    Контейнер

    NSPersistentContainer — это основной класс, охватывающий работу с Core Data. В его обязанности входит загрузка модели данных, а также реагирование, если он не может её найти или отсутствуют классы для определенных сущностей. Обычно его инициализируют с именем файла модели, а затем вызывают loadPersistentStores для загрузки. Он имеет свойство viewContext.

    Правила удаления данных

    В модели можно задать стратегию удаления данных. Она указывает, что делать с данными, если их родительская сущность удаляется. К примеру, у вас есть категория рецептов «сэндвичи», а также список рецептов, принадлежащих ей, — то есть список рецептов сэндвичей.

    Что делать с рецептами, если удалили категорию?

    1. Nullify. Самая популярная стратегия. Связь между родителем и дочерним объектом удаляется, то есть в дочернем объекте вместо ссылки на родителя будет nil.
    2. No Action. Ничего не происходит. Дочерние объекты никак не уведомляются, а ссылка на родительский объект, который уже не существует, остаётся.
    3. Cascade. Все дочерние объекты удаляются, если удалён их родитель.
    4. Deny. При удалении объекта, имеющего связи с дочерними объектами, возникает ошибка.
    Работа с Core Data

    Все классы Core Data являются подклассами NSManagedObject. Это стандартные классы Swift с несколькими дополнительными аннотациями.

    Так выглядит модель:

    public class Transaction: NSManagedObject

    NSManaged — это специальная аннотация, которая позволяет Core Data работать со свойствами особым образом. Благодаря этому атрибуту Core Data может отслеживать изменения свойств объекта и, следовательно, знать, что необходимо сохранить.

    public lazy var persistentContainer: NSPersistentContainer = < let container = NSPersistentContainer(name: "DataModel") container.loadPersistentStores < description, error in if let error = error < fatalError("Unable to load persistent stores: \(error)") >> return container >()

    Для сохранения данных необходимо использовать контекст и по окончании вызвать метод save, а в случае ошибки — rollback, который откатит транзакцию:

    let context = persistentContainer.viewContext var person = Person(context: context) person.age = 32 if context.hasChanges < do < try context.save() >catch < context.rollback() >>

    Без вызова метода save данные не будут сохранены.

    Получение данных происходит при помощи запроса данных, который называется фетч-реквест. Ему можно задать фильтр, или предикат.

    NSPredicate — это метод фильтрации в мире Core Data. Но его нужно указать как строку специального формата. Если допустить ошибку, узнать об этом получится только при запуске приложения.

    let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "Content") fetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(Note.wasDeleted), NSNumber(value: false)) let allContentWithNames = try persistentContainer.viewContext.fetch(fetchRequest)

    Здесь используется функция #keyPath для обеспечения некоторой безопасности. Значения в процентах отмечают части строки, которые должны быть заменены значением. %K — зарезервировано для путей, а %@ — для объектов. Значение внутри %@ будет заключено в кавычки.

    Миграция данных

    Поскольку базы данных имеют строго определённую структуру, в соответствии с которой они сохраняют данные, если решить изменить свою модель (добавить, удалить, переименовать свойства в классах или добавить отношения), то будет нужно выполнить миграцию — то есть перенести на новую версию.

    К счастью, Core Data может обрабатывать множество изменений с помощью автоматической миграции.

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

    Многопоточность

    Контекст выполняет операции в том треде, в котором он был создан.

    У него есть функции perform и performAndWait, они потокобезопасны и их можно вызывать из других потоков. performAndWait работает синхронно и дожидается выполнения переданного в него блока.

    Но нужно помнить, что сабкласс NSManagedObject нельзя передавать между потоками.

    Чтобы создать бэкграунд-контекст, нужно вызвать let context = persistentContainer.newBackgroundContext (). Он инициализирует контекст с типом многопоточности — .privateQueueConcurrencyType.

    Ещё один способ выполнить операцию на бэкграунд-потоке — вызвать performBackgroundTask, который сам создаёт бекграунд-контекст:

    persistentContainer.performBackgroundTask

    Но он будет создавать новый контекст каждый раз, когда будет вызван.

    Realm

    Realm — это база данных для нескольких платформ. Если кратко, то это no-sql база данных для Android, iOS, Xamarin и JavaScript. У них есть backend, который позволяет синхронизировать данные из всех источников.

    Структура

    Realm — это объектная база данных. В отличие от Core Data, он обновляет объекты сразу. А ещё работает с объектами-моделями, которые являются сабклассами Object. И сам генерирует схему на основании этих классов.

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

    Существенный минус Realm в том, что он хранит данные только в своих типах. Там нет Enum, а значит, его нужно преобразовывать в String или Int. Optional необходимо преобразовать в RealmOptional, массивы — в List, обратные ссылки — в LinkedList.

    Работа с Realm
    class Dog: Object
    let newDog = Dog() newDog.name = "Earl" let realm = Realm() realm.write

    let dogs = Realm().objects(Dog)

    Миграция данных

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

    Но проблема Realm в том, что он не хранит схему отдельных версий — миграция происходит от текущего формата к самому новому.

    Многопоточность

    Realm потокобезопасен. Читать объекты можно из разных потоков, но модифицировать — лишь из одного. Нужно открыть транзакцию на запись и произвести изменения в ней.

    Объекты нельзя передавать между разными потоками.

    SQLite

    SQLite — это реляционная система управления базой данных, доступна по умолчанию на iOS. Как правило, используется, если нужны оптимизации на уровне запросов и работы с базой данных, которых нельзя достичь, используя Core Data. Можно использовать напрямую либо через различные обёртки.

    Работа с SQLite

    Открыть базу данных:

    func openDatabase() -> OpaquePointer? < var db: OpaquePointer? if sqlite3_open(dbPath, &db) == SQLITE_OK < return db >>

    Чтобы создать таблицу, вставить или удалить данные, придётся использовать чистый язык SQL-запросов.

     var statement: OpaquePointer? if sqlite3_prepare_v2(db, sqlString, -1, &statement, nil) == SQLITE_OK < if sqlite3_step(statement) == SQLITE_DONE < . >> sqlite3_finalize(statement)

    Здесь в качестве sqlString нужно передать запрос.

    Например, на создание таблицы:

    let createTableString = «CREATE TABLE Contact(Id INT PRIMARY KEY NOT NULL, Name CHAR(255));»

    let insertStatementString = «INSERT INTO Contact (Id, Name) VALUES (?, ?);»

    let queryStatementString = «SELECT * FROM Contact;»

    При вставке нужно связать поля с данными:

    if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK < let id: Int32 = 1 let name: NSString = "Ray" sqlite3_bind_int(insertStatement, 1, id) sqlite3_bind_text(insertStatement, 2, name.utf8String, -1, nil) if sqlite3_step(insertStatement) == SQLITE_DONE < . >> 

    При получении так же:

     if sqlite3_prepare_v2(db, queryStatementString, -1, &queryStatement, nil) == SQLITE_OK < if sqlite3_step(queryStatement) == SQLITE_ROW < let 0) guard let queryResultCol1 = sqlite3_column_text(queryStatement, 1) else < return >let name = String(cString: queryResultCol1) . > >
    Миграция данных

    Всю миграцию данных придется имплементировать самостоятельно, вручную. И точка.

    Многопоточность

    SQLite может быть собран как для однопоточного использования, так и для многопоточного.

    Проверить, есть ли многопоточность, можно через вызов sqlite3_threadsafe (): если он вернул 0, то это однопоточный SQLite.

    По умолчанию SQLite собран с поддержкой многопоточности.

    Есть два способа использования многопоточного SQLite:

    Итог

    Мы разобрали несколько способов хранения данных в iOS. Поговорили про UserDefaults, который подходит для хранения пользовательских настроек и флагов. Обсудили конфигурационные файлы Property list и работу с файлами в целом. Разобрались с тем, как безопасно хранить данные в Keychain, и с работой с кешем, для которой подходит NSCache.

    Но главное — детально разобрали несколько доступных на iOS баз данных:

    1. Кроссплатформенную Realm, известную своей быстрой работой и простым API.
    2. Нативную Core Data, которая удобна своим графическим интерфейсом моделей и разным типом хранилищ, что облегчает тестирование. Среди перечисленных — это самое удобное решение, рекомендуем именно его.
    3. И, наконец, SQLite, которая позволяет работать напрямую с языком SQL и не подтягивать в свой проект лишних тяжеловесных сторонних библиотек.

    А чем в своей работе пользуетесь вы? Делитесь в комментариях.

    Над материалом работали:

    • текст — Аня Кочешкова, Ника Черникова,
    • редактура — Виталик Балашов,
    • иллюстрации — Юля Ефимова.

    Делимся железной экспертизой от практик в нашем телеграм-канале red_mad_dev. А полезные видео складываем на одноимённом YouTube-канале. Присоединяйся!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *