SwiftData дебютировал на WWDC 2023 в качестве замены фреймворка Core Data. и обеспечивает постоянное хранение данных на Apple устройствах,  беспрепятственную синхронизацию с облаком iCloud, Весь API SwiftData построен вокруг современного Swift. SwiftData является частью iOS 17 и на момент написания этой статьи действует версия Xcode 15.0 В SwiftData, в отличие от своего предшественника, базы данных Core Data, очень просто создать Схему (или Модель Данных) для постоянного хранения информации в вашем приложении. Для этого  прямо в коде создаются обычные Swift  классы class со свойствами, имеющими обычные базовые Swift ТИПы , Codable ТИПы  или другие Swift  классы  Схемы.  Вы также можете использовать как Optional ТИПы, так и НЕ-Optional. Чтобы превратить эти обычные Swift классы в постоянно хранимые объекты, Apple дала нам "волшебную палочку" в виде макросов,  самым главным из которых является макрос @Model.    Если вы пометите макросом @Modelобычные  Swift классы, то  получите не только  постоянно хранимые объекты, но и сделаете их Observable, Hashable и Identifiable, и вам не нужно предпринимать никаких дополнительных усилий при использовали их в SwiftUI, ибо новый в iOS 17 протоколObservableобеспечит вам "живое" отображение на UI всех изменений ваших хранимых объектов, а Identifiable и Hashable позволят беспрепятственное использовать их в спискахForEach. В SwiftData, в отличие от Core Data, нет никаких внешних файлов для Модели Данных и никакой "закулисной" генерации старых Objective-C классов, которые еще нужно адаптировать для использования в Swift. В SwiftData - всёисключительно просто. Кроме того, в SwiftData существенно, по сравнению с Core Data, упрощена выборка данных и отображение её результатов на UI. Для этого предназначена "обертка свойства" @Query , для которой вы можете указать предикат Predicate (то есть условия выборки данных) и сортировку результата SoreDescriptor. Новый мощный предикат Predicate выгодно отличается от старого предиката NSPredicate Core Data тем, что теперь вы можете задавать условия выборки данных, используя операции самого языка программирования Swift, а не какую-то замысловатую форматированную строку .  SwiftData дополнен такими современными возможностями как Swift многопоточность и макросы. В результате в Swift 5.9 мы получили, по определению самого Apple,  “бесшовное”  взаимодействие с постоянным хранилищем данных в нашем приложении. SwiftData совершенно естественным образом интегрируется в SwiftUI и прекрасно работает с CloudKit и Widgets.  Если вы начнете работать со SwiftData, то вообще не почувствуете даже "духа" Core Data, всё очень Swifty.  Apple настаивает на том, что SwiftData - это совершенно отдельный от Core Data фреймворк, нам точно неизвестно, является ли SwiftData "оболочкой" Core Data, но даже если это так, то она настолько элегантно, интуитивно  и мастерски реализована,  что у вас будет ощущение работы исключительно в "родной" cреде языка программирования Swift. В этой статье я покажу вам, как  определить Схему  данных в SwiftData,  выполнить CRUD операции (Create -  Создать, Read - прочитать, Update - модифицировать, Delete - удалить),  сформировать запросы Query к данным с помощью предиката Predicate,  использовать "живой" запрос @Queryв SwiftUI и динамически его настроить, эффективно "закачать" JSON  данные  в SwiftData хранилище без блокировки пользовательского интерфейса (UI). В качестве демонстрационного приложения я буду использовать упрощенный вариант приложения Enroute из стэнфордских курсов CS193P 2020, которое отображает в некоторый фиксированный момент все рейсы Flight, обслуживаемые двумя международными аэропортами:  аэропортом Чикаго "Chicago O'Hare Intl" и аэропортом Сан-Франциско "San Francisco Int'l". Данные об этих рейсах получены мною с сайта FlightAware в JSON формате. Мы "закачаем" эти данные в постоянное хранилище в нашем приложении и сможем не просто видеть всю информацию о рейсах, аэропортах и авиакомпаниях ...  ... но и делать различные запросы с помощью фильтров.  Например, выбирать определенные рейсы Flights по аэропорту назначения - destination, аэропорту вылета - origin,  авиакомпании - airline и  нахождении в данный момент в воздухе - Enroute Only: В качестве примера мы выбрали с помощью Picker в качестве аэропорта назначения destination международный аэропорт в Чикаго - "Chicago O'Hare Intl",  а также рейсы, которые в данный момент находятся в воздухе Enroute Only: ... и получили следующий список рейсов, кликнув на кнопке  "Done": Кроме того, в списке аэропортов мы можем искать аэропорты по первым буквам имени, например, "San " и, выбрав из сформировавшегося списка аэропортов, например, "San Francisco Int'l" (международный аэропорт Сан-Франциско), посмотреть более подробную информацию о нём: местоположение, рейсы, вылетающие  и прилетающие в этот аэропорт: Мы можем сортировать рейсы нужным нам способом. На рисунке ниже представлена сортировка по дальности полета distance в порядке убывания и в порядке возрастания:  У меня есть точно такое же приложение Enroute, написанное с применением Core Data, так что при желании очень легко сравнить его с вновь создаваемым приложением SwiftData Airport  в Github. Итак, центральным объектом нашей Схемы является рейс Flight, который выполняется авиакомпанией airline: Airline между аэропортом  отправления  origin: Airport и аэропортом  назначения destination: Airport. Модель данных такого приложения мы представим обычнымиSwift классами: Flight,Airport и Airline : У рейса Flight имеется уникальный идентификатор рейса ident, время взлета (по расписанию scheduledOff, приблизительное  estimatedOff и действительное actualOff), время приземления (по расписанию scheduledOn, приблизительное  estimatedOn и действительное actualOn), аэропорт отправления origin: Airport, аэропорт прибытияdestination: Airport, авиакомпания airline: Airline, выполняющая этот рейс, тип самолета aircraftTypе. а также расстояние routeDistance между пунктами отравления и назначения, скорость filedAirspeed, высота filedAltitude  и процент пройденного пути progressPercent. Аэропорт Airportимеет код icao, имя name, город city, штат state, код страны countryCode , географические координаты latitude и longitude его местоположения , а также временной пояс  timezone. Кроме того, нас интересует информация о рейсах, вылетающих из этого аэропорта flightsFrom, и о рейсах, прибывающих в этот аэропорт, flightsTo. Авиакомпания Airlineимеет код code, имя name, краткое имя  shortName. Нас также интересует информация о всех рейсах flights, выполняемых в данный момент этой авиакомпанией.  В SwiftData достаточно перед Swift классами разместить макрос @Model, и мы получим "постоянно хранимую" Модель Данных,  то есть в приложении будут постоянно сохраняться "рейсы" Flight,   "авиакомпании" Airline и "аэропорты"Airport, каждый со своими атрибутами и взаимосвязями:  Благодаря макросу@Model SwiftData по умолчанию автоматически преобразует все хранимые свойства Swift класса  в постоянно хранимые свойства.    Если свойство имеет Value ТИП, SwiftData автоматически адаптирует его как атрибут. Такие свойства могут включать в себя: базовые Value ТИПы (String, Int и Float и т.д.) более сложные Value ТИПы : структуры struct перечисления enum Codable ТИПы коллекции Value ТИПов Если свойство имеет сылочный Reference ТИП (то есть класс class), то SwiftData адаптирует  его как взаимосвязь. Вы можете создавать взаимосвязи: с другими @ModelТИПами   с коллекциями@ModelТИПов   @Modelавтоматически адаптирует все хранимые  свойства вашего Swift класса либо в атрибуты, либо во взаимосвязи,  и в большинстве случаев можно вообще больше ничего не делать. Но вы можете влиять на то, как SwiftData будет выполнять эту адаптацию, используя  "волшебные палочки" (то есть макросы) и  аннотировать отдельные свойства  @Model классов с помощью макросов: @Attribute @Relationship @Transient С помощью  макроса @Attribute вы можете, например,  добавить ограничение уникальности для идентификатора рейса ident:  Если вы попытаетесь вставить рейс Flight с тем же самым значением идентификатора ident, то существующий рейс будет обновлен и заменит значения свойств на новые свойства вставляемого объекта. Это может помочь вам поддерживать актуальность и согласованность данных вашего приложения, если информация периодически скачивается с сервера. С помощью  макроса @Relationshipможно управлять взаимосвязями c @Model объектами и явно указать взаимосвязи типа "один-ко-многим"  или "многие-ко-многим".  Например, для аэропорта Airport с помощью макроса @Relationship  нам нужно явно указать "инверсивные" взаимосвязи для flightsFrom и flightsTo , то есть свойства в  рейсе Flight соответствующие аэропорту отправления origin и аэропорту назначения destination: Мы можем также указать для аэропорта Airport уникальность свойства icao : Точно также в объекте Airline с помощью макроса @Relationshipмы указываем "инверсивную" взаимосвязь для flights  и обеспечиваем уникальность атрибута code: Вот как выглядит Схема Данных для нашего приложения в SwiftData: С помощью макроса @Transient можно исключить из постоянного хранилища определенные свойства вашего класса, они могут участвовать в формировании пользовательского интерфейса  UI или во вспомогательных вычислениях, но сохраняться не будут.  У макроса @Attribute есть  следующие опции: unique:  гарантирует уникальное значение свойства  transient: позволяет контексту игнорировать это свойство при сохранении модели-владельца transformable: преобразует значение свойства между формой "в памяти" и сохраняемой формой externalStorage: сохраняет значение свойства как двоичные данные отдельно от постоянного хранилища  encrypt: хранит значение свойства в зашифрованном виде preserveValueOnDeletion:  сохраняет значение свойства в истории "постоянного хранения", когда контекст удаляет модель-владелеца spotlight: индексирует значение свойства, чтобы оно отображалось в результатах поиска Spotlight Объемные данные не должны храниться непосредственно в вашем хранилище, потому что это может замедлить его работу. Вы можете указать SwiftData хранить свойство во внешнем хранилище с помощью опции externalStorage макроса @Attribute для этого свойства. Например, если вы хотели бы сохранить изображение, полученное извне: Когда Схема Данных определена, пришло время создавать объекты, модифицировать их, удалять и выбирать из хранилища. Для управления операциями с @ModelТИПами в SwiftData используются два важных класса: контейнер ModelContainer и контекст ModelContext.  Контейнер ModelContainer обеспечивает “бэкенд” постоянного хранения для @Model ТИПов. Вы можете создать контейнер ModelContainer, просто указав список @Model ТИПов, которые вы хотите сохранять.  Если вы хотите дополнительно настроить свой контейнер container,  вы можете использовать конфигурации configurations для изменения своего URL-адреса и CloudKit, а также опций миграции.  Как только ваш контейнер container установлен, вы готовы создавать новые данные, изменять существующие и сохранять изменения, а также осуществлять выборку данных с помощью контекста ModelContext.  Вы также можете использовать SwiftUI View и Scene модификаторы, чтобы установить контейнер container ... ... и использовать его в среде @Environment вашего Viewдля получения контекста context:  Контекст ModelContext отслеживает все изменения в ваших моделях @Model и предоставляет множество действий для работы с ними. Они являются вашим интерфейс для отслеживания обновлений, сохранения изменений и даже отмены этих изменений. Вне иерархии Views вы можете попросить контейнер container предоставить вам разделяемый (shared) MainActor контекст context: … или вы можете просто инициализировать новые контексты  context для данного контейнера container: Если у вас есть контекст ModelContext, то  вы готовы к операциям CRUD (создание - Create, чтение - Read, модификация - Updata, удаление - Delete) над данными. Cоздание новых @Model объектов , как и экземпляров любых других Swift классов class, производится с помощью инициализаторов init,  затем вы вставляете insert вновь созданный объект в контекст ModelContext. Но класс  class в Swift, в отличие от структуры struct, не имеет инициализаторов по умолчанию. Вам нужно предоставить свои собственные инициализаторы. К счастью, Xcode может помочь вам в этом и автоматически сгенерирует для вас инициализацию. Просто начните вводить init и используйте автодополнение Xcode. Но тонким вопросом при создании нового объекта @Modelявляется определение взаимосвязей, и здесь нужно принимать во внимание два фактора:  взаимосвязь с другим объектом @Model создается только в том случае, когда @Model объект уже находится в SwiftData хранилище, достаточно создание взаимосвязи с одной из сторон - другая сторона формируется автоматически, например, создавая взаимосвязь destination: Airport в объекте рейса Flight, нет необходимости добавлять этот рейс в массив рейсов flightsTo для аэропорта destination, это будет сделано автоматически. Поэтому, если мы  создаем новый рейс Flight, то указать взаимосвязи: аэропорт отправления origin, аэропорт прибытияdestination и авиакомпанию airline, выполняющую этот рейс, мы сможем только после того, как рейс Flight уже будет находиться в нашем хранилище, так что нам понадобится только один инициализатор рейса Flight - init (ident:String)с единственным уникальным атрибутом ident, при этом остальные хранимые атрибуты должны иметь значения по умолчанию или иметь Optional ТИП : С помощью этого инициализатора мы сначала создадим новый рейс Flight с заданным идентификатором ident, а затем вставим его в контекст context: Сохранение нового объекта flight не понадобится, потому что по умолчанию работает режим автосохранения контекста context. После получения уже записанного в SwiftData хранилище рейса flight с заданным идентификатором ident, мы   модифицируем все его атрибуты, включая взаимосвязи origin, destination и airline с помощью static функции func update : Для придания универсального характера функции update, которая работала бы как с новыми, так и с уже существующими рейсами flight, мы использовали static функцию func withIdent класса Flight, которая ищет рейс flight с заданным идентификатором ident, и если находит его, то возвращает уже существующий рейс flight, а если не находит, то создает новый с помощью insert: Надо сказать, что это еще и программный способ обеспечения уникальности свойства ident, и в принципе можно не указывать это с помощью макроса  @Attribute(.unique) var ident: String,  а это может очень пригодится при синхронизации SwiftData информации с iCloud,  который не поддерживает ограничение @Attribute (.unique).  Аналогичным образом мы поступим с Airport и с Airline ( код в Github проект SwiftDataEnroute). Итак, мы научились читать (READ) объекты из хранилища SwiftData : Создавать (CREATE) новые объекты: Примечание. Если происходит вставка insert SwiftData объекта, у которого есть уникальный атрибут@Attribute (.unique),  и этот объект уже находится в хранилище, то  новый объект не создается, а атрибуты существующего объекта просто обновляются.  Модифицировать (UPDATE) существующий объект: Удалить (DELETE) постоянно хранимый SwiftData объект так же просто.  Достаточно попросить ModelContext “пометить” его для удаления : Примечание. Все SwiftData объекты имеют свойство context, которое дает вам контекст, к которому они принадлежат. Вот как вы можете использовать его для оптимизации функции удаления delete:  Когда сработает механизм автосохранения, произойдет фактическое удаление объекта.  Однако, если вы хотите немедленно выполнить удаление объекта, a также зафиксировать другие ожидающие изменения, вы можете попросить ModelContext сохранить их с помощью явной операцииsave: Для выборки данных SwiftData привлекает такие "чисто" Swift ТИПы, как предикат Predicate и дескриптор выборки FetchDescriptor, а также значительно улучшенный уже существующий в Swift дескриптора сортировки SortDescriptor. Новый в iOS 17 предикат Predicate работает с “родными” ТИПами Swift. Это современная замена старого ТИПа NSPredicate с полной проверкой ТИПов. Реализация ваших предикатов также сильно упрощается благодаря такой поддержке Xcode, как автозаполнение. Вот несколько примеров построения предикатов для нашего приложения.  Во-первых, я могу указать все рейсы, вылетающие из международного аэропорта San Francisco:  Я могу сузить наш запрос до рейсов, выполняемых авиакомпанией United: Можно запросить рейсы, находящие в данный момент в воздухе: После того, как мы решили, какие рейсы нам нужны, мы можем использовать новый ТИП FetchDescriptor для формирования запроса к нашему постоянному хранилищу и дать указание контексту ModelContext выбрать эти рейсы:  Работая вместе с FetchDescriptor, Swift ТИП SortDescriptor получил некоторые обновления для поддержки “родных” ТИПов Swift и keypaths. Помимо предикатов и сортировки, вы можете  ограничить количество результатов в FetchDescriptor, исключить не сохраненные изменения из результатов и многое другое. Чтобы узнать больше о контейнерах и контекстах SwiftData, а также об их возможностях, ознакомьтесь с сессией "Dive Deeper into SwiftData" («Углубленное изучение SwiftData»).  SwiftData был создан с расчетом на SwiftUI, и их совместное использование невероятно просто. SwiftUI — это самый простой способ начать использовать SwiftData. Будь то настройка контейнера SwiftData, выборка данных или управление обновлениями вашего View, компания Apple создала прекрасный API, напрямую интегрирующий эти фреймворки.  Новые SwiftUI Scene и View модификатор .modelContaner — это самый простой способ начать создание приложения SwiftData:  SwiftData использует в SwiftUI "обертку свойства" @Query для выборки данных их хранилища. В представленном ниже  коде мы выбираем все рейсы flights и показываем их в списке: @Query напоминает нам @FetchRequest в Core Data. Они имеют много общего. @Queryтакже является "живым" запросом к хранилищу SwiftData, то есть все изменения в нем автоматически отражаются на UI. @Query также поддерживает фильтрацию данных с помощью аргумента filter, сортировку с помощью sort, порядок сортировки с помощьюorder и анимацию animation. Вот @Query, который поддерживает сортировку массива рейсов flights по длине маршрута routeDistance и упорядочивание по возрастанию: Приведенный ниже @Queryвыбирает из хранилища только рейсы flights , вылетающие из аэропорта Сан-Франциско "San Francisco Int'l" и выполняемые авиакомпанией United Airline и сортирует их по % пройденного пути:  Однако в отличие от  @FetchRequest в Core Data, @Queryв SwiftData на данный момент (Xcode 15.0) не умеет динамически настраивать фильтр filter и сортировку sort в зависимости от изменения @Stateпеременных.  Например, если с помощью @Stateпеременной originICAO задать код icao аэропорта отправления... ... то в модификаторе .onChange(originICAO){...} не удастся динамически скорректировать параметр filter для @Query: Тем не менее, вы можете создавать динамические предикаты с помощью инициализатора init (originICAO: String) вашего View, когда изменяемый параметр originICAOпередается из предыдущего View.  Например, у нас есть HomeView  с закладками для рейсов, аэропортов и авиакомпаний и @Stateпеременная varoriginICAO: String?, которая задает код icao для аэропорта отправления: Мы передаем переменную originICAO в инициализатор init (originICAO: Binding<String?>) нашего FlightsView, отображающего рейсы flights, у которых аэропорт отправления origin, определяется этой переменной: Сама переменная originICAO может выбираться в FilterICAOView с помощью Picker из списка аэропортов отправления airportsFROM : Для выбора icao аэропорта отправления в FlightsView мы используем кнопку Button("Filter")  и sheet: Эта версия динамического @Queryпредставлена в Github. в проекте SwiftDataEnroute. Можно, конечно, в FlightsView организовать точно такой же динамический выбор рейсов вообще без настройки инициализатора, а просто выбрать с помощью @Query все рейсы flights: [Flight], а затем использовать функцию filter для массива flights и получить уже отфильтрованный массив filteredFlights, который и использовать в UI: Эта версия представлена в Github в проекте SwiftDataEnroute1. Более полная версия фильтрации рейсов по аэропортам отправления origin и назначения destination по авиакомпании airline и нахождению в данный момент в воздухе Entouter Only представлена в Github в проекте SwiftData Airport. Предварительные просмотры #Preview в Xcode играют жизненно важную роль в разработке приложений на SwiftUI, предлагая быструю визуальную проверку логики создания UI. Один из способов использования предварительных просмотров #Preview в SwiftData — это создание пользовательского ModelContainer. Этот способ был показан в видео WWDC 23 под названием "Build an app with SwiftData" ("Создание приложения с помощью SwiftData"). Основная идея состоит в том, чтобы создать контейнер ModelContainer исключительно для #Preview в SwiftData. Контейнер может находиться в памяти (inMemory) и содержать необязательно реальные данные. Возможная реализация показана ниже:  Теперь для любого View у нас есть предварительный просмотр #Preview: Если при запуске или в процессе работы приложения вам необходимо заполнять SwiftData хранилище JSON данными, то можно использовать современные возможности Swift в реализации многопоточности (Swift Concurrency). Для простоты мы будем считывать JSON данные непосредственно из файла, размещать их в промежуточные Codable Модели : AirportInfo, AirlineInfo, FlightsInfo (источник JSON данных - сайт FlightAware) , а затем использовать MainActor для записи в хранилище SwiftData без явного сохранения, поскольку действует режим автосохранения для контекста context. Вот пример считывания информации об аэропортах : Аналогичные функции используются для авиакомпаний и рейсов и всё собирается в async функции asyncLoadMainActor () ... ... которая используется при запуске приложения в модификаторе .task, если в хранилище нет данных, и при нажатии кнопки Button ("Load"): Загрузка данных в SwiftData хранилище несмотря большое количество рейсов (349), аэропортов (203) и авиакомпаний (84) происходит настолько быстро, что вы даже не заметите блокировки Main Queue,  и все же она есть.  Эта версия загрузки данных в SwiftData хранилище на MainActor представлена в проектах SwiftDataEnroute, SwiftDataEnroute1 и SwiftData Airport на Github. Мы можем пойти еще дальше и загружать данные в SwiftData на фоновой очереди (background queue). Для этого мы создаем actor LoadModelActor: ModelActor, инициализируем его с использованием ModelContainer, создаем новый контекст context для фоновых операций и используем его для создания DefaultModelExecutor:  Как видите,  для actor нам пришлось выполнить сохранение контекста context.saveContext(), чтобы данные отражались мгновенно на  UI (может быть это особенности работы этой версии SwiftData). Добавляем async функцию func asyncLoad () async в наш FlightsView : ... и вызываем её, также как и предыдущую,  в модификаторе .task, если в хранилище нет данных, и при нажатии кнопки Button ("Load"): При старте приложения SwiftData Airport1 , в котором реализована загрузка JSON данных на background, мы попадаем на пустую закладку Flights, идет загрузка данных, и мы практически мгновенно можем перейти на закладки Airports и Airlines, обнаружить там загруженную информацию, а затем вернуться на закладку Flights и обнаружить там уже 349 загруженных рейсов. Так что никакой блокировки Main Queue нет. Эта версия загрузки данных в SwiftData хранилище на background представлена в проекте SwiftData Airport1 на Github. Мы можем пойти еще дальше и сделать Codable SwiftData @Model, например Airport, чтобы загружать JSON данные непосредственно в @Model: Однако, мы получили сообщение об ошибке "ТИП Airport не соответствует протоколам Decodable и Encodable", хотя все свойства класса Airport являются Codable, и если бы не было макроса @Model, мы бы не получили сообщения об ошибках, так как компилятор автоматически реализует эти протоколы для классов и структур, в которых все свойства Codable.  К сожалению, в бета версии SwiftData @Model объекты не получили Codable поддержки. Правда механизм Codable очень хорошо отработан, и в качестве "обходного пути" мы можем сами его реализовать для @Model классов Airportи Airline:  Несколько сложнее это сделать для класса Flight, так как в JSON данных есть только уникальные icao коды для аэропортов отправления origin и назначения destination, поэтому нам придется записать эти коды в дополнительные свойства icaoOrigin: String  и icaoDestination: String...    а потом с помощью контекста context выбирать нужные аэропорты: Эта версия загрузки данных в SwiftData хранилище на background с использованием протоколаCodable представлена в проекте SwiftData Airport2 на Github. SwiftData, построенный вокруг современного Swift, эффективно заменяет Core Data, повышая производительность ваших приложений и упрощая хранение данных. В статье рассматривается, как SwiftData организует описание Схемы данные с помощью макросов @Model, @Attribute, @Relationshipнепосредственно в коде в виде обычных Swift  классов со свойствами, имеющими обычные базовые Swift ТИПы, как использует контейнер ModelContainer и контекст ModelContextдля выполнения  CRUD (создание, чтение, обновление, удаление) операций как на Main Queue, так и на Background Queue. Показано использование предикатов Predicate с запросами Query в SwiftData, обеспечивающими мощный механизм фильтрации и сортировки данных в ваших Swift приложениях. Пока, к сожалению, предикаты Predicateимеют некоторые ограничения. SwiftData был создан с расчетом на SwiftUI, и их совместное использование невероятно просто. В довольно простом демонстрационном примере на SwiftUI раскрываются нюансы динамической настройки "живого" запроса @Query и формирования пользовательского контейнера ModelContainer для #Previews в Xcode. Показано, как сделать @Model классы Codable (хотя на данный момент это не поддерживается компилятором автоматически) и загружать JSON данные  непосредственно в SwiftData хранилище без промежуточных структур данных. И все-таки в будущих версиях SwiftData хотелось бы иметь: Возможность динамической настройки @Query как @FetchRequestв Core Data  Возможность использования внешних функций и более сложных логических выражений в #Predicate  Автоматическую поддержку Codable протокола для @Model классов Имея многолетний опыт работы с Core Data могу сказать, что со SwiftData работать фантастически легко и комфортно, и уже сейчас видно, каким большим потенциалом SwiftData будет обладать в ближайшие годы. Фреймворку SwiftData посвящено несколько сессий на WWDC 2023:  Meet SwiftData - WWDC23  - Video  Model your schema with SwiftData - WWDC23 -Video  Build an app with SwiftData - WWDC23 - Video Migrate to SwiftData - WWDC23 - Videos  Dive deeper into SwiftData Советую также почитать статьи Karin Prater (очень подробные с хорошими демонстрационными примерами): Modeling Data in SwiftData Introduction to Data Persistence in SwiftUI with SwiftData Data Handling in SwiftData: Create, Read, Update, Delete How to fetch and filter data in SwiftData with Predicates SwiftData Stack: Understanding Schema, Container & Context How to convert a CoreData project to SwiftData Background actor SwiftData Background Tasks Codable Making your SwiftData models Codable Easily Preload SwiftData Using JSON On Your App’s First Launch