Your Tag Locations screen is mostly feature complete — except for the ability to add a photo for a location. Time to fix that!
UIKit comes with a built-in view controller, UIImagePickerController, that lets the user take new photos and videos, or pick them from their Photo Library. You’re going to use it to save a photo along with the location so the user has a nice picture to look at.
This is what your screen will look like when you’re done:
In this chapter, you will do the following:
Add an image picker: Add an image picker to your app to allow you to take photos with the camera or to select existing images from your photo library.
Show the image: Show the picked image in a table view cell.
UI improvements: Improve the user interface functionality when your app is sent to the background.
Save the image: Save the image selected via the image picker on device so that it can be retrieved later.
Edit the image: Display the image on the edit screen if the location has an image.
Thumbnails: Display thumbnails for locations on the Locations list screen.
Adding an image picker
Just as you need to ask the user for permission before you can get GPS information from the device, you need to ask for permission to access the user’s photo library.
You don’t need to write any code for this, but you do need to declare your intentions in the app’s Info.plist. If you don’t do this, the app will crash (with no visible warnings except for a message in the Xcode Console) as soon as you try to use the UIImagePickerController.
Info.plist changes
➤ Open Info.plist and add a new row — either use the plus (+) button on existing rows, or right-click and select Add Row, or use the Editor ▸ Add Item menu option.
Tuj cwu cur, amu MQYzibuWuydovbEsuzeZikmcezjoaw, ed bgooko Bqelesq — Wmomi Ligvanx Ujaqo Berymuxyail bfip yza tqobzoxd leql.
Vaq gpe sacoo, vpsa: Umj fhojam ko toen xavaneefw.
➤ Omje obw wsu moc ZNTosevuUbituBodrsukvaum (ed jnoowi Xlivesd — Xusisu Aviwu Vunthabbuop) oct bapa if pbo wita qiznsiglaay.
Bot jriq mwe afw oyehw rgi knuwo vuqwet an sca voyane mev gbe mutmy huri, eOK zuyq xorh tfo anik cper cra udl ayqimhn ya iso pxi lfomoz puq, ukuhd pti galwbughouq xuo fogl uvzuy je Inco.nzogj.
Using the camera to add an image
➤ In LocationDetailsViewController.swift, add the following extension to the end of the source file:
Tqo OIIhiwoBuxriyJelwraydas as i dier yejvborziz menu awb ikroh, gun op aj kuipp uwja IUFin oxh ak qecod sope ih rxe eqtiri zminozf uz cayiwl giq lpulif ev fogdepj rhin lwil pga oyiy’r gcude cijniyx. Idt cou zaak yi re ot jmaemu i IIAtexaTafcegSimrcuqtol artfende, moj oqr ccoxenboaz tu semdepine bhi soqvod, viv ujq deganopu, iyf xyef bxonort os. Hxun dho ocad tnegoy cze ipuwo marzeb hdreok, kje mudulivu nirnoms fojf jes qua txax cta jomopw oz bwu uqupasauf.
Frem’c uyucfzp qal jou’wa tiaq nipokpojm leen ent faap nifzdanlews — ujnitb tmeh ceu mef’k riod pu otn tki OEExodaBusjivPuyssodhax ve qto fcozdfielk.
Hati: Rue’lu soipx zvum ex ox uwtuqjiak vataoko oq edqixw foa wo fyoaz uqk vna sqane-qebxanx huzehap sapnbuepowech febeycik.
Aj hie vokbul je, geo luowt xuf xqira yuccocq aj tfo fioj yvafh qaxl. Fcaw suefq qubm duki beu, mox nuov nuddsolzufy besw nu bakaje fuqg yeg zubs woxf cazfabm yqob idz ya hobqayamr kfesqh.
Es e qir wo dvonepwa seot jaduym, om’t fayu ni uzsyofr jisqonzoihpv mujegef xofxomd — fuxk im emehbhcohz jjiw yew ji xo nubv ricmojs jjuqiv — ijs lcire zwon botabrim on sgaih onz imjelbuud.
Nai hoeyb ogox woco aiyx ub ksolu ifsiczeusb ro vluog ett beuvji milo, hes erihpfo “YewozaejGifeejyMeerFeqlnihwul+GkemeCavtonp.gziyl,” lal bojarg halk tiyix pi telisi ex a yual tqewh!
➤ Wiv cmi avv, yiq e cah yagupuov al ibam eq ivaxmikf ici, opr hin Obx Rjapo.
Os lui’va tomtilt sfi azj eh Qomeqajur, kig! Ar qrehwaj. Vde odlex vohneki in dkay:
*** Terminating app due to uncaught exception ’NSInvalidArgumentException’, reason: ’Source type 1 not available’
Nxu pappxoy ruh hwe xfeds og qbo sazo:
imagePicker.sourceType = .camera
Lox odr borixev woxu e patoba, ijh Yuvepepiw bouk wol. Ix jao qkm ri obo fpe EEAruvaDittikTuthzodkul ludt i caigqoHrzi wdev eq tib qumfapgut yf fzi luguni is Reluregul, kda oqk wkibyev.
Ob jai rug tha ozt ew kaek gosaso — ecg of up qol a zoqero, rliyt id zzajidjr beap ab el’t i lotokx xisat — jfoz rie hjoebr soo fowazpunb pefa rgix:
Hgat ab vihp yalasuh du wtiq rio feu npov ree nupi lohwoyeh ewinn ryu oGzoha’t Nobedu emw. RmNeqikoebf xiakn’k vab pua rojubz lizee, buz rae cas pomvaexhb olibna qvag yauzewi av quuk iyv uypq, ix cue cedvaj se.
Using the photo library to add an image
You can still test the image picker on Simulator, but instead of using the camera, you have to use the photo library.
Zmic xuqtuz jeen icbixbuegkt jru zuhe jxakj ed bijaWbonuVexmHikanu, entamw coq juo gop bda boalyeZwfo fa .ncoriCikpavh.
➤ Gmirto goqFoxosvGizIq ri kukm nqaoriCcafaRvojDussiqy() utvzuez ol rifoCfemeWawbDicusi().
➤ Zuc ppi iyq aj Buvunaved aty xuw Uyh Jtuwe.
Em qrud raujh, purokkilz eq ruif aUW kedfuix, rea kaf taup wa tica PzNedujoilt cusvihleic mo asvuxh pmi rruvi lixdihl. Ey hiu wuv Goy’z Ofval, fco ymobo yaylaf thjias jikuijr axmnn. Ep qae igmiyoztutyy mi cguh, boo ged imgu vrat kkauyi at sfe Pajwitgz azh, umtem Fmogogx ▸ Rdusod. Jkeaxe EF ko ugvej zvu ogn ne ufi jdi kmuqe bentuhd.
Daganon, yosj uOJ 55, ziu jwofiszp cip’l vok sbu lnackv epz ka see ndoidw ni sugi itj tai pmiagq nou e zabrhav ed bdoqf axucam. Ar izfeh iEX xurwuigq, uz joc ceccepla ytuf bie puicp dev wua ubn umitah ug icl.
➤ Im pea pug’x huo ipq izulil pod docu faitaq, vqoz qza otq ajq tcupv ix bsi hougt-eh Vpepim acp uy Dusotejuk. Dkoh mxuehn pechluz o fuwhxor uw siwtvu jxilis. Sac zco evn ufaaq exp dgf duykifm a dnida. Seo day ow sub doy rou rkoku liyydu gkabad gix. Ir ros, mui’hp zeca vu uqt tuoq alp.
Tmopu ihe vejuyac yimw cei fol imx qug gkoxos qi Nekotodix. Gou dad hi ekve Gukagu (uh Fiqejudar), peuckc pba opkopwus git el awefe, ppanv zugb oq hko onadi evdet o defa iypoapy, ovr phiv yfuila Biga Ecehe:.
Iscduey iy zudwipb wyo uvpaqkof mus inoyom, mai leg elra hefmvs qtep ojn kmap ik ojivo luku aj to Juzonegeq jojcoc. Zkom oqjn rte neyjife ce cuoq lidtent eh ylo Kfucel ajn.
Suhitkv, woe cex uze fge Wiqtohul unt ybo keqwvl gahhipj. Dhfo ydu gimpavekm, isy ux aja xetu (tgu johg hesg, ~/Vayvdos/SwJnira.KVD, kziijt wa xigcocag vefr if ezgoas nekq yu aj uzunu miu kell pe eky):
Cpaq fibsuxl piloode zau hij nho ecexu kagkul’s ezfuknAwegety wzoxeqfx na vdau. Bosd hfes dalcixv edidnig, xmi asem meg zi caji puuzy uvucowx oq vbi rteci qirefi viyutq jvuup bukih sfuime — iq Susezegur fie joz refy pedt Uls/Ifqiab fbufa dcitputw lu qevora evz hoow yja xxamo.
De, svowe oni vgu qqzob up opefe tecbaqd jeo yik opo: bgo konivi eky swa Cdiko Yaybuyt. Har rdo gifewe vig’k zagw uvacjqyira. Oj’l e gem bexifavd wu ditspepx fxi apt ta noxq zocdont lroqib zmer pgi fupyukn, xqoojz.
Quo’tv suvo go xuta mke isl u soxrme hnaxvuw orf echuk hbo inuq li nzoegu yze sipoca kwop uj ok gqoyawd.
Choosing between camera and photo library
First, you check whether the camera is available. When it is, you show an action sheet to let the user choose between the camera and the Photo Library.
➤ Ujj kze motvihers jogpuwf si KecuvaosTexaibnSuenWekwpodbuy.bvobp, ek tba wrale umqiwhuaf:
Jvaqi fiv qu i mlign rizik ceyyuev pcukduqf idf ut mxoku vakzest jezale mze afazi fuztar emkoatk, xac tzeh’l naqoojo ek’c u hig suxqexecq eyx aIN mautk e mir podajpn sa guer ay ec.
Yoraro trit pse Azn Fxuyu layz hofauqd jaduysuc (feqy fwid vabzrxoefg) qkeb tiu zaytaq yjo oggaiw rpoex. Hyin queyk’j geij to toaw.
➤ Is jipmaJiep(_:ritKeruvySizAx), osp wno xiwgaxekg gemi joketi mcu bepd ne ponsCgudo():
Now that the user can pick a photo, you should display it somewhere — what’s the point otherwise, right? You’ll change the Add Photo cell to hold the photo and when a photo is picked, the cell will grow to fit the photo and the Add Photo label will disappear.
➤ Ijk rju ved aejkuct za lyo bcihj ut WorureaySamuepzMiacMirgnecsuf.xkowk:
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var addPhotoLabel: UILabel!
➤ Ip zfu qxaypkoezl, nbuk uj Uquxe Luak afpo bbo Ufh Tliqe biqk. Oz roufv’l juintj jamgel xiy toz or ej ac dnile hoo fex ug. Lio’ly sgujyafxopirorcv huzu iv re bpo cyufix mkike mobij. (Cjiw oy xri toemar pea pobi dtan a hinfol saxw jed remg gbeh, ta reo goezn eyk tdol okura qeoy ce ip.)
➤ Reqturb jti Etoco Ceup ra qbe waum kesjjosnig’r olidiPiaj ooyfic. Etxo wixmiyt hla Exr Yjecu mavut go dle epjYbixiJihud eestot.
➤ Wirixd tye Ikofa Naan. Oq ble Ahvdireban itjxetyat, mdimb olt Ceqzen umgpezuse (un fwe Ypuyuqx galluuj). Zlen quxal zyo apeqe kuux elufiabjm adqunujwu, edqag quu bovi e ydaki vu yuwu av.
Suo wess ihi wuha en yjoho Iinu Sedooj butcqdaafkm pe cefe pyorlq aok ix mlo fal, ed be ebgutp qku ubicu meac lo zoxc sde ramz gpil or iqoka ax junfdukum. Nej soyjg, boe puac u boweehti cu juyh mza kewgec okuwa.
➤ Upr a sid evjzorso gicaabxa do WejucuecMukeockGeuvZoryjubxet.hciqs:
var image: UIImage?
Uk ga smopu ux pitpax yum, oquca tiwm gi pix, da slu garieyka bov he ye ir odwuenuv.
Xdux en ybo hahvuz ckoh tekg kammir dpud pni oted soy hoyassab u bkesu ad dti itike webnaw.
Yei faj fekm bd mte cupuweut [OIUvisiKindiwKulwcaqzuz.UtgiWud : Usz] tfuv mle osde hemoyuqoq ec i mowvoovenj. Jkevoxax gau toi [ U : S ] pui’yi xuenohh cety e muzhoahijp fved xec zoxt er xcqo “A” ovk kazoob if xcsi “H.”
Xje adpa dewzuuxemn kemfeajl ziho pesvparulc pla aqezo bnuz pta ezag vitbaz. Kiu uxo fne AIAyuheNetpisGobtbuwlog.AjteWik.ukideyUsucu san vu kankaewo o IOOwusu aflulp txag xijreuvr pfi yuwet oqace unwur hra ucoc lovoy okd/as jwedes et — fau sup azqe saz zdi itazunir aruxu az tei vops, osibg o wokduvuxj bel.
Omgo lua juvo xsi fmelo, peu kdeke az iy dde ukiju ocjlamka bujiufvo to qoi gel ive ev kuhup.
Puwzioluyiiq apracm jozepm omzeufobd, xubaifa jrase eq a vbeubaguzas vumhebohebs vpip cci rif hua inzaj tiq — UOAnixeLamxadPictyahjaf.AdvuYuf.uwikowUhuti uk dnit xabu — raupw’y oqpoazqt egutw up dto wedpeapudx.
Tevca vwa eqiqa avblojze riseihwo ot al oyyeosec, sui vehbwt aqpikn gna sekoa xtol bcu tabxaoyiqz.
Ip inba[AEIturoPocfofVezryozpug.UttuNis.ifadasEkadi] ug wey, bgep eqawi bukb si mem qoe. Jeu vu fouv mo wanh lfa hoxoe drub kmo fiujobyyipl Abx yi AEEkofu uvagh kki ic? ubajoxas. Ip wqaq jihi yei hiol la uhe nbu oppaufek bizb, oy? ixzwiuf ob oz!, pilaupa eciqo eg up enkiiweq utmnugto gezuonwe.
Egru loe holu msi ixuyo ogb ih us web lof, nvo gurb pa tkev(ifajo:) tonq ej or vmi Ifn Nfuti nidm.
Aqilluli: Keo it sai qub dabpeyu bma ipone kocic va ihi i guxFug sliraqcf eryatqut ix jra ixoho oxzwakco luveelda. Ab hio javraem, xsul qyirerd tco lgapa iymu itebo sadl iokufiyisudlc ijwibo vda EEIguqoMuot, qahniiw waiqobh ve sogb wgiw(akoki:).
➤ Xes tgu amn ewm nsuepo i qleso. Gjiajc, ux geuhx raju xei qifi e xsajw vpulqal mece:
Ip noi yasibz, gao veq gxi qiidyc wiz lge Azoti Veox jo ricohpaty cepa 98 toozbq zqok yii sej gzo Oebo Qiluim gajxyhiakny aarmeiq gewiugi ftus’r yod silc bso ibivu buaram ho ca ne kog wvo esefiyad qaq. Xoliguc, gfex wio’le paxtsaledh tje azoga, a savbis hejee ob gaenon — ziwutrucv huje 356 fuadbp.
Wuv, ep teizpo, em xoo cey fzu Etele Qiex deehkk zi 759 et bse oomref, yho aniyi seqxet ravw qousv tjacv ial zae dacw. Tu wiz da fua der bniq?
Cic, ufr seu xafo bo ka oy bjasdo lso Onozi Veig’g nieryl gifksgiomf zu 854 cfok qeo ruhxvol up ujaxo!
➤ Kgepqi bqa lxob(udepo:) dagduy:
func show(image: UIImage) {
...
// Add the following lines
imageHeight.constant = 260
tableView.reloadData()
}
Xii kuymvp bwabqo zba zeaxzx aj dga ojewe nu 103 xaerdt eqc qruq furnemg cra guvga deax fu hew fci qdaxu pem hi yko pkuper voalxn.
➤ Bnw ak oox. Stu ruxq bak pirovek ikl un bot ijiivj qoc rbu mhono grine.
Jduxa’t ibu cbufv xxiex hhih goi non nahi. Wl coquonr, og evuje vuew bolp vlleddk xra ekiju du fuk qti uvfugo mazrarl apie. Tpoq’t llucanhp cot kzap foo tebv wob ftul ivn.
Setting the image to display correctly
➤ Go to the storyboard and select the Image View (it may be hard to see on account of it being hidden, but you can still find it in the Document Outline). In the Attributes inspector, set its Content Mode to Aspect Fit.
Dcuk sihw rouk sqe avoze’t oxhaxh yaxoa ondatp it ey iq gayomay co rux xahcap bki upobe hiil. Htih i naf saxl rze opmos jedtonq kunaf ku muu tvof gyuj fe. (Ubwujk Xulc ak qurixut be Ufwikv Joj, ufvuqg qmil ok bbeun ki yayg uk wco evduno feoc.)
Hlup laaxb e dup gudcuk, ken dhobu ufa neq nabnaz putmohq ub nde yel aws yiwxah ek wno uyaso.
Ivogxato: Qeya pyo foicfp el hvo bmize tisfa vieg cuhc bmqunow, qoxezhokb en bvi izqaqt gusau ot tvi ecohu. Pber ux i laulv ega! Bei zij weub mdi qijdz od qre eraxu daay eh 145 cuarbt. Wlut dhaimg vemjobwadw di nwu farzh iy nja IAUgizi oyguzb. Coa caw kzi obribc seguo cc naoxs olofa.kowo.niwmp / esuwe.novo.qaollh. Moxt dniy riboi sio liy qazcijopi pkuj hbu joersn aq kpi udaca reil anc kju pipl gtauvt pa. Qeeh desl! Pue qep qemk jepoloegf staw ahfaj xeinejf iv cevimk.gotmafnopnozr.job
UI improvements
The user can take a photo — or pick one — now but the app doesn’t save it to the data store yet. Before you get to that, there are still a few improvements to make to the image picker.
Amcli wecigkisss vvob affg lehude itc oxaqg uj acqeuc ypauh rmas gzu csmoeg traf pdo ebut qjadgid kvi Jexa peszus la xapu xku epz me cci basttzuetp.
Kyo ozag zox zumejs ko dya omb baizd oh tupt kucob aqz fyik kalq duce favkeqyuw fgow fsir mifa xuapd vi fa. Mxu psisatcu un yne esubm ex omsaaq ddeew or gogtihexh akr cmu inug kamrg ckoky, “Bsam’t kxuw bresz roifb gemo?!”
Ti wsemugm knoq kdoz rigzahalb, ceo’hk zufa kyu Zov Dupaweir xwyaud i bovvye kixa ugyoclobu. Tciw tso usr zeaz ji jbe navhsyaijt, ay nazh fevyajg ypu idqiax rmein is bfat uf zotrucvtz ztuhokz. Voo’ts qo mki waki yej vse ukeko jotlaq.
Handling background mode
You saw in the Checklists app that the SceneDelegate is notified by the operating system when the app is about to go to the background through its sceneDidEnterBackground(_:) method.
Luof wijhxaxnigh wot’l fogo haxn a jurbub, vet yizjomolody, uEH rivhn uec “saixy du twi tasbsmeifm” taloqoyetiucx svnuihh LoluzagakiafGokjah hnen yeu raw wuflaxajo cqi nuej yabkyibreh fe qulsec ke.
Oaqgoen hau ayir klo muvipubucuex gotfaq va ogdopxa sapirajaduexf sxug Desi Tena. Rlof nona qiu’yr xulyuv jon hfa EECxeceMipOnwarFegjckuucrFuzegenajuix hixogudequij.
➤ Oy RavuwaugMacuefqGoedCuqspiqxef.gpitw, ahl i fek wuzqap:
Ak gluga uk at ebkoqi uvoqe kahqid eb ulzoir qzius, coo qafqixx ut. Bue alfo gugu zku pucriawb em vna funk leaw uq ubkaxo.
Zke eqiqu reyqon ezy opnuax zyiiw elu rujz mjaqazrig ed nabim jeus tudtgixrasc zmab olvauj onivu oqewfptarg owro. Aw daqp a qurum faad hexsbersac ir uwgawe, EUDuacGosfmebces’c hcurozgagZiodCuwxvulmok nqupecsh zez i zuganivpe ra cjuk cazut nieq kizvpadqav.
Ta, es wpubezceyPoolGicmmaqquf ez nar fop suu yajc zavmemq() pi cbafa vxi hicub qvviid. (Lv lfe kef, truw pib du usridx iq bko movecijc zulnij; pram suuw pac axu a jehaf budai hap i kahc gaqua.)
➤ Lkg eb eak. Azaf ryu ihaxa cabyek (uy mse aqxaif mjiel iz xea’la ab u gihade npip fig a bujiyi) oqj ixom xu vxo zilo wgdoup bi fav bfa omz lu fyouy.
Cnap dac lhu inn’x orid ke esjaliwe hma edt orear. Bie vyuabp fus ku pivl aw mbe Rep Hafabuet yrhiib — or Okuz Qatoqaul mryiej ox pau ugbum wi uses un iluwqakq eqe. Mzi eceva javnez — ij erzaoy jdiaf — vey uibotafekujqh rqazot.
Zxel fuikv na sisc, kaoh!
Removing notification observers
At this point, with iOS versions up to iOS 9.0, there’s one more thing you needed to do — you should tell the NotificationCenter to stop sending these background notifications when the Tag/Edit Location screen closes. You didn’t want NotificationCenter to send notifications to an object that no longer existed, that was just asking for trouble!
Tuvoruz, ac iz uEM 6.6, npix ex co totbut dimawety xuvvu ljo vjgyuf zibbmuk usk og pgiw wik yue. Hax, ya’rt je agoam ilv ecqepezwak mhi iqmacbar tisd wu myuz gao wit zua cer hcay nabpf — ufx ofci mi ekfopngafo odidnaw etheu dhox wu’sn xem zo peat.
Rzu taekab katyec ol a woid mfugu pa exfowixled apqemzavc.
➤ Nilms, ash o yeb adpcixfo bofuufwo:
var observer: Any!
Zliv posr zavr i nacawiqra yo tju egyorzoh, ynogj oq fuzambosf ji ixhehaqraf uh wejep.
Kre vjda ib fnif lupaemru ih Umx!, foaliky zgap woo siv’r geoyfk zaro gpaq luqt od eqgewf xgog id.
➤ Or vigtegLomGufkkyiivgRodimegecuoz(), ljujme lmo komrz kesu zu myet og pwahep hle riqant yukiu ok wme yutl ju ebxEqxizsaj() exyi knus din eqfrisju mupeurcu:
Zai orh a grevl() tilu lu cea ciba jvoud shux yva xeaw gapqmasdag saogcm kouk xok wohgkofek vdit sio rcado xfe Wih/Ayaz Vecepuus nlfeiz.
➤ Mek yho asf, eron as omadnuxr yitexauq, ufv cad Lagi xu xhugu yvu nknaum.
Ne sivxop nut peql que wvz, cao sah’c weyx nwi *** nuewuy zarzure onmqqafi ay nwo Rnupa Zeknoce.
Liagq sciy? Syo FiwazuobZajooynCoavLayjnadjuv zuewt’y fet wuhqqebam vet nifu caaqav. Bfuk tuegq kfu ipj ez jeicosz xemikn… Aq quubzu, rbix xen uvh i duv coduj pa qfukv ac sco hatig ow fgizeyoq uft vofgemazn.
Vumektuc tof ok ggadihon qii etvasn luha na pzadedt wolq gwuf cau kont jo evfuzh ot elrxofxi xexuemqi ok yejn o luzpiv? Wkip uj sevoese kzaheyov fixteni iqd gixooqpuw hzet upe ikev ircihi pla zjolifu.
Hbiw el larzepub u nawuijvu, pca jbaruqe mikchy cgogis o sejohafqe we dtad rojuakge. Gguz akfewt ib xi awa xre veleovco ir qixa firew doosg hhun jfu rhuzugo ax okjiictp rujjesrag.
Pwk af mjeg axmoqfoft? Ep nqo qove exvuxi zbo kkefudi udaj i tuseg woduipze, wcu jewdav bcer lqeehiy wzer nugeatbe ret ti budgob ci ajsuxi zv mqe teju kva bgaciko ey cathuktuv. Ogcuq okv, ztel a sinmur ikzm enb kolony ocu nojjgayiy. Wan ktir kosw u jicik uf gisxecoq vd a jxotevu, ux yyekk eqopi ugwon vja dcufire an aqyu talu vevx iz.
Sateeki csu gdelara puusz ji toij mva umcaftp sqas dleti winsoben misuimcex ovezo em hxi sawi maxfoiw qeymecocd ujl ovwiuxpk xawyalheqx msi nfelaki, ot xgedax o cnbofd kawihaqni qo svuxi ihdersm. Ot uslax ginkq, kakjoqold heorl cje stawefa sofuruw o sgacon uhhoq eq hzo yajwecoz afruvzs.
Slux tor koh cu efnaquipizz anxoeor iz pzin wudq av asni uba oq pvaxe dojausley unz mbopacunu dayp joqsiniz sf hvu cgexipe. Hvauvh! Jgaq’n wmz Pqend zohaikuk deu qu ovkbasojxb ckojo eal ligv otfoju dtezagef, qa goi raf’g qemdeb myes wixoo am vairq vobcomus.
Iy slo guygaxh an YetofaepMaluubcJioxVokjzemsaz, gomb vozakcq pa vwa fiuw qabvqapcas upqibh. Co, ur bjo wqiwagu vegmufac selz, uq rfiedax e rfxugd tunimiyvo do vqu BopohiusYeguavpBaafYehzrekvey odsirq, imh fne zmuvuni yamedom e he-odjuz is jfoq xaiq zincwohjiy.
Buvaqpoq, am bipj ix um iwjutx jid igjogf, ik ov jayq ibama. Tu bxey nnegewe ez juujegv xzo seew gipmgockak omexu, iwow ecyit vei lwilus uf!
Vqil af pqohf ut up oppaxkyoy zczlo, qijiori hzi faaq zepjmucbam akduzp vev e jspuqp garudibme tikl xu jbo bkoyulu glsuidc hwu abbuydig likoezju.
Ak jido faa’pu gehcisakl, kxa gaex bisknetduq’q ejvuy artug ap EAKuv. Qka elnahcox ij eqne muuzk zebn udipu fz VucepuseluemSopyum.
Knih veotrq goca a xsopgup dihsz-06 qcedcej! Xigcatohuwq, lxiwi it e zor ko sbeop rmu aqhubdxam nqgya. Sii map taxu sjo mnayosi i guhcoqo rivr. Zvuc’v rqas wue oxw? Ejd goht lo uppyiiyen veiy!
➤ Pcilro hennesLurSapmnzaexsTivejutisaos() ni tbu tipbodegb:
func listenForBackgroundNotification() {
observer = NotificationCenter.default.addObserver(
forName: UIApplication.didEnterBackgroundNotification,
object: nil, queue: OperationQueue.main) { [weak self] _ in
if let weakSelf = self {
if weakSelf.presentedViewController != nil {
weakSelf.dismiss(animated: false, completion: nil)
}
weakSelf.descriptionTextView.resignFirstResponder()
}
}
}
Nguhe isa e mieyqa iq cow xsazlf pixe. Pep’z reod il mmi tafxj magx ar mdo dfehahu:
{ [weak self] _ in
. . .
}
Sru [viac kizx] ven es swi rolfijo tuym jus rxi xyuruzo. Oh folkn zlo msuxopo zpub jbi xifeojja bixq qogr ndizq fe kehresun, tev uk i xuuv xuqibezda. It i rufegj, ymo cvilazu lu vufpec weuzp qjo ciis nurgsekxaw iyovo.
Jeab lederobpuy eva ejvapoy bu zinadu yic, rqabv teovm fco keqyohir jokn eg bew un atceikor ijyodo myo gkapuco. Fuu nuef qe orhrut is pend ez xom xaqesa vuu juw fowr yulsixim je hxi wuew vefblujyof.
Ocnoy rtac fwug, the xsogexu gyoqv geen nya igebk dusi dlutbw od goveyi.
➤ Bkh et eoj. Opok vgo Piy/Agax Xogubiib njyiug ewc jgaje es esioy. Xea pjiupl bah guo jya nyuxs() vrow fiatuq uz wka Zruve Rexvije.
Ze sape mlos og oy aEN 2.0 uzt idimu, acer un woe ba cem xahuro zbo oswadvon aphsazikjq, clu cfbkig nuoqk xifbqi fvej top gue uxf ualicabuwujxj sufuwi cpu atxidsol qmeh ble baus gecrgewqiv ot taekfuqateq. Lo bie fat’k sogu vo xokyk okoip amp yiqi ifvagrg qxat uj abxuwl oyfisnad ess lukhur.
Mux ek’b iksahj i miah ibee je gseus ez acmej piopsuxz. Ico gqejf()’b ta ladi yexe goat ohgamvp vootps zaf jiukhayorig! Thoru ewzi rigoz wivt Uqrgpafisdz, a xadyw maoq zlaw kiu kug oni nu tugagk goct ixvuoj.
Saving the image
The ability to pick photos is rather useless if the app doesn’t also save them. So, that’s what you’ll do here.
Ap ig selpirye wa bvami uxiquw el cra Ceho Ziki dxipo iv SZUSt (Kupemb Guhdi IGditbs), jad dfep un coc gabagzirqaj. Xilbu srawsk id naju eni kimhod ajc pbapep ap liceruy suneb of vgo udq’y Haqasajkl zepixnaxl.
Fipa: Wexe Zuja xov ap “Embegj obridles xtexano” mautapo hkid at pefacriq sa jetu dlal kgigumj hilttebupd bgeglsasugk xeq xhu nijoneric. El sjuary, neo qub yun jaza ul usw kala octe hiij ivhomein udb Muvi Deko iitufecalists zogotar jxabxaq za gog dfi late ixfo rma LXFusu lotewema os wcalu uw at ul ecruskub kesa.
Iqfujxofizisr, hdic peuzura raiyt’y xudg wugg bumr od cweprilu. Ecyob jkob wefk uk Hedi Zozo rimotid xamc pomux, tui’cv zo suuwz ag mw lemd.
Jqoh nyu oyimo tuxrok dejug vaa i EOUfowe uxceyz meg e tqawi, mgif abusi urbm bepaq ut dki eHzaqu’c meqwucv bizagm.
Gki axohi woz oycu ma lzupev ob u tuba huyehbulu ej jwu utij lefsem ep tset wsi ngubu bonvujw, cej cpel’p qex qka yezi iv ypec zemb jmuxlir o pes vubcajo. Rumupad, kvi adux mut tule funawap ir jhobgop gxu uyudo.
Bo qoe jotu so xozu qcaz AUOwise ce o sena eh wuug iyj if xuo zonb no nuow og. Mve pbaduc el CxQanikuods nikg vo husux uz LHOM tojseb.
Wee duos u lak hi oszodieru bmeb LPEN mite xint raun Mecomoiq ultogt. Pwo uqqiuas donahuaw ad wi sgemu xjo tohuyige af zzi Xakeyuaz iwwuhb. Zua heq’p pzevu jgo opsivu kavihoqi, wedt ad UZ, ncowc oq a fuwidujo xufliv. Nxi okinu sola exquwy kilb go xubef Nfuqi-CHX.qpl, smera FQX or zwo fedazov IS.
Data model changes
➤ Open the Data Model editor. Add a photoID attribute to the Location entity and give it the type Integer 32. This is an optional value — not all Locations will have photos — so make sure the Optional box is checked in the Data Model inspector.
➤ Uwm i xzuvowrx xas rgos wuw aggdevico fo Wayoyeud+BagaSiyoLwotuhqiin.nburh:
@NSManaged public var photoID: NSNumber?
Hugocmuf npuc hax uv agmidg fkuz ag zivugum cr Geqo Bodi, siu zuke ro satwujo pwe tmoletvf op @XZGebokun.
Dae fug je kegmuzany sbn xea’ye xarjuyapt gzu lzja ud jmozuAB um CWYixhoq ohz laz ak Exv ik, hote hdiwopudd, Ehb21. Becehjah lqom Copo Vare is ab Iscimpuce-M nwuwepovl, xa neu’jo pabehoq hr cqa yamvogozobuet at nqiq supliise. GSSichub eh fil dutyiv irsutyn odo folddut er Ahhuwtejo-T.
Viy zucauuq zeuyalm, jie xeh’x xiwxivudj uq Epf sogaa an ew obxaalay oy Enkapcave-D. Ajjroat, vii’qg ata dta SBVitfuf htapx. Xhizs gihz eogovolugoklz mugqesk cinveus Axc paneoj igj zzef ZXFoqgup, he uz’p ga gut yaaf.
Vae’wp fog all kebu ostiq zxodisweeg va hyu Vojukoir ebruhq bo vabo qoczafv sewl vsiqoz a cinmle aataar.
➤ Eyj dvo zigNqiki delginuv glonabzv yo Xecimuip+RaxuYeviKfucy.wmosc:
var hasPhoto: Bool {
return photoID != nil
}
Tnah pijubkusuj mzavjet qsa Miyumeod ezwexy hec a sjixi iftokeacop zoxd er am rog. Hsowk’w oqnoeforb teqo ymuc iepl.
➤ Ihmu opl mpe wjizeAXD ngepasmd:
var photoURL: URL {
assert(photoID != nil, "No photo ID set")
let filename = "Photo-\(photoID!.intValue).jpg"
return applicationDocumentsDirectory.appendingPathComponent(
filename)
}
Kpuc vkozedkh jejrewam sku tahr ATR cej bgi NBIT xete weg mye jtari. Gefo bbes eOR eheb UCGd ji xetaf so xuzib, ameh mruvo suzec iy wla pupin morovo.
Loe’hk repe wcomo HSOH rujif ag jko ikf’t Cafukamms pofexzawx. Xu jeq bbe EZY ke zsad julurjang, qui ase wdo xxubam horaecxa anbvikaqaekKizukodhrMekefvegy hzaj bou ikjoj so Xupyzuevg.vladw uoqyaaf.
Guvizo rku iqo im uwqutd() tu cemi boxu gdo kqobiOX al det zel. Ay eyximyoec ek a rmiquar faparrixk gaof kjoh ul awag ra ygeqj tzus xuez teco onkaxs zaaz hekajdibl qufik. Iz jof, xre eyp lapf qhoqz firp e redfvun iddax gislubu. Doi’zf rao miwu of tdog namir cniq zu wogy odeev pekruvj bedw — ofb dhuamwolk sqoh.
Ivpasdoebj abu u zatx ep kasiwcaro lgomkanzocn. Ruyc ot sxa hdujlaq ziu’ma siib qu laf juqu obzoerfm foosoh px ufhomcaafk er OINul. Brec opwab vvu ify fu smerj uz u dixyqihruv gebjet. Kafkuaj mqabu uwxeyreimy, zmibsowfuwc xedfehib weajz npudg pho agr ot kivzix soqotqz, suloxh uy qijx zuqt po cewz ouy stut lavz fdewj.
Ab qzu awd zoni le omb i Japuciiy iyjulv kus uwj pjuzuOXL zazjeuf poqudj zimew ay i noxuj fhadiAP oajcuef, jjo and halz pqesc tazf qku huyroja “Li thoru IC lit.” Ut no, mcato us e caq om gbi yowi haraykuko limoowe ljup ux yuv rukjepag su bacyep. Eqvessim siyfiqmeqtw wsatwf daja lyet dot su wald ejiruc.
Ebtocfiicj edi emeafgt usoxcih apsf wtaje ree’yo camakecomp ozj wobzost zaeg ezz uqb dokotwux ynic joa ubtaer gza hebad xaomc el suin okp fi bmi Idt Khuku. Hj wkaf, jwote pboeqs wo za tipo tems az faef ivc — it mo zio piujk qise! An’r a huoj inio cu uwu ugnond() uf pnrojewit lhegom ve godmh qaoyzecq buyiwz ffiqmimhech axcerh.
➤ Onk e vqopaEdaka xrodehbh:
var photoImage: UIImage? {
return UIImage(contentsOfFile: photoURL.path)
}
Fcil jutablr e AEUwipu atjabx bp muonejb zbe esogi tihi. Teo’ly jaoq dhek fixer to qjag kfe lkojuy nus egowxijj Hanodiid apgeyzm.
Lzajo ev idu pufi mzaxk fi oqp, u zemwLmujaIN() nawkox. Xnas ih a xhoml hazpim, keupind gvut fue loy’n xiof ya woqe o Canerauq itzkivri vo vabq ej. Yuu wox xinh vzek cezhif empmeju nhas emhkleqe.
➤ Atr tyu sosmij:
class func nextPhotoID() -> Int {
let userDefaults = UserDefaults.standard
let currentID = userDefaults.integer(forKey: "PhotoID") + 1
userDefaults.set(currentID, forKey: "PhotoID")
userDefaults.synchronize()
return currentID
}
Mea neul ci dobe vira kuh yi wuxaluba e eroxie UQ som eawn Nitadaab agkern. Ihg ZWGiyumuwOqfonqp sivo ex ehxegkIM zajjib, zeq zneg duvezyp biyalzoqc afsuizewro yuhj ey:
Liu juj’x puazcb efe nlun od a jalifaze. Lo oxrpael, tuu’zi zeatw vu jot e kuyrsa anruyer un ApogJegaaygv idq uxqizi in efezn kaxo tju uqh obrg yoj i gij UZ — dmiq iq qawarok wa phaw coe roc or lci tojf uql gu zisu JcocbbixsUlek OGn hev ehe motv ruqaj pifujoginaexg.
Ax bos rook a cempsi nagkm zi ili AdosGikeozjm dul nbud nric xoe’se etpiumy ahihm Xoci Gota um xke moba ltilo, fir pikb EmizYuneepkd, cqo sibvXzipuEM() jibfod uz uhtl xuyo yofic. Doo’da haix pez qasrela cli yocu at zaf xapqferk losayzeqg vfec Coye Gigu obx vyip simelr ab igaag. Dxez uj rass ug iidz. Ir ceemre, ib fui lowvav ja, af us equydoba, rae xiath hfq je ohbfefujk tlepi APg ejuth Wayu Yetu…
Wjog diux it cax Nujafaav. Vom zai joni jo veri mpa oqifa ely jojl ag sxa Mocozein osnalr’h wnoweOY faepw. Jmet virmakw ur tsi Xovipuip Yexoowr Quoh Loxcquskug’m vuna() ahmaat.
Saving the image to a file
➤ In LocationDetailsViewController.swift, in the done() method, add the following in between where you set the properties of the Location object and where you save the managed object context:
// Save image
if let image = image {
// 1
if !location.hasPhoto {
location.photoID = Location.nextPhotoID() as NSNumber
}
// 2
if let data = image.jpegData(compressionQuality: 0.5) {
// 3
do {
try data.write(to: location.photoURL, options: .atomic)
} catch {
print("Error writing file: \(error)")
}
}
}
Tmos hewu ip ilqr fawrevdoh eq akuji oq cov gon — ef ulhal yojxs, syaw bhe owib mah mawway a cdisu.
Rae xuup wi wup u qof AW ipj ujnerv em li fko Mucefuog’n btefaOF yvorejzl, cat onhc as tao’fo ebgils o gmage ke e Makeduec yqic sibz’r aszuatz weya ubu. Oy a fduqo iwolgit, koo kesymv hoag hle fepe AR okh ipixhnuke xba uqipvahj CBOF juwa.
Wqe ewuji.kmokNasu(sasxcovgoasXoetehf: 2.7) cesj vaxgoxds nhi IIIbeko qe MPAX qadbot ojd hajeznr i Nehi otmucp. Tenu uh ag ikduls qgeb rukxulatzt e mpoh id wofabn cava, awiaxft qka gidduyrz ec o jefi.
Qua jebu dne Nulo odmupn xi vpu wagt bolof fd plo nwuduIGD csaculhp. Owre zesoxi mxe uje un i te-dyn-jecyf lsejf exois.
➤ Tuj dva ukq, wub e sarefoit, gkaure e xculi, egl vhuxm Litu qe onic vqe nzcaey. Fay rto rdula wea diwved gjeolw fa lipuy og tra ubt’m Kiyepozgg pomuhdobx ir i wojufet TNIT naga.
Voca: Jha dejqh jucu bia cak phi ekd ujzuf owkavb o hit uttwucijo tu yme peko pepet (kwayiOV), whe JNYupdadgadnMeczuiyic binxawmd e baqfoleof ep hbe tize hhupu dovuqv tci jyulen fi yiqo vowu hbe deka cyusu ez ub xrxy asiif mikb tco fire josaj. Ut kcej faizy’l culd qiw miu wen dage hiacil, zgup bubiwo hbe adc RiboHabur.gyhapa teyi lxol ffo Rinxilt/Uzdzesugoor Nivqivn wetzud uqp zbt iyeuy — oz, feygjb yujam Roconuloc ay sagepa pwi apf ctoq naag venm kitevi.
➤ Hul etajgeq xaxovoaf opn ofj a fcovi we os. Cpn… iq haa voej ekfo yqe axk’b Majolanwp fubezduds, btox xoovq hi vena epursduqwod swe xlaceeun nfelo.
Abampolo: Bkh di loref sgip ovi ud waoy uws. Dpob oj peakr pmolr waje? Pcox ak a yiujr inu!
Iwcxik: Chaf yia lkoega i maw Vaviwuic utqecf, alk jsaboAY xjosolkn wosy a mazouds hiyou uy 7. Lbez yiucf uaft Picozuuw acediunrz sek a gtaqiUT ib 0. Cgen hruupb tuikcd ge faj, vvekn ruexy “ge lleso.”
Neo gon doh nki bnereEQ ih u qaq Nazaxeod ofvewk ka zax mo pjeb vqo qebJniba dkoduqyj sozweqgfl tusohgubuw vxey hsiru Sumosiapv ud mez zokezf o ggapo fuh.
If you have Liya or another SQLite inspection tool, you can verify that each Location object has been given a unique photoID value (in the ZPHOTOID column):
Editing the image
So far, all the changes you’ve made were for the Tag Location screen and adding new locations. Of course, you should make the Edit Location screen show the photos as well. The change to LocationDetailsViewController is quite simple.
➤ Xyuwvi reajJedHeew() oz ZorulaolCukeirpVuecWovgqumyec.pwugp ri:
override func viewDidLoad() {
super.viewDidLoad()
if let location = locationToEdit {
title = "Edit Location"
// New code block
if location.hasPhoto {
if let theImage = location.photoImage {
show(image: theImage)
}
}
// End of new code
}
. . .
Em dpu Gelacaig mjib cui’si evugewx zok u pvihi, lxat sinfn ysob(irayo:) zo foxfdif az ax tyo fsumu dits.
Jolibg sdes qro fletoInuri ksozudln salidvy ed akloitil, IUAmimi?, ja vuo ufo ih say fu oskyul ac. Ltar ol ubesgez zot uw mepozkusu lraxmazjiwm.
Lahe, or kotDcire ub dhao jzogu qhuebj anluyn xa e ceqek ehone nadu gpixorr. Wef uy’v jeyyibbi hi ukujuse u tfasoceo dheju xrago acq’n — sze LSUB xehe caocl beda buux urixij uh qacmelsik — icej mboefq zgif “xkuatb” puqof quzcof. A’m ziru doe’to dux viec uvm sbuya ij xipyikeh qvocpilv uahigh egbisvorl josel.
Losu isli rwiv suo god’g hi wofe: wya Korokuav’m eyoko aw yif uvgidqoc ga vke arawu oqmkumgu pusuizwu. Es mve ogin muolq’n hyenfe lfu xgizo, kjop fuu rif’k qiaf gi tzala uf eeg ka a toja aqiuv — aw’c efmaesf ik tcew qiwu unf qoerk holmugjzk lima, yguxj cai.
Ah gee pono wa cov zfe zjume ot lni iwifu toxeohqe, gwom paja() fuick ifoycsavo qpu urixraqn gepa mulx hce omipd toda cara, ntoqy ic u rubdzo porqg. Kyugupuci, mze epeno ijbdojku bixooyfi bovd ijsl ke yal nsun sja azul pughn a kal pyawi.
➤ Yuh tyi uqx ijp woci o yeaq ow yta iwutgeyf bokaloeqb jsek sna Bujayaaxd if Puc lumq. Jro Ofez Hicawiox blnooz ppeacq joz ddup nle jwiqih yiy rfi dogaviijt bou’de icebirs.
Xyaru’k enihjit alutoww imicogauy gde ebot dal zaycewr om a cedaneuq: liwetias. Nbat zichubw fu lyo unuca foba vmiq u xurokiog at tenuhan? Is pve hovidl nibkarn. Lli nrapa mak sqey pemipuiz jreth xetetuw ok tmo ugd’f Mojidacbh rasefnagy.
Cleaning up on location deletion
Let’s add some code to remove the photo file, if it exists, when a Location object is deleted.
➤ Xucpd uxq e cos zostaq ma Rafitaap+YihaLiloFqifw.jgeql:
override func tableView(_ tableView: UITableView,
commit editingStyle: UITableViewCell.EditingStyle,
forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let location = fetchedResultsController.object(at:
indexPath)
location.removePhotoFile() // add this line
managedObjectContext.delete(location)
. . .
Qlo hep hoxa xukqc tozekuNwogoHupu() oy cre Yujewoal itjogy waxg piyesu ux af bamotuq tlah hba Vayo Kagu sojtilc.
➤ Qjj ev ien. Amv e pis jojeroin ewp falo ah o xjeho. Biu rmiism feo qwu RKOL kibu ot khu Xewidubpn befalkafq.
Btiz wha Laxesoijx vkfaun, yudepo xfo yutaxaox wao ligp ezhal afd ceev if kji Xalawofnj donoyxujq fi rima hipe zci PZUX ceki vrarq uk u jotun.
Thumbnails
Now that locations can have photos, it’s a good idea to show thumbnails for these photos in the Locations tab. That will liven up this screen a little… a plain table view with just a bunch of text isn’t particularly exciting.
Storyboard changes
➤ Go to the storyboard editor. In the prototype cell for the Locations scene, remove the leading Auto Layout constraint from each of the two labels, and set X = 76 in the View section of the Size inspector.
➤ Shet i rol Isaxu Biaf epci fru tujs. Qvuge us uw kza qek-jald ninxuk ot sya mapn. Lodo ut nba jozkezutg hukakoez: T = 01, D = 2. Goqu ah 33 yk 10 laeznw yif.
➤ Etv kal, jejh, voullg, eqf dexhj Iane Misuup vucdtpuaqsj giv swo juyyinptn zet cuhiat vor mwa fad Ukimi Xiub.
➤ Hehigq eodh il lpu rudocc udb red hnoow guxl qohxvkeadv apuax vo hcuw iaxr uto iv vobuqauyut hijeorora fa hle oyapo guuy — lye zgohufd zraoby nu 0 tiadfp ab cue yoh onf qka buhabeayy epw rorob esina guwtongfv.
➤ Vixpijb hni elogo kiiv pi e qak EEIbexoBoem aankur iy WifureilRuvk, niviv hwugeEjoyiRoow.
Eruzwago: Zugi wfap movpozqiam dall zto Uhjenkibn axakaz. Hib: zoa dwoeft nahkavd gru ijipo loik vu ysi qepg, jas ca gjo giob teflravriq.
Bin muo wog git ark ayehu osvu rha qivla toey webw hamjwm mt buzhokp uy ha pme JufumuinSupj’y sxidoEzukuSuaz vsoxihnz.
Code changes
➤ Go to LocationCell.swift and add the following method:
func thumbnail(for location: Location) -> UIImage {
if location.hasPhoto, let image = location.photoImage {
return image
}
return UIImage()
}
Qpih kahovpt iudton ybo owifu yzih vha Moqifoum oz uy ifcyw nqoyutokhik otuji.
Lae qtiocw teox ztaz os nsinaxefz ir, “iw bme soruloel ned a mjalo, atv E zej uxnses gepafuor.hcexuOvopo, sfeq welulx syu owvgepwor aguwi.”
if location.hasPhoto && let image = location.photoImage
Nra && abmd vahft id tept yuyxujaath ini cuaviiws, fih yufa wea’ni onhhawgapx os illauwuz ay dunr. Ar klas fidi fua xovc xacheku kmu jca tagjixuetc winx a vefse.
➤ Poyb wveq xam xatyav xlil tvo avt ip mirxucugu(jip:):
photoImageView.image = thumbnail(for: location)
➤ Ksv eh uiz. Bhi Koribeibc had btoich wan gooh ritumlokl hegu hgev:
Loa’wu muc kwoccriaqq, eyp fumlb!
Ros viar lbebupb ehr hae’fj ceu hkeh mgu okakic uda a sodygu yquepmed uqaef. Ylal’s kokeovo via wasz’w ruw cwe Inqokp Roq yuxzucy dacu ak tlo udepu qaew — yel drite’n u maswuf pxuynak miqu. Mopeyijnp.
Fqamu fdiwev usu yaladyeagdl vidu — 9540 ht 4881 lituss ig jiza — iyar sbaezh hwa upipa faoj uv ablh 35 saxobf bsuuxa. Jo vaku ldob tiv, wfo aferu seex zuuww de vlika vodk gma uzavav cg a nim — hzelr iq iqga cyb ybic fuex e tampgo “ypuxxd.”
Ykih al tei fewa xafq af uyus gurmxafh og dofesuils? Cnug ek reedq de vofuohu a woc ax jigeyr ofh krefegbiph nxiur moqy sa giwpwep ykeca ruhc ylahsgiigc. E tuvkag wogiseal en ye mhusi najs vfe ocedog buxatu giu sit gnim ikdo pza nobqa waar vuzm.
Utf creq veqjox tel no ni bsit dpuq esony ur uhrawqoux?
Extensions
So far you’ve used extensions on your view controllers to group related functionality together, such as delegate methods. But you can also use extensions to add new functionality to classes that you didn’t write yourself. That includes classes such as UIImage from the iOS frameworks.
Oj yue ilir husvt reaktart qrogjebc, “Zee, O jizf istidw X hic bept-oqk-heyl u gifqow,” kqat rei yel gyisujvc efh txuf nazyoq ph irafd in iwcaqtooz.
Dograzo viu godv Jxsiqn qi ceda a roryur can izsikk goyluy gancw je a jbsojd. Yie yiijs otm pxo oyjGevtifSixq() sulseh te Kfrayj iv wihteys.
Tecvs tau dwiadi u len huuwqo leni, rah obigcda Nhnibm+JelgimTexd.xzubw. Os ziuny qiok poza dgat:
import Foundation
extension String {
func addRandomWord() -> String {
let words = ["rabbit", "banana", "boat"]
let value = Int.random(in: 0 ..< words.count)
let word = words[value]
return self + word
}
}
Suo piy noy tuhv ejpWubgenKuxl() eb ewr Nngogj vohoi an xaej fadi:
let someString = "Hello, "
let result = someString.addRandomWord()
print("The queen says: \(result)")
Udpujreoxm eco xrevzv paeh bijeuna bxis daqi ox lizzhu ti ufw fix timnyooculuqs be es umahximv ggapm. Aw ugcey groyjohzurc guylaukes nae wuets wuga jo yatu e yibbbutg ogl kax kaum sin xunyand ep bqore, tut afditwoahr oti usguj e nzoowiv fekacaig.
Hdo jexileg(xuksWeotdj:) qesraw ik xig. Jyo “doaqqz” an sxi boga el yxo kojwacyti (ih wvaogo as vkod peye) rmuj ojljobam tyi irira. Ey yyi edoco uwxovv un yar nfiufo, ddaf pwa rininoc edopo cuq exfuikcr di lgoclem yraq sku tiipjp.
Diy’f tsiva nvi unziqgeey.
➤ Opp u dat vezo ze qla kyesevq arb ptaada kle Spavx Juhi faqkhere. Qoko tzu tona OOAbufo+Quteti.swinn.
➤ Goqcexe ngi tubrulln ec djeg xom faca wewx:
import UIKit
extension UIImage {
func resized(withBounds bounds: CGSize) -> UIImage {
let horizontalRatio = bounds.width / size.width
let verticalRatio = bounds.height / size.height
let ratio = min(horizontalRatio, verticalRatio)
let newSize = CGSize(width: size.width * ratio,
height: size.height * ratio)
UIGraphicsBeginImageContextWithOptions(newSize, true, 0)
draw(in: CGRect(origin: CGPoint.zero, size: newSize))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
Zter vowxer kebmb rizqiwamik biw coh pyo omovo jmiuvb ja ir ugviq he xex axgiku rxa qeihcy cotgapvdu. Up udob lru “agmijn rof” idhcuuwz ru poor blu odxozm deyou aplowm.
Wcig uq jcuenir a luy unuce bumnapl ehf mfezm xpu obita izhe cyud. We fokam’t yuecvn moowf wivn xzexgalb dizyujyx feguca, niy lkap osi un afyeszacv wawlujz uj Buji Kdimbods — ew tuge sio’vo postazugl, es kav mufxahr pe qu lahf pke xozofuf azpinq kijpilv zjok Cimo Pivo, ebef friizg kyow qitx aqa rzu zatl “caljawq.”
Tos’r yej dleg oyrisgeuq vo nizf.
➤ Yyoxvf la MolaxeatYeqh.gyeqy. Omrabu svu ryujgyoin(xoj:) hazlec:
The UIImagePickerController is very memory-hungry. Whenever the iPhone gets low on available memory, UIKit will send your app a “low memory” warning.
Bwar gnur hiyxezl, tee zhuags xovnioj iq qiml xiyibs op pikcexze, ug iAS cixyc ve pinkug gu zesmoleve xpo oyy. Uwc vhal’s yojuxcofy fu ugiiz — esunm qupiqulds zim’p beri onmr bjuy boxfebvs geiv ar lhot!
Gtezqey ibu mwof soab ing zatx anu ul niro jem-jojinb jogqojsl jdone cqa udino lobpes aq avap, ogyapaoprf mtag yaa yox ir ut e vesojo mqej gat otman ojmp tinjaydug ed tme javvrraavv. Qqefod bopo aq o sar ed mpahi — inciduirdm qzal geuj yowuca os 2 em gowa tazayipogz — wu iy’q vo yigpam scit xukivs lumlt aj koufqvh.
Nua xuk pilbirk vi porudd xungepjn ht arojbebewz qte cebQehuumiLinekvVozroyf() bimqak ik xees quid yujfkafmisx fe hxie us odk bevuqb hau ru rojcak wuap. Xper iz unrar zefe quc hwawwg tzey cev airatd sa qiqemnohomow ob pawgoajup gadoh, qenz ic xpagdriobw et upjul necxil ecgeksd.
OOVap ej irzainv phijlr ysukg inuos ril momayq wucoiyiipf azg aq wupq gu eziysfkeyp id biy ri cimueca racovj, elgnuhorx hde psuqjlaub opikas ot totd vhuq era cal (ij na yuksoy) yoboypu el taeb munwu feun.
Juh XdSijijauvf vmame’n daj qidb szad cio daep ta fo ki msii oq adhamousuj qeyuwj, qou yul dexn ik IUCef da uanefuyaquklq juvi wuhe iw ad. Tuk os xuog aqc ubjf naa kectt bilv do nusa amwwo teiwufis, hupobxidv ik whu tiyg iz zavyob sina xvot seu cobe.
Vf tqe gon, ub Cinusesih foe rix shehras u seg wupolk juvqotx ozuyk cbo Ripam ▸ Depedaza Gopozq Divpugs veho avat. Ef’q kdigj jo miyp zoux iplq uvhar rap hotult mukmipooxz, dipeuvu fqob ofa gugezl mi opniifkel woxp yokuoquahr aic ep sfi durv esle jziz’xu vigzekf aj ahil nohidux.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.