Лекция 11. Постоянное хранение (Persistence). Обработка ошибок. CS193P Spring 2021.

Это Лекция 11 курса Stanford CS193p, весна 2021 года.

Главная тема этой Лекции — «постоянное хранение» (Persistence), то есть хранение данных в файловой системе и других местах на самом устройстве и в iCloud. Теме «постоянного хранения» сопутствуют еще две важные темы. Это формат хранения данных (самым распространенным форматом является JSON формат) и обработка ошибок, ибо операции ввода/ вывода типа записи на диск или считывания с диска, сопутствующие «постоянному хранению» (Persistence), порождают достаточное количество возможных фатальных ошибок, требующих обработки. Что касается JSON формата, то в Swift существует очень мощный Codable механизм, который позволяет практически любую структуру struct или перечисление enum превратить в  Blob данных в формате JSON.

Все 3 темы — «постоянное хранение» (Persistence), обработка ошибок  и механизм Codable — сначала рассматриваются теоретически, а затем и в демонстрационном примере.

Обработка ошибок

В Swift  вы увидите ряд функций, которые помечены ключевым словом throws. Это означает, что при их вызове они могут «выбросить» ошибку. Такое происходит только с фатальными ошибками, с которыми вызываемая вами  функция действительно не знает, как поступить. Она “выбрасывает” эту ошибку вам, a вы можете её “поймать” catch и разобраться, что с ней можно сделать. Когда вы вызываете “выбрасывающую” ошибки функцию, главное — это дать знать Swift, что вам известно, что эта функция может “выбрасывать” throws  ошибки. Вы делаете это с помощью ключевого слова try.

Есть 3 способа сказать try и не обрабатывать «выброшенную» ошибку, а передать её на более высокий уровень или вовсе проигнорировать её. То есть по сути сообщить, что вы не собираетесь иметь дело с “выброшенной” ошибкой:

  • Первый, наверное, самый распространенный способ — это использовать try?. Второй способ — использование try!.
  • Третий вариант — “перевыбросить” (rethrow) ошибку дальше по цепочке вызовов. Вы просто пишите try без восклицательного ! или вопросительного ? знаков. Но это работает только внутри функции func, которая сама “выбрасывает” throws ошибки.

Но иногда мы действительно хотим обрабатывать “выброшенные” ошибки и хотим с ними что-то делать. В этом случае мы “заворачиваем” наш код с try в do { } catch { } блок.

Все эти варианты try в огромном количестве исследуются в демонстрационном примере.

Постоянное хранение (Persistence) в iOS.

Сначала дается обзор всех возможных систем постоянного хранения (Persistence) в iOS: 

  • В файловой системе (FileManager).
  • В SQL базе данных (Core Data для OOP доступа или даже прямым вызовом SQL). 
  • iCloud (взаимодействует с двумя вышеуказанными).
  • Cloud Kit (база данных в “облаках”).
  • Множество сторонних возможностей хранения также присутствует.
  • UserDefaults Простая. Ограниченная (только Property Lists). Очень небольшая по объему.

На этой Лекции очень подробно рассматривается файловая система:  «Песочница» (Sandbox), FileManager, URL, и «древнее» ещё до-Swift эпохи «легковесное» хранилище UserDefaults. В демонстрационном примере файловая система используется для хранения EmojiArt документа, а UserDefaults — для хранения списка палитр PaletteStore. В обоих случаях используется преобразование данных в JSON формат с помощью Codable механизма. 

Codable

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

Крутая часть протокола Codable состоит в том, что если в какой-то структуре struct все переменные var сами являются Codable, Swift автоматически реализует протокол Codable для всей вашей структуры  struct

Буквально все, что вам нужно сделать, это разместить :Codable в  строке объявления структуры struct, и у вас будет полностью Codable структура struct. Иногда вам придется зайти внутрь структуры struct, в которой могут быть подструктуры struct внутри вашей структуры struct и внутри подструктуры struct могут быть другие подструктуры struct. Вы должны все их пометить  :Codable. Если все они являются Codable, то вам вообще больше ничего не надо делать, но теперь ваша структура  struct является Codable и Swift сможет превратить эту структуру в Blob JSON формата и записать ее в файловую систему или в UserDefaults. Это так называемое «волшебство» Codable.

Кстати, если у вас есть перечисление enum, то Swift делает это всё и для перечислений enum, но но только начиная с версии Swift 5.5, а если у вас версия ниже Swift 5.5 (как для курса iOS 14) и ваши перечисления enum имеют ассоциированные значения (associated values), то вам придется делать это вручную. В демонстрационном примере профессор детально показывает, как это делается.  На это стоит посмотреть в любом случае, если вдруг вам придется это делать для вашей нестандартной структуры данных.

 Рассматривается вариант оптимального автосохранения EmojiArtDocument.

Лекция 11 — длинная, её длительность почти 2 часа. Все темы рассматриваются очень тщательно с оригинальными экспериментами в коде, но это потребует от вас также следовать этим экспериментам, иначе не удастся оценить оригинальность и красоту решений.

Код демонстрационного примера для Лекции 11 находится на Github для iOS 14 в папке  EmojiArtL11.

Русскоязычный неавторизованный конспект Лекции 11, иллюстрированный, хронометрированный и представленный в виде PDF-файла, который можно скачать и использовать offline, а также в формате Google Doc доступны на платной основе.