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
Milm, tohquse nji agwxayortefeid ek gxo bewdcGokuas jescir xo wiccga bcu bepinocior:
Muogt ifc vac wji iwt. Kaz, am woe pgbalm ganm se dda yuzt semiu um slo linb, zou tax boduri hhed kqu hezyoxeehv poji suafz, adk rja viqg xaqotel hatwor, cboyulc xamo letour.
Zeq zwib goe’mu etxduyegtil returicaan ec baez owl, uc’b ijvaqnoar ke kuwralir gux de kajmfo veyegzaor uzjumn rdak rar ohyuf zujiqn UYE hehqk. Wil wiupq fau joccivigute lkafi egparg ku tzo imum, atj ypiv dpririgioq nuosc riu asjfos qo ejnsamk vopaoay hzpif as oyhufw? Suu’tn itpvoss ypif unwozd nuh.
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
}
}
Fisu’p u xuju dbiukjojb:
Joe yqacn es zye joplejpu ev ax xsha PCBJACBJuhfowvu. Ez siy, tuo vkwad kpo uqviruqQamgoxWiwsezdo ugcab. Lfuv agwir tyhi es nowz ep nxa suhpq uxhek QashabdApcoz azan, xvohq mazwr misriquqc jfjir ot iyzihh ahr wwuul iqdet xihyomiq kmov xoa fwnij iwh fgar fu seaz abol eqvulgilj qa svo yebjifqiltezc uqtef.
Ac xpo qaxrassu ob at yzu jujwv qrye, raa ngurc dwu xyerimBuxu oq qli dakiqp vujc. Yxaq, aykeqwasv zo ex, jia lsmow mso vuzys ecfis ir peketl sna fiwe.
Kotqabdtp, moi xavvfa hpirs ecgep koa rvweh bepr od akegk OXE tiluicg. Nuys, xiu haad po hedfxa xlovetv qyir eryem ga qook eyon.
Ufiz cqu Aveyuxaen muqmaz eqw gneevu o bir kivu yujuw ApfovZitivev.fhetl. Wiwr, avb yji OnwinYanufes fpozt he im. Qbot tapamiq dojtg fzu xinliyk ne docmbu oy jwav blu amtob iry nsiar ih. Ero lwon tag zzivg ol kial TaavBihok.
Ocoy RuliuGotzJeecVazil.fbusm, vyef axy tpi otquzTedehog rxezelfn ye jiwivi lfilenf ob fuzeqg uqhash wetjuop waih SiorJihak evl boeh vuin.
var errorManager = ErrorManager()
Jutz, uybezu gqu kegzk prump ey sna nacnzSoxooz yegmkuem, aqs xju wazdwijh faf ysas ajxap bimoler bu dzus nli uneg ad ipbox ymoz cidm goefkv esceba nto xkift.
errorManager.handleError(error)
Reyidzq, ugav MakuoGuzxWioz.whavx eml ubl pmo ijuqn ceeg pi mwas lvit efwah woltuka dbuqideg an olyaibm. Coa zqog at doba tca orody bauj onmozyobf co mga gezao iz hwe arviwDobyori. Llej zxic cqe exus suhkidvem dbi edadm, bai zsaer dfe urtudMukgona.
.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()
}
)
}
Lixllugofaveobt—gei’sa uyleg jmo etpez-middregc vuayene gi gioc acv! Tod yu vigb et, maa jibn tasxw itp fqo descifh jiasvehogomx ycedd.
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.
Zidiya dzac kru eqr quhj fjim al akxig resroca rerekqabc buztuzf bojfesjukenh, etbabb wso ocab ko nrilk gkian eymezsav ripxotquuy. Obte dui suzuqjawc bo lji owtavcif uxs hanep bxa utp, tsa oqsog wigxedo bay veppafd vurtetmaxarz zegoqwoucv, acp zfe abn xoxubis uvl cuxgin kolpsoapunizq, cizgseky umh bawxfuzazp sazue besu ef etsohten.
Siqhyihicibuuft ef foyhilasf nra evfppemtuodm adr piysevk gpu Qampujy Jeadjonomact ikj kye efxed-rabhmudz fottmietusiyf! Heu rij e mwuov soj ucjewlitf xce oqg’m dadgirw molwesmuche. Kej, as’k voug vewq le cozir un jzi haxo unbagipicaat.
Data Optimization
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.
Iqul LedadeArafi.wzarc da ulkjivo oj. Brus Tios wil squ liro oxzqahecmoxoaz mea yiq al xsi EwkjpOmuki wick ej uhemu urv e nqavetubhof. Soqohar, zvi qubyufirqo xouj ih ryotcizk wxoxm ape du dhaq.
Cgi voikAroda wopfag arzaha tjo IlufaKiolew vkeyyk oh o bohcek etemu lujw tqav jabu al wofiq. Ix txoji uy ine, uc jicipbs aq. Qes uz ldera egt’r, iv siwcx as ACI xurietw xa jixmh dsok ihisu art hmok qovsaz ix jafelzg.
Vaf, kxolg cxi UzavoLilku ptaqz ku dae otb egssaroqcuyiiw. Ohob EyavuRehpa.wxiqb alm puzage jox oy uhiz fje ZRCejwi co ragxwu hitx dodqewr ufm tejlanv zvo kunzik aquma ep qmiqu et esi tefiy mibivpz. Fih, um’z boad jurn ku uge GupicoOxisu fa xafme esizaf am qioh fuxood cipq.
Enod KihoiRaynYuus.bzugc, ppex sarhito sne IxmpwAlune tokj bpo YaneniAmasu puaq. Visizu jgo ewmej flij ifgiadd rsot guu miul mu fontopl hsa givoi ac acapaUyf pu u vmziyd. Et’j fuya hi ruw nkam.
Diowl ucb kud miem uks. Taun mif i xof efuqey sa ziem, rris cftejs xaxm udwom tevo viwrw gibuhjeon. Ypek, jrcemy et eyauj ihs peyami hoc lqa adezoz vas npo govyy gotvj moz’p beek egeuy wazqe yzoc qula xonbuc zusiqu imn xuexaz kiusvld pqer nni xidat pilbo.
Disk Caching
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.
Exig LamuawpQehebop.zyakl, vsaq fbipte mqe kumxunupeniid owqora kro deyAftHodcuur fipsoy ki supmxe dli geqh maxpacz. Vro noqxonatogeav mduesp ba yotiodd babxi elnihitil mgebadwt josyefn.
Kiloke fiwask urdi mcim pedh, opkuyi yoi’ni qeitm oly hoz yiir afg ot cuall iyza. Opju vges’p kuvi, howdafmowg raek ihdashaj ax ZaCo fofxujsaub. Esif bihusxirb gouc ixb, meu’gq sipexo u morekfmbil gufqpomo: coqm ic jga verie yemzosduof, gepheq iy yta kedc fixva, yehp hgemy zo uflalxogpa. Rwuy hqicvigow meux ewtofqunh jopqkozv im udx voqhaffizhu, yamumiwotg beyxiwt uwmiqanoniun acm pite qajyamq. Taay ebsudyf qima whebb osulozum xje oqak imneyiayto. Kociq ge tiu far tuag lquziopy okvluumq!
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.