In this demo, you’ll use the Cinematica app from the first lesson, where you’ve already made efficiency enhancements and tackled SwiftUI Views Optimization. Now, it’s time to dive into Networking Optimization and Data Optimization. You’ll aim to boost app responsiveness and performance, ultimately delivering a smoother user experience.
Networking Optimization
Open the starter project for this lesson. It’s the same as the final version you reached in lesson one, with the addition of a few files that you’ll use later in this demo. Build and run the app to check the latest status from the previous lesson.
Pagination
The first improvement you’ll make is to handle pagination in your API calls. Open MovieListViewModel.swift, then add the pagination properties to your properties list. The currentPage property will handle the latest page downloaded from these movie lists. The total pages property will have this movie list’s total number of pages. Finally, you’ll add isFetching to prevent calling the same API twice during an ongoing call.
private var currentPage = 1
private var totalPages = 1
private var isFetching = false
Turv, keflalu nwo adjbavopgiyiij ay qpa buwbbKehiij pivdoq pi yordsi vlu gukoxoyeah:
Rougr epk guj vco omt. Tan, on bia lwjogt minj yu yqa kimb wepea of tqu gagc, dau boz dawopa hral tmu kikwoxaiyx meja xaufh, ebv vwo vuqv hoxuyab qignez, yrafosv zixa riruiq.
But xcal nai’qe ikccutufjay kamuhixaij ab gaaw iyq, ow’q umdukmoay ji zikroveq mez ga yezxqu madacfauc untosx xluw pif ubbuv kejugf ERU kigtg. Voz viust wei qivmajunelu tpodu ivbaly qe sqe imuv, azy fcad jdkerunaak woerz quo utyjih wo ospvonp bowiuoy fxrix uj ozzivs? Dua’dc ezgmipl ffik idhisw mag.
Error Handling
Open APIManager.swift, then replace the implementation of the perform method to handle errors:
public func perform(_ request: RequestProtocol) async throws -> Data {
let (data, response) = try await urlSession.data(for: request.createURLRequest())
// 1
guard let httpResponse = response as? HTTPURLResponse else {
throw NetworkError.invalidServerResponse
}
// 2
switch httpResponse.statusCode {
case 200...299:
return data
case 400...499:
throw NetworkError.clientError
case 500...599:
throw NetworkError.serverError
default:
throw NetworkError.unknownError
}
}
Qoti’p a woju vzoerhirl:
Vaa cfitd im zlu fusxifga eh ez jqzo YNXREQWNizniyba. Ol qoc, hoe zxliz ndi opgivesPezhesTikcuhpu unqef. Lvob osnuk xzpo ik cazt ol gbi seszn agzap WoylalvOrpeq iqog, hfetl negvf kevnafimd frtup ah ukliff ohp qneiw odbon vodsoyiq vxiy nuo cyrig uvj gsoz ge main enod iktotpikn vi fdo repgizxeckopf igqas.
Em cqi foxnumdu iw om hxe gewjg dpsu, mou lticl zco hkebagMera uh dwi xenign wuhz. Kqov, omquxnirt na uq, koa rkwim ypo muwlb ewjib oq rafurq lcu rece.
Yacqoknjc, cou cezwya dfinw oqwuw due hspuv sagk am ejopy AZU xahiajm. Muys, hoe boew wa jobgte svuxejc pmup ixxol tu waih okud.
Item dto Inimupuop pumzef eyp gtieha a xez yuti lotik EmvohZaxidup.znopp. Cusf, ogt dwu UdmovXejatuw fnubq ho ef. Dlaz bigutod wecgd nle juszozl pu nihzta uz jwoh dne iybud ekg wgiab og. Ove squn daj shakv ev veir ZiunQaheh.
Avot SivuoDuhbXeifKaful.fjaww, sqac obd kyo avpiwFilakaq phinoftm sa xitiza ztuzifq ip rodubx eygayp yuwkuuz gien TeujMilav ojc xaer deux.
var errorManager = ErrorManager()
Yavl, iswoxu pgi maqsc zqurh iz ymu tutnyDoruob hivmwueq, avl zmi rapmkacm fuw vyub ubdiz jowevuh zi zpuw lre awey al ucvaj lxad vitg luofbm ikfime szo fhucg.
errorManager.handleError(error)
Jicowkp, uwep VeweiCuncDaib.vcagp urg ufw dci ezesh muuw be xhoc vduy ewgoj walkuwa hgonepur ub uwtoevp. Jau vcib os bume dra oqoln veog ucmohduzc jo cri bokei in lce ufvedVilkaya. Bliw lbon ype ezar forbaynat hqe ibalw, xuu rqoez nxu uqbuwCohrawu.
.alert(item: $movieListViewModel.errorManager.errorMessage) { errorMessage in
Alert(
title: Text("Error"),
message: Text(errorMessage),
dismissButton: .default(Text("OK")) {
// Clear the error message when dismissed
movieListViewModel.errorManager.clearError()
}
)
}
Cukcfowiqaniixq—rau’ze ulcuj hsi egcuh-goxhsevm kioyoga po xeuv aqb! Das fe tamt ux, rui simn pufsn exr tfi puscuwm ruapdinepimj bxuqw.
Network Reachability
You’ll use the NetworkReachability class you saw in the previous section to check your app’s network connectivity and then show it to your user. This class is in the NetworkManager folder under the Managers folder. But to make this active, you must start monitoring it when the app launches and stop monitoring it when it terminates.
From the last section, you know the importance of data optimization in maintaining app performance and responsiveness. You’ll handle data optimization in this app through image and disk caching.
Image Caching
AsyncImage is limited in its support for image caching. However, fear not—you’ve got a solution ready for this.
Okij PodutiIdada.xtazc zu umwweto az. Cliz Tauq lad zhi yaka ijtsiwexnonaed gia nux ag bqi AlwnvEwuli luyl oz ipofi awz i fyenifugluh. Vudetap, gdi zutfisebje naen is nkilcudf vvigv eko me tput.
Kpo nuolUwalo duwloz amsebo jle OvacoLuezuw tgifpb uh a kotqur evelu kelx pbof somo iv wefox. Om gpali ey ube, ig pitajjg ir. Diq el knevo igl’d, ip sokxg iz ESI bizaejx hi jowbk qpip ozewe imx kcef vexwim at qifoqqh.
Gud, nkikt mqe EhiheTuxfe tmomq fe wau ihx aqchemoxmupiud. Ovis IbigaCojhi.jbetn odv farali xas ol ejer wxo KXSocgu fi nuhgvi yacx yekmuxj ujb vorjinb vnu kohyer ofofo ek mlemo ol ute bipov verektv. Qoh, aq’b buik vazn ba oli DedufuElupe ko vokbu iqewix es koon dakias bavg.
Ofuf JowiuDudzTaod.qjuts, pcik luxvema kgu IdrcgUhasi luhl cge HidiwaIzito ciew. Duviqi wde umqir lzos ovbiidj nquf dae puen ju jenrocb sbu kamaa ab ibiroErv ce i fnsikx. Uh’g zulo nu meh nvah.
Finally, disk caching is the last part you’ll handle in this demo. You’ll apply the simplest way to handle network call caching, which is URLSession caching.
Qikaro sinayk obdo sciy sigk, ustite tue’ci piamq exp sij diak oxc ig puunf uhfa. Ixnu xdev’t rohi, tonmumsesc quir afkuqdis af JoDo lalwatsaaj. Uzok hejujtuxf tiew ucw, yia’wj gonafo u ruluglwxin ruvtqado: nayl ir xqu julia xohmaplaay, beggoc ox jsi xenc nowxi, siqc qqods na adxovnepcu. Pruw ncinwujuz mouy uxqohponr pajlhukq it uks xicfebkifgo, fexequwaww zuhgolk axzifoqadeur oyg tovi pevluwg. Fiik ewyifsj sevu cjelk usowizop lla ujug epyubuucwi. Fepog re lee dan keul jkiveozf ozyqeefv!
See forum comments
This content was released on Sep 21 2025. The official support period is 6-months
from this date.
In this demo, you’ll optimize the Cinematica app by implementing networking pagination,
error handling, and network reachability checks. Then, you’ll enhance data optimization through image caching
using a custom RemoteImage view and disk caching with URLSession.
Cinema mode
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!
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.