Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SwiftData: Dive into inheritance and schema mig...
Search
1mash0
June 26, 2025
0
350
SwiftData: Dive into inheritance and schema migration - Swift愛好会スピンオフ WWDC25セッション要約会
1mash0
June 26, 2025
Tweet
Share
More Decks by 1mash0
See All by 1mash0
SwiftDataのカスタムデータストアを試してみた
1mash0
0
220
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.6k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Building Applications with DynamoDB
mza
96
6.6k
Facilitating Awesome Meetings
lara
56
6.5k
The Power of CSS Pseudo Elements
geoffreycrofte
78
6k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
36
2.5k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
Docker and Python
trallard
46
3.6k
Raft: Consensus for Rubyists
vanstee
139
7.1k
We Have a Design System, Now What?
morganepeng
53
7.8k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
114
20k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
30
2.9k
Transcript
ू·ΕSwift͖ʂSwiftѪձεϐϯΦϑ WWDC25ηογϣϯཁձ SwiftData: Dive into inheritance and schema migration ͍·͑͢,
X: 1mash0_
Topics Harness class inheritance Evolving data with migration Tailoring fetched
data Observing changes to data
Harness class inheritance iOS 26͔ΒSwiftDataϞσϧͷΫϥεܧঝ͕αϙʔτ͞Εͨ ܧঝΛ༻͍Δ͜ͱͰɺαϒΫϥεΫϥεͷϓϩύςΟৼΔ͍ΛҾ͖ܧ͙͜ͱ ͕Ͱ͖Δ @Model class Trip
{ ... } @available(iOS 26, *) @Model class BusinessTrip: Trip { var perdiem: Double = 0.0 } @available(iOS 26, *) @Model class PersonalTrip: Trip { var reason: Reason }
Harness class inheritance ͍ํෳͷϞσϧΛѻ͍͍ͨ࣌ͱಉ͡Α͏ʹ͚ͩ͢ WindowGroup { ContentView() } .modelContainer(for: [Trip.self,
PersonalTrip.self, BusinessTrip.self]) let modelContainer = try ModelContainer( for: Trip.self, PersonalTrip.self, BusinessTrip.self ) WindowGroup { ContentView() } .modelContainer(modelContainer)
Harness class inheritance ϙΠϯτ ΫϥεͱαϒΫϥε͕֊ߏΛ࣋ͭ͜ͱ is-a ͷ͕ؔΓཱͭ͜ͱ ֊ߏΛ࣋ͨͣɺ୯ҰϓϩύςΟͷڞ༗͕తͷ߹ϓϩτίϧ४ڌʹ͢Δ σΟʔϓαʔνͱγϟϩʔαʔνͷ྆ํΛར༻͢Δ͜ͱ σΟʔϓαʔνͷΈͷ߹ɺΫϥεͷϓϩύςΟͱݟͳ͖͢
γϟϩʔαʔνͷΈͷ߹ɺͦΕͧΕͰϞσϧΛ࡞͢Δ͖
Evolving data with migration VersionedSchemaͱSchemaMigrationPlanΛ༻͍ͯɺաڈόʔδϣϯ͔Βͷ ϚΠάϨʔγϣϯ͕Մೳ iOS 17: εΩʔϚόʔδϣϯ2.0 SwiftData͕ಋೖ
iOS 18: εΩʔϚόʔδϣϯ3.0 ॏෳσʔλΛղফ͢ΔͨΊʹΧελϜͷMigrationStageΛ༻ iOS 26: εΩʔϚόʔδϣϯ4.0 αϒΫϥεΛՃ ηογϣϯதͩͱMigrationStage.lightweightͰϚΠάϨʔγϣϯ͕ߦΘ ΕͯΔ
Tailoring fetched data SampleTripsΞϓϦʹݕࡧόʔͰͷݕࡧػೳ͕࠶ಋೖ ηάϝϯτͱݕࡧςΩετͷPredicateΛΈ߹ΘͤͯϑΟϧλϦϯά͍ͯ͠Δ αϒΫϥεʹߜͬͯϑΟϧλϦϯά͢ΔPredicateͷੜ let predicate: Predicate<Trip>? =
#Predicate { $0 is PersonalTrip }
Tailoring fetched data ϚΠάϨʔγϣϯ࣌ͷϑΣονॲཧύϑΥʔϚϯε্ͷ propertiesToFetchΛ༻ͯ͠ඞཁͳϓϩύςΟͷσʔλ͚ͩΛ࣋ͬͨϞσϧΛ औಘ͢ΔΑ͏࠷దԽ ಛఆͷϦϨʔγϣϯγοϓΛḷΔඞཁ͕͋Δ߹ relationshipKeyPathsForPrefetchingΛͬͯ࠷దԽΛਤΕΔ SampleTripsΞϓϦͷΟδΣοτͰ࠷৽ͷ1݅ͷΈ͕ඞཁͳͨΊɺfetchLimit Λઃఆͯ͠ޮΛߴΊ͍ͯΔ
Observing changes to data PersistentModelObservable withObservationTrackingΛ͏͜ͱͰϞσϧͷϓϩύςΟʹՃ͑ΒΕͨมߋΛ ࢹͰ͖Δ ͨͩ͠؍ଌͰ͖ΔͷಉҰͷϓϩηεͰߦΘΕͨมߋͷΈ ΟδΣοτɺΤΫεςϯγϣϯɺΞϓϦͷผModelContainer͔ΒՃ͑ΒΕͨ มߋ؍ଌͰ͖ͳ͍
Observing changes to data ಉҰModelContainerͰɺผModelContextͰ͋ͬͯQueryΛ༻͍ͯ͠Δ ߹มߋ͕ࣗಈͰө͞ΕΔ ϑΣονAPIͳͲΛར༻͍ͯ͠Δ߹ɺผModelContextͰՃ͑ΒΕͨมߋ࠶ϑΣο ν͠ͳ͍ͱө͞Εͳ͍ ࠶ϑΣονίετ͕ߴ͍ͨΊɺཤྺػೳΛར༻ͯ͠࠶ϑΣον͕ඞཁ͔Ͳ͏͔Λஅ ͢ΔΑ͏ʹ͢Δ
Observing changes to data iOS 26͔ΒཤྺΛsortByͰฒସ͑ͯऔಘͰ͖ΔΑ͏ʹͳͬͨ ࠓ·ͰཤྺΛશ݅औಘͯ͠͠·͏Մೳੑ͕͕͋ͬͨɺޮతʹ࠷৽ͷཤྺτʔΫϯΛ औಘͰ͖ΔΑ͏ʹͳͬͨ var historyDesc
= HistoryDescriptor<DefaultHistoryTransaction>() historyDesc.sortBy = [.init(\.transactionIdentifier, order: .reverse)] historyDesc.fetchLimit = 1 let transactions = try context.fetchHistory(historyDesc)