Это Лекция 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 доступны на платной основе.