-
SwiftData의 새로운 기능
SwiftData의 최신 개선 사항을 확인하세요. Codable을 사용하여 맞춤형 및 타사 유형을 유지하는 방법과 가져온 데이터를 SwiftUI 앱의 섹션으로 그룹화하는 방법을 안내합니다. 또한 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.