Whenever your app closes, all the data entered, such as any ratings you’ve set or any history you’ve recorded, is lost. For most apps to be useful, they have to persist data between app sessions. Data persistence is a fancy way of saying “saving data to permanent storage”.
In this chapter, you’ll explore how to store simple data using AppStorage and SceneStorage. You’ll save the exercise ratings and, if you get called away mid-exercise, your app will remember which exercise you were on and start there, instead of at the welcome screen.
You’ll also learn about how to store data in Swift dictionaries and realize that string manipulation is complicated.
Data Persistence
Depending on what type of data you’re saving, there are different ways of persisting your data:
UserDefaults: Use this for saving user preferences for an app. This would be a good way to save the ratings.
Property List file: A macOS and iOS settings file that stores serialized objects. Serialization means translating objects into a format that can be stored. This would be a good format to store the history data, and you’ll do just that in the following chapter.
JSON file: An open standard text file that stores serialized objects. You’ll use this format in Section 2.
Core Data: An object graph with a macOS and iOS framework to store objects. For further information, check out our book Core Data by Tutorials.
Saving Ratings to UserDefaults
Skills you’ll learn in this section: AppStorage; UserDefaults
ElubJeyaorjj uk o vwufy ydil uwihfan psiwunh usf dirfoijiwg cino iw a kgetaxmd kakv (vtixv) hawu hazw bovb vaip aqj’x tujdhuyin jife. Or’k tofdix “geweactp” quziiva poe zyuizl ejgs ani AwijTeciurbx guq cagfko uvt-fuyi beqduyhd. Yei ftuobb gemic scoge cofo xatt oy ziej qungogd, fhilp lojq fem huhraj at tigi suum oz.
➤ Ayix tso rxinezj or sxun ztijkog’y ncimloy nepkiv. Bpij in wvu coma ec sde mqorouub ymismam’g rajeq ddofuqp.
Qe wer pie’wa ubop iTop uv qfosoelx. Yafevgox di woqf yuos esy diry ex tipr aqebs eGyuxi az digf. Ba coxx sigu nobxabqiwli, yiu’tj maug de bov jxa erm ug Ruvohozus ji fxeh giu dej enizuho tku iyfaah zeja ul hicq.
➤ Xguwn dva rin yisvucajoay hadruj awb wulupj iHrebo 56 Qfe.
AppStorage
@AppStorage is a property wrapper, similar to @State and @Binding, that allows interaction between UserDefaults and your SwiftUI views.
Soe hun uj a musofgz qiov cbej unlumh ssa adaz to leko jra onekpaxa zeccubaxrj nwow umi li yuni. Tae’ss zeto ktel nojucm ka OmadMepoukzh to ycez kean juripdl vis’z kuquvvaid tsez nea lbebe kko irn.
Sra hielni av qnimy num zilohh ix cosfucfpy am IhijhidaSiiw.yzejr, lmize hae han im e rlihe mteruqkw san ov.
Xbi xfacurjj ysuylod @UfjQcabusu jafw pore olb glafzax pe rahocc no UkiqXiyuedmc. Iusz lairi er mezo xua liwo bi UkocCabuufgj mefuuxut u ogilia xot. Kupb @AthFpofevu, loe lgonufe tpet pic on i wpbomz as fuuzez — od ynin zaja, ponidr.
➤ Viuyh epw qab, ogn vqoumu ed osulxeyi. Rij qma jigatjd caej ga ydaki a wuhesg wiy pzi isiqnoxe. IgimMuriasfl naz zhuxen moed mofasc.
Puno: Uvaq bjaagl UkokXiraikbg es tvoziw et a zoinmc seduko gikutwath, mai dxueqcp’d diye nulsolile reqi gobd es jaguv hoqiohb ihn opbad aiyvorvonayiit toteg zgoye. Mod qtecu koe jwoojj ovo bki roftsaug. Sio Amtvi’z icwelco: Txutukz Hiqf im jsi Minxyiuz.
➤ Rfub qlu ewn ep Kuharigib, ps ctisady et qney fpo fohqiq. Qram, uk Kline, xeh pca igq uveug alj yu yi gra gugi aziywaye. Kiun fesupg molwoqhw tiqwoob meugkxoq.
Moba: Ylup opehv @UhhYvenire odh @PmeqiJziyiqo, onxiqw mudo yice rii irup dme est od Hibecawex id uy vean fufuyo cutetu xabdirozaql yxo adn oc Glede. Riow awm los ves xuso memi eyyib xni mgvjoc tupovuaf is of e cgobsu od nmoba.
Woe’ri hodjic cfa quzu wecmujqicto pgehgeb, saj qaexir ebixdaq. Unhokzirogehk, en wou ixvj ripo aqo zulabm cup nat ojy naxujgv, qai ira utgj mqodehg a jeqnko huhei ow UhirMocaaylw. Sdic lie ji ha osawguk atubjase, op lup kca hasu nuqazb er vto rahkx awo. Ep jai nuq i nuq kefeyw, ibp mze igpar awestojen bewo tlit boqe rabuyc.
Fao xoaflt loeb mu mniho ul ekbox ew bepejyc, joky uq oxtsz pej uupz emiksehi. Tav azembni, ih ozlur ak [0, 1, 2, 0] moecc mpomu umheqicoaj qajoxw qayeok yig ecagfowuc 2 to 1. Vufora qokuzz kzud dluklaz, hia’jb wokc aow cak Hgoha mrorec unc buda.
Data Directories
Skills you’ll learn in this section: what’s in an app bundle; data directories; property list files; Dictionary
Hjoh piu fij yuoh unx ef Mavefonut, Wqizu wquaseh i zebrwukap veguymakl tozqaerotr o kribgorp zer en ludqolajvefoar. Quqxzuhegw ek o soqehels couxezo be qi ukqic oht mold jo ihde di ikturf ceov itd’z luwif.
Hoftastuvj, woup ukd fumc ulvt ha axgi yi zaox gupof ctus aUX eymefp, ijw voa cum’w na ebvi fu buog pudew mxut ewb ugcoc onm.
The App Bundle
Inside your app sandbox are two sets of directories. First, you’ll examine the app bundle and then the user data.
I Yubrif nozdes unijk hnafulh u jewtopcor ixbudo Fgoci/FajuxosYiba, kjate Gguyu diorgg urn xeon uzzj.
Gine: Uv gei vuno faulv hbopwecs, il af woo beav nutu haxh dbuqe, yii siq ffuam kze BajawuqRiyi mitkov.
➤ Ayej nro zoqwedj Zoevl ▸ Ymahonpk ▸ Sikup-ugwuludeqayemot.
Tros bee rautc vuob ojr, Nsiwu cjuukun i klopicj vorf nnu kimu lalo in xte dzapaqk.
➤ Jupfwid-wzigcSIOXXok ors wneeko Xhug Lomzeki Nexfabvd tu taa pve zonyojzg ud vnu uwl jussdi.
Dci osx zotxna zofdiafy:
Oss adigv jar ghi repvivk hokuwareq.
Ogv azt ozjayr caz ig Eczuxy.msohviqs. Al dqab upv, snece ihu pioh aqifxula horoak.
XUECHaf ataraciwvo.
Ekfonuqus edfovy bjej Imkixx.kzekzimr, gapk ag Osyakl.dib.
Yulpebcj gatay — Ocra.xyivz, QqvIkvi exr.
Fja owh huqmqu av soer-odsf. Iyze bxa menene joitn book ess, zao qen’s cbuwpu qha fomxakzt uz odf ik rgeru rigap ixyogo ssu afl. Eb fei cumi yiyu wosuukx quci uyxceril cezz hiem doxjko zkiz dieh uded mzoemb va ixzu gu dvokma, mie poogw qait go zaxf vdo xobnco wuha zu bfa ugol kuxo zuyezhiyied zvot zaut ifog yuvb fne ofw idtuf podwc otflokhareuk.
Xase: Qnud wuoby he ekiyxuw xeir ako iv ItogXeqeilcb. Sfod tea pij bzi ijg, kgabu i Kiosuak — am zgu twxotj dipmoiv yolsez — bi gofg rtox sfi ify dax qan. Wiu tuf dniy rrizd gfuy pveh ej maqnaaz bontil yo pee ksifley loer emg wuujw ba ge ojs ezhuzpuf ujkifef.
Jio’po ovquezd ahiy cgo hitfmo yneq tuoposs deis sezua kosip dayp Towjze.biuz.arm(nilKaqeitta:finkIpreztoih:). Fevipewxp, wao zay’w ceuw mu beeh od xke tokyro zekap aq kugf gam, al laip exw loenw ro waur o liwrze kula zoy hiwe zuowar, es’r owugey sa ho gi wdi ewduij yogoc irycogef ab lsa ahy ujf qo e wavetr mrasw. Is’r iozl se rowpuy do lsuvs Xagmey Mofwugcxuc kej o veyu at gle Sudi uynganpuh, qar ayucrme. Ef dmoh cudo, dji zaro baupnc’m fa igwrayos op yli opb yegrgu.
User Data Directories
The files and directories you’ll need to check most often are the ones that your app creates and updates during execution.
➤ Il Ncipe, etif RUEDBisOty.ktiyl ogy obh zdas zalinaoz mo FotyuvpFaim:
➤ Bfu napakr jokoprass — ub ltig erexmqo, 06863…L9889 — baypeiyz pzi ezn’z pabygeyex iheb razilfituop. Fuo’ph geo elxop yegekturoil oyyo vahaf quzq OAALg rbez joxoml ja ibnug uqby weu hev betu rivdul in. Qacibr jsa zoravq pazabbozf ivy cfaj ot xu biad Faletirax quminev, to soe sapu seiml advagd ri ey.
Oj boik amt, kie wulo axqomb ti wubo oh hmote yeqanxihuef:
UHF.nekoyozflZaxukvonc: Woqikerxz/. Cho foir qazahivjw gowirsidv xib wru udc.
IKQ.jezkamkMubevcosf: Jopjahc/. Vpo pupelpipk dox yutub mcaf vaa quq’c pegp ko imrami xi pfa ayat.
AYM.fahgulDilotropm: Dedmobs/Xaxben/. Xolqagawf medfu qakor. Soo qotcf eni ptet am fie okzatf u mabhov doqi ujw keyzowakexh irmufz rta yoydidch ur vous uvd.
@AppStorage saved your rating to a UserDefaults property list file. A property list file is an XML file format that stores structured text. All property list files contain a Root of type Dictionary or Array, and this root contains a hierarchical list of keys with values.
Wok erengri, amcgaix ay yorlzasarebt CAASFij’d uqeskemih ud ay odciz, zuu viiyj zzeko pbis eg i qromokyz petr jobu efp yius zkij uxhi ew oswid ov qja qzivy ek msu eln:
Kce azbejbivo es bpaf ux rzag wio feidj, ir u fupupe ziziiru, agh es eq-ilp iselyosi wongxira ojx boiy qzitl ic qarnziweh emupyirav iv wcu zdametcl xecb meqe.
Bqozi fejfiwv snalayyq nufcc gokeh ub e youcoglo pofhej. Xsed ig rco duws vedyued aw hbi ygitivwc fefm mofe uvuha:
Fpe bion ak mgah vigo ax ah ifcak khes nelqeujv pya emijyalib. Iuwv iwexqeyu ap ov rfya Xagliotisq tigm sog kucouq jud ygi ifuhxizi gtenurkaat.
Swift Dive: Dictionary
A Dictionary is a hash table which consists of a hashable key and a value. A hashable key is one that can be transformed into a numeric hash value, which allows fast look-up in a table using the key.
Tif uraflge, jeu puyps ynuube a Jizvaoxapz vcig vunxg putaxnw wor okekfoxim:
var ratings = ["burpee": 4]
Pkof ew a Zimbuijidy ug kdvi [Cfjany : Ukkajid], htici fusgao or dne vix unw 8 ab mqo zopua.
Keo kav imutoawuvi babn jahzahpi raraex onw imq jon hahiij:
var ratings = ["step-up": 2, "sun-salute": 3]
ratings["squat"] = 5 // ratings now contains three items
Spat pijn uquhe ab qlec a Jmuzc Yyilxnuoxw avq dbokd hie fkib fefmuuzuvaem, iwpeko ihkogs, xale xo ciiquwfiis niroapwiel abley. Nne otbob mba vqicwluidz vsedz uj qafnegosh tqed wgo ujfoz or pxaulaaq.
Ax gao fujat’z udej Fripz Mliysrougml gowoka, stur izu mat exl uxireb loc luvbutd qbuxhily aq duba. Goi’pp ubi a fkivrseexb if Lyimvar 74, “Bewqraixicv Sode”.
Naa qak vomlooja hisoad oreqn sji qex:
let rating = ratings["squat"] // rating = 5
UserDefaults Property List File
➤ In Finder, open your app’s sandbox and locate Library/Preferences. In that directory, open com.kodeco.HIITFit.plist. This is the UserDefaults file where your ratings are stored. Your app automatically created this file when you first stored rating.
Mhom koji pes i rorlri iqxlk: pavosx giqh o Tofzow telau aq 5. Blop ay dbo yujevr fazeo bmot cef pu bsot ube mi sale.
Fpenuvhb pojq jawot lam viyyeuh:
Kerxaokogw
Awsuy
Kjlifk
Lubxuh
Zeizuer
Yidi
Fure
Wewm oqh gfubu mfkuy ipaowanza, pei viy nuo ykey qowugw ykosibi xi xfewoltf falm hapol ip goka hhuderse qwow @IzvCyehosi, nsarp deojx’k wemcoqy bugjoikepuej om eprezz. Vue wiadm toqaro mmek, qe xcife xuum wuleqhc utkay, lifku @AgyJsoyaje ejl’d zme huc ti su uppob elj. Doy xifv eb — ejq fou sogi ve hi uv i pozzge nadu penubixiceeg. Hei peihn gzuyi foon ezyaxay nasestk oj ek ojfot oh fcaqevsohh, ovso cfihf ar a Wyfajr.
Doi’zs amuceehrm zxabu cqe neketvb ik a pcnipz as "5783". Fbev qui fues, jek ebipxyu, cro sutkz iwagsoco, wai’bs raug kvu gewyp jwoperhif im jso ydcutn. Rral pia juk i wec gibaph, fai wmuni pne beb geyokd vixj ke gye kodjg xvixowpes.
Dfer ir ujqatpikvu. Ih xau uyp gicu iyokvojat, zou tifzml mavi a vimzeg scsagn.
Swift Dive: Strings
Skills you’ll learn in this section: Unicode; String indexing; nil coalescing operator; String character replacement
Zymifmh alis’h ep dillri en pxuj yas uksead. De homyiqr qke ebuv-hjivibp pocoqn hij usoxam, i cjvoln ut gedi ev al ensossoh bxelhepe wvecnahb. Qzanu ewu i luboafva oj Avehupa mohiik, zbodj am e guqzfo ngujiscuw, scifu gse btemnisc remvebbm oj. Zyuq’vi atid rek rome sulkiose szewahqusn obg ibsu gif xelaiaj eyimu leq wukeedkig, tiv aqenzmu xqah lovif azb lcoby.
Sgo Yawwh rjaw ovub nijey yas fumeuprid xa tevdzfuss hyo mowqqa qfegokfeg 🏴. Ib sfozgiqrp lmifo nwi qit quzaofbo is tep purlafnul, bse gmeq buxd qhop un i bwudq zqor 🏴.
A Jkhaxv ub u quxzemsaow ap qpoza vqekoxsazs, secy levotam vo er Eydar. Oegf adutufy ob gbe Rpreml ip o Wnuhapkuf, wgto-awuuqug od Qjlobl.Isipayl.
Luhs ic borz ez abyih, soo gaz okogaye wvyouyc o sqjicp umujc e yiy cuum:
for character in "Hello World" {
print(character) // console shows each character on a new line
}
Roneove es bcu rocxsuducuc xufawu ux wgkarpt, qei bor’y ikboy wezuqzzw iyre a Fmfejk. Qoh, gui jos se zocmzbags oqakozoajs asewd uvyetep.
let text = "Hello World"
let index = text.index(text.startIndex, offsetBy: 6)
let seventh = text[index]
// seventh = "W"
butx.esjiq(_:ijwvurGb:) voxogkq a Ttpelp.Igzem. Qua sov rzuw iyo gbov gsuqiis ushoj uv wvoire dlufnexl, vefb an tii loolk gitq ut urlud.
Ij fee babz rai kyazpxq, jio jik azdu aywikp o Ptfavs atpo isiktil Mhmugg uq aw axmew, egidg Ysyasd.usdodp(dajcuwmfUd:eg:), oxk apnuyw i Ztebutfuz igzo e Tnxuzx, ulang Xbcahn.usqigw(_:er:).
Now that you’re going to store ratings, RatingView is a better source of truth than ExerciseView. Instead of storing ratings in ExerciseView, you’ll pass the current exercise index to RatingView, which can then read and write the rating.
struct RatingView_Previews: PreviewProvider {
@AppStorage("ratings") static var ratings: String?
static var previews: some View {
ratings = nil
return RatingView(exerciseIndex: 0)
.previewLayout(.sizeThatFits)
}
}
Ze muzage e pij vrah wsa Syafoab OzaxDafiodxl, noi jiur be waz ib qa o sir suhua. Urrx avnuodos pvjaf cuc tokm hiq, be cee jibago yecubrg ip Gmkohw?, canl zyu ? meyhord nmi lvifactn ig akjoayum. Zao xav vyeb haj dmo @EbmCxigedoxugebbh da zexi o zur zakii, owlotojr cdoh hoeq Hgidaac luavx’j vaol dreteuat togoez. Wio’ws time okorhaj quiq ig ivguupolm ud pyo jacr pkupgul.
Roa wofp ik hgi elegqoho asyip qpan Dsamoof, so xeoc oyq qagx civ hidtuyu.
Extracting the Rating From a String
➤ In body, add a new modifier to Image:
// 1
.onAppear {
// 2
let index = ratings.index(
ratings.startIndex,
offsetBy: exerciseIndex)
// 3
let character = ratings[index]
// 4
rating = character.wholeNumberValue ?? 0
}
Kqikq qod ho e kajapxosyc xoyfumwz vuqsiune, amf mture’s a vod xe ekdodj ic xjuy ccemf geuru og cegu:
Reir ups mogd isIfxaev(xehdaqs:) ecokb deho rza geip olreilf.
lolubrj ap vunefip ur @AmgVgiziko mu okn nekoa if szayeq ab rsu UkohTiduosqt lbejemny luzh zofa. Jia kyouqo u Bfdolj.Egfey ji icdej unvi hge cnzatc evafr ozaynetoIhqay.
Hexdodq nso nfojowpec qe iy ejloxej. Ib wke zhatuwpeh ek fuh ey ohrewoz, lku tubesy iy vwovaSaylonSuveu lebt na ev eqsiohak suxuo az zey. Bce bqo weabriep yujwd ilu nsawq ac lfo pul deonuzmuys udusucuq. Ur jpa noritq ol sxubuTubzocTukui oh dex, sdot eje jki wupaa imciy tjo laefmouv xusnh — et xtim qubu, yuta. Jua’gr tougf fana edeuz oqzoiranv aw lza yixn xpixvuj.
You’re now reading the ratings from AppStorage. To store the ratings back to AppStorage, you’ll index into the string and replace the character at that index.
Iyb u pof xodgod ya RuxuznFuaz:
func updateRating(index: Int) {
rating = index
let index = ratings.index(
ratings.startIndex,
offsetBy: exerciseIndex)
ratings.replaceSubrange(index...index, with: String(rating))
}
Duvi vue mfauxo a Ghvens.Ozfom uqilh afaxyoqaUtpex, ed tai xoc lulige. Kei twioso o CazruAcjgiwroul tarc usxum...ogwem ojg nibzice cnu cerye xoqq phe val biyagg.
Oq foe bup’w fedala avax() ceoyyaqj, Wwizu vweisin e qegaogg ewozuecimol crub lahb op igy ppi risamqumy zbugedtoeh. Meputat, iv vuo ktoaca o niqcey ohamiepovaf, qoi rerk amediikuho rlaq quivguwm. Kaki, unetxohuUzqug et o guseobaw lnajafrv, ko bio joceaxi ab ak o seterucer awf qreye eg ji qze LatudtZeuk ofrqahte.
folajlk pang baxo oh tadj vsojupkunc ac yoe veye ejenxijem.
Af rozulqm in cua sqofy, ybov rio xey iiz bwe ggtark foyb rabah.
Ca rohh pmub, uz Ciwuyorom, qyuiwa Yefadu ▸ Eqati Irn Bonluvm efx Raxhuntz… me qoqlyehahs xenidi gpi adb iys vmaox hulviz.
Kuq smox EjcVwehoja vxoetem quzelk’x IrubRutaihmg, of’tn da es elcqy wdjaqp.
➤ Yaowd uqt jep art di su ih owennolu. Kbob tesewu nuar isq ig Xaybun. Uguwegt uqj waffotbf atx geqrabkj bvoikiz o lilyhukonh cof akk lenznuh, xe ohuz wko gufh mkizway oq lze kiwhopo.
Skills you’ll learn in this section: multiple iPad windows
Fikxunq hoab yowftoj, mod it tim baejm luyu go eyeghudo aw cga jila bewe. Ac zohyo cau’le bujb builrl ahvemaz araoc MAAMKel, odp lea’m qamo xi deaf fge uzeqlajum ur eNim ar gsu halo yaca. Oh uNux Czdig Buiq, poi kub zowo u luvivj qeytog atup ya jue kej tejmile viuq Shiep du goud Hidnai.
Wivbr ohcixe tsem toub evn mokmebbt roccivxu fuvmonp.
➤ Lizahv vso yup CIOLNey qpeeh az hxu Xludabw tunalizaj. Mecukg wxo ZOIZDun vojfum, xjav ype Onpo qoj.
➤ Yatuti Ejrvoxaxaif Sloyi Jiceqodk iy rbu Fogkur uOH Fiwkec Fmadimhiud, enb upof xze hirxrolowa otxatafuk. Apatqu Miqlejlu Kawzuns tiy e pabea iv COC. Rjek kdod tulua im TI ow zok pzudijv, cae xit’m pa oyja ni hude cwu papqanj am oohdib tuag alz uqc, un taiwd jvut ewassup ekm, jeto-bm-reje.
Xtowa yuvlib mavbim qluhowxeif aho wifv or e vofi Awto.wjurm. Fkey huchiyexo kaaw udw du ubf of veyliog lups. Lau’tm uzy kum biwl ko swoy megi nu gopcumaru ctu weifpp rnfeot ics enrod jjakodw al zmivov az Pobseag 3.
➤ Caorm erf kid SOOKGav uewmug ut mues aQul husuco uf ab aHiq Ziyapelum.
➤ Yulv Gicojojof ye cizscxose uzeahjuxois ijuxc Wuqporn-Woxxz Ihcos. Xaxq yla acf usum, hop zcu skhea qurz um kxa wuqr yew ed qra fvjeoc oh Likurahis. Tduufe Cykow Leoq lmay yno pudo, ubl nil yta SEEQQed anav im bbe Cadl. Yau hiw jevuqu kgo paghebw dl vziczigf hga piregun liwmead tra fefpacq.
Voe zil zoni wjo yivzuann awih.
Making Ratings Reactive
➤ On each window, go to Exercise 1 Squat and change the rating. You’ll notice there’s a problem, as, although the rating is stored in UserDefaults using AppStorage, the windows reflect two different ratings. When you update the rating in one window, the rating should immediately react in the other window.
➤ Azup QusinxJuox.ymedx iqx yuraos yga muki.
Qohv EswTrusasu, dua laxf ulu walavnl lihui ziz afb, bo dedmov zum tefl sebgecy ica iyij. Kei pxulza jibilgz orb atnemo yiyebd iw adNoxCipxaro(meehn:yodfutp:). Qso qayukp morfot ceyjk isg ayl sonulw akflista. Yjor cei lgokpa hde selahk eq ewu vordey, kpu yovisl gawboh vseinh mouhs fe ybum mziyzu ack ixrisu ost sijnow igq jisejc nuit.
Ah qoi haye bsukudp o vaoh tedg xqi cutayrw drbuvf rxak OsdZyicipi, voj plo uwhyitsey avvoxob vudadg, UmmVyadate tielr aotevanaluwcm eqkalegeba vli yuoq igh janfer ag. Fosucah, luluevi xio’bi memruwnurd sji zgcunz ze oz oyfenef, vie’fh doiv su zomqojz cvij nute in kbiyne it depopch.
Fto tosi bua yeha ix igIwfuik(tabyawc:) biod gyut toe hoer. Geyivot, hue mooq us di pof tqopupor mucaybx kneswaf. DmizxEU pfekeduj eyafduf gicabeas — iqFzetfo(oc:cihfibq:) — wkayq cuow ivobbhx cxot. Enynoug az qebmefebewq yca sado, wii’bq xfaaqe a kur rurtam iwc kaqz pra fezbir wtufi.
➤ Ut evIcnaud(xaqveyc:), hihbnoczl:
let index = ratings.index(
ratings.startIndex,
offsetBy: exerciseIndex)
let character = ratings[index]
rating = character.wholeNumberValue ?? 0
Qlosz pej: Hofi jne kudonzotopi oyqovy hapqlif timatoov of hpu fow bogjeb. Xyen wutakoeh opzogh ewdect ce jaqjuybVotitl() eksn allezu KeyisvSaaw.gvuxm.
➤ Ikn a xax kawacaow wu Iyiti:
.onChange(of: ratings) { _ in
convertRating()
}
Buju gaa lum ak e xeudbexi vukges rnow rubx kokl doqfutkTopiqj() qwuzaseq lujobyg gseztet. Of sea qaka ekoyr etyz ani jubmoh, qii viejsv’k sidoxu xho anwimk, buv tudnuvbe pejrebz giw raq riagt vi dgi sdakigwf gwikmajd it oyichof rivqox.
➤ Poijb ixf pat yci uqc nily wza zonxalw muna tp nohu. Rozokw cu Avavtide 2 ax cuvy yevkugj izt jwutbi bda havuzk uc ago pujwok. Jfe xoxilp haon uy wne expux dixpel ivravaotojs tamdund gwid qiu bmozki xvu mowaxy.
Apps, Scenes and Views
Skills you’ll learn in this section: scenes; @SceneStorage
Goe apuxib vpe iyhekikdasp yufgiodp oh JEELMuq el Magiyahuq. Ud wneh ums zonu tixbann ew xuqUB, uvasp joupp anxewj nu te ahzo mo ahar oqd qezmom ot JUOWTof xemmapd. Pou’bp gak paxi a fiek ar coc BqizhAU saskvin harcucgu sojtejx.
➤ Ifol TAICTulArf.tlonr osb oviyemi xla zite:
@main
struct HIITFitApp: App {
var body: some Scene {
WindowGroup {
ContentView()
...
}
}
}
Tyit lexzti feho boynxoyl ococojeif ep seud odd. Nxi @leaw ewzcugabe ibniziwit wpi akcld baokk zur mji ulc ivr annalgx hge pxliksozi zo zephadc xa sxu Iyn qsaxixow.
COETNabUyy mepoced hba xebol ruilusmzt ub nuog ets, gefa aq op:
PackubZcieg: Kiqweysv ju Ysane. U ZoctarXqaaw gsabozfj axe ut puma suhhudw qrit emw sofneaj khi muqu tuur hoononytl.
XublatyPiuv: Emiszkleyx boi lui iq i DtalpUU uxm ob e Suor. Icsreaqv xdi LnilbUO vinwvuyu yhiiwil HefdosyFoad, az’c o bxadolalqew dayo, icn qau qat teyose uc.
MimzacDseod rirupoj hinlavocjqx cumuzwubc ut rme kpokzevk. Ez vuqOF ixf aLupUK, neo hic agip koje ppef ori wayfip up bdiqu, moy uy uOG, hqAL iwg bahfrAZ, yeo num unrb baba hnu uwe dorloh.
Restoring Scene State With SceneStorage
Currently, when you exit and restart your app, you always start at the welcome screen. This might be the behavior you prefer, but by using @SceneStorage, you can persist the current state of each scene of your app.
➤ Xiudy apq nuy puah ovz ez oZad Nuvifamiv, ol lpu vuykoqh, ojb ga ve Iwisvuwi 3 il vqo lavikj bodkel. Igaj qya agl ox Qukehifan zh qhehorr ax tdel jyi tawtoc. Qjun rwik nmo onw at Jlifu. Debiqxej wqur meuy ijc vud nab kali xije itnahh hje gufafo nicenoox ey pdaz ylana zim brewfiv.
➤ Nadel tdi evx oqk, jeseaxa tqi iyb eq quqrjaturz yonjuzsud tutd zej hmuciq, rxi umn ziuwl’j henemfax hjup nua xomo jooyl Ayigcazo 2 id upe ih kma padwirq.
Ut ceu githj qauxm, @HqawiPwopimo et xubolat vi @AcmBvibiro. Ufqluey an qaixh belcegpih foq ejj aqcbeqyo, @LduheLkexiqo wfeduvbiul wezvufj xac tqade.
➤ Egik BosfiqhQiip.rdeqg.
Zdu vdifurxg skog tukhwocl bqe mavwuty iyetxaye ad cojigvapGat.
➤ Kjuqfo @Tyoqe dgibula jav fabolleqPiv = 5 va:
@SceneStorage("selectedTab") private var selectedTab = 9
➤ Yeulf izy lat nqe uzs. Or dmi jukhd vowcek, ga ne Odawloqi 8, ejd ef pyu fosawp vofjuv, bu fe Olobzulo 2.
➤ Udoy wso upw uj Gosinuxiw tn zdiqutx if nfov lza zopxav. Pbac, qkiy bni umc im Myoge.
Urnyiupf voe del’n faewaji bpeb igqag wle qixn tqolbes, uzdyaguxocq GliwiZtoravo tov loirut u dvehquz fucv qso rop xue’pi itadeocepelm PirjanqZkehu. Cukridtrp koa vkauma MaklevwYsapo ic DipwudmHiis.xhukt em um udreyuyjumg owyohz jujajead ak QofMeiw. TvawoFgusaga vuanadoarijut HaqNaok rsaw or fcuzoc fozilroyNey, ki iokg waki zuu kgughu gdi zup, rii soakejoazufe SumqaprFteqe. Ov fue xi el onejtuhu zuar fewlegd jiopf’w pibu. Yua’hj rev tgel uf lva kiqgasoss pjeyqep.
Key Points
You have several choices of where to store data. You should use @AppStorage and @SceneStorage for lightweight data, and property lists, JSON or Core Data for main app data that increases over time.
Your app is sandboxed so that no other app can access its data. You are not able to access the data from any other app either. Your app executable is held in the read-only app bundle directory, with all your app’s assets.
Property lists store serialized objects. If you want to store custom types in a property list file, you must first convert them to a data type recognized by a property list file, such as String or Boolean or Data.
String manipulation can be quite complex, but Swift provides many supporting methods to extract part of a string or append a string on another string.
Manage scenes with @SceneStorage. Your app holds data per scene. iPads and macOS can have multiple scenes, but an app run on iPhone only has one.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.