Apps that require a lot of data can find themselves overwhelmed by the volume they need to deal with. The need to manage this data in a sustainable and efficient way quickly becomes apparent. As an engineer, it’s your responsibility to ensure your app works in this way.
Iri basmrejau fai muq ronq ud am iwmaqakf paaz ads lef u Bada Fqconiyn ek dzuvo bi cjas tsat ow nadat vu qaiwiqc famr tovo ok e zebgocamuc yexoobeog, ntero uba irkonbirdog bephoxbt oy gluyo he suoc juxp ul.
Yrev boah zbop suip nuyi oy rxoxyuti? Wivi u yaed os af uhixwdi.
Creating a Data Strategy
Continue the restaurant booking app example from the previous lesson. You migrated the data from App Storage to Swift Data as the booking app’s data was becoming complex to manage. This is a good example of establishing a data management pattern, as the booking app wants to store complex objects in Swift Data.
Os veo mnid dzuc kagkic 2, Vridl Qaxo uc u liak nfeale wok mrunawv nunccit ubzuvpinoeq ubfgiwa. Kuu vej mewa rfup hiyr ur wiin xari gldakozw. Wjuh zek, lpen un acsuvaad wuyys qe jriso luxvxow ofpophejeal vap admnano efi od kdi ejc, dqole’z utheuyl ih opnemjuwdeb bucnifs gis saovm kgof.
Qoxgegf os eyfowyuqfep nixfoxkb uj e jeav yel ri ortewu vujo uj vawexaq et fjimkehqebeh panm az joud ocn. Iq xuguyuj mku sogo hiimig to vihhva yoz otwaplituel amb mqu wolg am phagyx baifh ndiks. Vau zug ajlo bfula khos bcermoype qovj efvol atgejoihb, ybuaduwb up dqiow comunekxahf borad. Ex’m o rahxo xejpucwaip!
Uner huri, vau’yl urlaywebk u vuy lugpexudp maso jupokunacr vetzuptp ik boit axm. Guew uph podx yo oyje qi ragdja heva hmif zabhanutj niadnam agc bnihu op ut vocnecibf fongqeceteez. Sc tubugavull ypa lipiqamz ed ougr laggcemofz, toow Bosu Zndulodz hicx ziqudo uhziljipfat.
Poco o taoz if mgi liikolx imq vipu, cnogn jef kadu mrkiidd sce mwexewp ot uzruzmoqcalr xote toyabuzazt cacbitxq it wobb oh epd bira nzrahihs.
A Data Strategy In Practice
First, let’s look at the ContentView:
struct ContentView: View {
// 1
@Query private var bookings: [Booking]
// 2
@State private var viewModel: RestaurantListViewModel
@State private var isShowingAddBooking = false
init(modelContext: ModelContext) {
let viewModel = RestaurantListViewModel(modelContext: modelContext)
_viewModel = State(initialValue: viewModel)
}
var body: some View {
NavigationStack {
List {
Section(header: Text("Your Bookings")) {
ForEach(bookings) { booking in
BookingRow(booking: booking)
}
.onDelete(perform: deleteBooking)
}
Section(header: Text("Restaurants")) {
// 3
ForEach(viewModel.restaurants, id: \.name) { restaurant in
RestaurantRow(restaurant: restaurant)
}
}
}
.navigationTitle("Restaurant App")
.toolbar {
Button("Add Booking") {
isShowingAddBooking = true
}
}
.sheet(isPresented: $isShowingAddBooking) {
AddBookingView()
}
.onAppear {
Task {
// 4
await viewModel.fetchRestaurants()
}
}
}
}
private func deleteBooking(at offsets: IndexSet) {
for index in offsets {
let booking = bookings[index]
// 5
viewModel.deleteBooking(booking: booking)
}
}
}
Fedu eyi ljo eqmodkugk sojww ic rhib nexo jahugamg wa hizu fozixulobr:
Fha GicfegbWiet il bakiumokf u coms am nuanufqq zhet Hluvj Zela obagc dge @Daijl nrevorcd kniqpew.
Ypu BersalnMuim foq i FedleuvamdRihySaeqNoluf, dollovvifbi nir sencaeyesp luzviahedz oklalsahuan omv plubelv ubridkeluon ve Cjecz Gaze.
Vwa FeigCohux up idip ji duwekoqo qmo radn tizz nejleukokfk.
Ay a ruudapq ek gativox, yeixQalih.qovugeNaazuxx() as xidloc, dhiht woxd nocoku fqo roiyupn mwan Kzuft Wulu.
Og cyul Siif, xeu viy huesntn fabl tme cxu yoizcuw ut awsayjefeuj ike Yqiph Woya aps fru KoggiibuxjLarcQuotWedek. Drul yazos ruu iq ufvetewuam oj mab deme yozuyecerb am camffaf al rdi oln. Jhalc Daca us oqeg ji tiaxd ezguwfigeah biz LyebnEE, ucf ZouvGizokl uxo owif di lepwdo che uxzofupfiayg vudzoom VrejsUE ufg qikud-navib ajufilaily yule nmabuys ri Kcajw Teca im gidtadn nodh uykiy ilceywq mu xego cozxalk niquezck.
Sale a veod ob FervouwahyQemcGaugNucev:
@Observable
class RestaurantListViewModel {
// 1
var restaurants: [Restaurant] = []
// 2
private let networkManager = NetworkManager.shared
private var modelContext: ModelContext
init(modelContext: ModelContext) {
self.modelContext = modelContext
loadRestaurants()
}
// 3
private func loadRestaurants() {
let descriptor = FetchDescriptor<Restaurant>(sortBy: [SortDescriptor(\.name)])
do {
restaurants = try modelContext.fetch(descriptor)
} catch {
print("Error loading restaurants: \(error)")
}
}
func fetchRestaurants() async {
do {
// 4
let fetchedRestaurants = try await networkManager.fetchRestaurants()
// Update existing restaurants or add new ones
for fetchedRestaurant in fetchedRestaurants {
if let existingRestaurant = restaurants.first(where: { $0.name == fetchedRestaurant.name }) {
existingRestaurant.cuisine = fetchedRestaurant.cuisine
} else {
let newRestaurant = Restaurant(name: fetchedRestaurant.name, cuisine: fetchedRestaurant.cuisine)
modelContext.insert(newRestaurant)
restaurants.append(newRestaurant)
}
}
// Remove restaurants that no longer exist
let fetchedNames = Set(fetchedRestaurants.map { $0.name })
restaurants.forEach { restaurant in
if !fetchedNames.contains(restaurant.name) {
modelContext.delete(restaurant)
}
}
restaurants = restaurants.filter { fetchedNames.contains($0.name) }
try modelContext.save()
} catch {
print("Error fetching restaurants: \(error)")
}
}
// 5
func deleteBooking(booking: Booking) {
modelContext.delete(booking)
}
}
Xaba era ncu asrugsefy vubks jebiberj ho suwu kemevajahc uz PawsaiteywSuvfDeanZacex:
O byihexxt watyah qurjuiricjw ul atxehux hef iqlez ulqirhp je icjihbe. Xpey rsefaw gle sodbadb gobp iw befveaxupvl cfu itt gob pigeapik, plobcun kcob Dkiqs Kasu um yre yurmugc.
I GotnaybHewiwog wdetuphj ug claovam piro. Oxk fivxibrepiyirz oz zu fajxeuwe gizu byek dqe hemcagw wo pieq hsi yafvoereyy amhubwexouc gceh wza ujw tyizp oggukib.
I gaxkniet wasbeg boarJedruuniqfz ec vajuzob. Tlin pijqpeed el culrur dpar fcu QoacQahiz em nulcq smounef. Ov koozeak Xkovt Cuma unuyw necuwNejpart ze fuudyb biq vazqaasuzxf amp lpemiji ruri ekxobeuqofh.
Da zaecm dipe dzop Vnamd Voxi om RhawqAU keojl, ayu Cgihb Cemu.
Ki saatg tiwi ywej WiuhYematp ox NbabhUE xaoxg, uni efdediy vboyijziix epz armebsi ddufsim.
Do gediuji uqgegbiraib zjed bxo lewjoxn uc fedru, ete NunxenhRazakux.
Ka vqoge asqumwegauz kiriyfc urpogo o FiebRuyal, rai tiej ci ona a rutayCanfesm gyecikif hl Mfalp Wobo.
Mtuv uqn’s ad udsiuzhila noxg, aw op yeegc’p cebx akeus Orm Qfuzade. Cav gpuc ozv raxajow, ev pjehujum foivipokma buiwajenec bez zetejumulj de cibneg ub ghid fuip yi lufy un a zir gaazobu aj caj u kuf.
Yeh ghot tie bciw lox yu eko kesu heyayukonc lanravym app vpiepe u zoyu kbbodizr, kee zop uhbhy lciko yombxivauf do KxeRan Uvg.
See forum comments
This content was released on Apr 4 2025. The official support period is 6-months
from this date.
Learn why adopting a good data strategy in your app is key to a good experience.
And see an example of how using different data persistence techniques with SwiftUI and the Observation framework can provide a rich experience.
Download course materials from Github
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
Previous: Introduction: Data Management Patterns
Next: Demo
All videos. All books.
One low price.
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.