-
SwiftData 的新功能
了解 SwiftData 的最新增强功能。我们将介绍如何使用 Codable 持久保留自定类型和第三方类型的数据,并将获取的数据分组到 SwiftUI App 的各个分区。我们还将探索如何使用 ModelResultsObserver 和 HistoryObserver 在其他各处观察数据存储的变化,以便灵活地驱动强大的状态对象、与基于委托的架构实现整合,并精准地响应模型更新。
章节
- 0:00 - Introduction
- 0:53 - Sectioning your fetches
- 2:56 - Using custom types
- 6:26 - Observing data stores with ResultsObserver
- 9:41 - Observing history with HistoryObserver
- 12:20 - Next steps
资源
相关视频
WWDC26
WWDC24
-
搜索此视频…
-
-
0:01 - Sectioned fetching
// Sectioned fetching struct TripListView: View { @Query(sort: \Trip.startDate, sectionBy: \.destination) var trips: [Trip] var body: some View: { List(selection: $selection) { ForEach(_trips.sections) {section in Section(section.id) { ForEach(trips) {trip in TripListItem(trip: trip) } } } } } } -
4:59 - Using Codable
// Using Codable import SwiftData @Model class Trip { struct Location: Codable { var latitude: Double var longitude: Double } var name: String var destination: String var startDate: Date var endDate: Date var location: Location? @Attribute(.codable) var mapItemIdentifier: MKMapItem.Identifier? } -
8:20 - // Use observation to update map bounds
// Use observation to update map bounds @Observable @MainActor final class MapCameraController { private let modelResultsObserver: ModelResultsObserver<Trip> var bounds: MapCameraBounds? private var token: ObservationTracking.Token? init(modelContext: ModelContext) throws { modelResultsObserver = try ModelResultsObserver<Trip>(modelContext: modelContext) token = withContinuousObservation(options: [.didSet]) {[weak self], event in self?.bounds = self?.calculateBounds(trips: modelResultsObserver.results) } } private func calculateBounds(trips: [Trip]) -> MapCameraBounds? { / * */ } } -
8:21 - // Using HistoryObserver to sync with a server
// Using HistoryObserver to sync with a server @SyncActor final class ServerSync { private let observer: HistoryObserver private var token: ObservationTracking.Token? func start() throws { self.observer = try HistoryObserver(authors: ["App"], modelContainer: modelContainer) token = withContinuousObservation(options: .didSet) {[weak self] _ in _ = self?.observer.eventCounter self?.processChanges() } } private func processChanges() { // Fetch and process history transactions } }
-
-
- 0:00 - Introduction
What's new in SwiftData for Apple's 2027 releases, with a preview of the agenda: sectioning fetches, using custom types, and observing data stores.
- 0:53 - Sectioning your fetches
Use @Query's new sectionBy: parameter to group results by a key path. Access the underlying query via the underscore-prefixed name to iterate sections, each with an id and a collection of models — demonstrated by grouping trips by destination in SampleTrips.
- 2:56 - Using custom types
Store types SwiftData can't model natively — like MKMapItem.Identifier — by marking properties with @Attribute(.codable). Treat codable as an escape hatch for external types, not types you own; modeling your own types as @Model or supported value types unlocks filtering, sorting, and migration.
- 6:26 - Observing data stores with ResultsObserver
The new ResultsObserver brings Query-style fetching to non-SwiftUI code. Combine it with withContinuousObservation(didSet:) to react to model changes anywhere in your app — shown updating map camera bounds as trips change.
- 9:41 - Observing history with HistoryObserver
HistoryObserver exposes a single observable eventCounter that ticks when new persistent-history transactions arrive. Pair it with ModelContext.fetchHistory() to filter by model type or transaction author — ideal for syncing changes to an external server.
- 12:20 - Next steps
Recap: section your fetches, adopt codable types, react to data changes with ResultsObserver, and observe history with HistoryObserver.