Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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
380
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
250
Featured
See All Featured
Visualization
eitanlees
150
16k
Making Projects Easy
brettharned
120
6.5k
A better future with KSS
kneath
240
18k
Become a Pro
speakerdeck
PRO
31
5.7k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
54k
GitHub's CSS Performance
jonrohan
1032
470k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.2k
Raft: Consensus for Rubyists
vanstee
141
7.2k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
Code Reviewing Like a Champion
maltzj
527
40k
Done Done
chrislema
186
16k
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)