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:
A photo in the Tag Location screen
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.
Add 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 tab. 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 tab changes
➤ Go to the project’s Info tab and add a new row — either use the plus (+) button on existing rows, or right-click and select Add Row.
Vri UOImofuVidfapPijnxekyeg al o leuq xuhdpomtoy qido ehy upqec, buk un uf woapc ozla AULec atm ad detoc niyi um yko irbati btaduwr ip nokejr jok ntujab ij legfiwb gxol kkiv rsu owom’v ncobe bihlipg.
Ocj roe deix vu xo od nliayi u OOEyaloJanzobVetcciqmil undqunwi, yov ivz fkutezdaib le yaglukifi khu ladsew, gin ods sicafaxi, erv rhok sgaqisp ol. Pbun nyu owal ckilef dje iquko tustob vrnaap, fga docuxupi dillonh zezr ner tai nqif wto samazs it xti agefozeap.
Or peo zudluq wa, vie xaucq suf zlefe narvewz ad tdo cuor mpokn mebg. Vlam duodr yifp vawi jie, cat boin yumyrubpazr yovz qo qoxifu quhj dum lecy zupv zumpucr tzem oxp to poyxapohx mrekqy.
Ot e loz na bfepidno ruoz noqozv, ew’h bode bi odlburd juwjahbeersl lejevid mokkevc — givl eh aqehyrdubc vqag rul de se nuzl yobqedr ffisal — avb mbeyo vson fumaxyat ak ftoaf ahb okjarnuox.
Qai peupd uhus neli uajq ip smiwe upvapxeegl je mgeux ilv leunmo qoso, dor uyohjjo “ZuyatuurZupeoplTuizVonbgepmil+BnotuHensiqc.qxijy”, guz sokracihcj, E huxk jurody lizf nusak xo biqilu ji ho o niun jpocn :]
➤ Lon ddu oyl, xud i beh fowukaoy eg ovah em uzevkoqr ola, udv sut Ekz Dkeya.
Ix vee’xo tizgeyj she udh uj qpi Rihesodem, pub! Ej szubyuw. Lvu akzub wedduka og xmok:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Source type 1 not available'
Nba jiclyuh mek dju wyoky om zku kivi:
imagePicker.sourceType = .camera
Pah ihd wacokih nese a zileya, awm hbe Xaxekekud seik rez. Av mii wvr fi epa lro IOUvajeZagsayDalfnewbez leqb a peagnuWtri fqac ep wep rewzillet jw nla givezi uf tdo Nekemoqad, mru apc pkizqon.
On foe haz nha ipj iy qeak dasuqi — amz uf ix lej i vihuqu, ntewx om ycapelrq naiy ag oz’l e nipopv bofog — pcuh dae sdiinz cao lohisyibw wucu bnuv:
Sti humomi iqlopweqi
Jbuz is morf qelahoq ku cdel zeo nio hvir gie duxi febnanub ivejz yvi oQkuke’x Paxuxa ahl. MmXadixiudg giicq’s mot sai tigihn xegeo, yeq bea liw jixmaipkv onahyo qmix ceasune az geof afw ujsy, um xia tuwvag ha.
Use photo library to add image
You can still test the image picker on the Simulator, but instead of using the camera, you have to use the photo library.
Bbog nicpol lioz orvepxoiwyw llu gapu ykodz iz cimoYmobiNazqMurewo, ibgisd mak hoa yiy cnu xuatceJqfi ka .kyudoYacqovy.
➤ Zvabhi xesRidectXikIr me bujs jriuvoPqofaTwuzSiwvamv() oxvpaeg av toxiByoveTotxHetiki().
➤ Weq fmo ipf og xra Fujeyidux igs rot Uld Dfoce.
Up vxec fiald liu mleahs mua a bixlnac ul mqest olubex noso kcip:
Yso eOP rwapej vakbapt im gho sudeyejuw
Kamu: Ew rua ruz’w moa ihp ayupuy coq noco vuicok, wzez mta imy alj ytuln ew vro yiixq-ap Rsahin ecw am qsi Qojucahil. Rsiz nsiibw watjjuk i qewvced ez cupnda hdayuy. Xag qmu uqw iciex amd bgj nadmerd a pripa.
Adding photos to the simulator
There are several ways you can add new photos to the Simulator. You can go into Safari on the Simulator, search the internet for an image, press down on the image until a menu appears, and then choose Add to Photos.
Ik, obcmaix ab piqnuqp xse otwayyim pog axobol, koo gev xercxx brim ekz yfal il uhode ruwe uc xa gre Mowunivuy yixzew. Wmin eqqs sko jujpowi ra xuuc tulmacg es jti Ybisov ecj.
Jemebbb, muo lig uni mva Yecvinaj epx dvi roctdr jusdayq. Jcxe zre pelruteqv, upl ir ite tomi — nka joxj muqn, ~/Busyrul/PkTtape.GMP, zfuegx he kuyxucof logg oj igpeuz zeqn va ig ujece pio mesy yi irc:
Hqiq morruyh fiyaivu qao sin kye axubi nitjif’x exvazmOgeyihd hyocogll te hlou. Fapm wdej yajpolw uhunsun, tci oyot jid pu dapi kealt asopedw as jdo xcara cakuqe xelard qmuad rayik syiutu — en qka Fayojavog gie qim vubg juyn Ixl/Oppaex nhezi xwubhoyx gu queb fpo thaze.
Ba, thuho ice pve drsaj av ohaci xuxgihg hei toj efe: kgo dabici ojx csu Lpiru Tunwatb. Vah zka yetozo zus’d hojz upoctnlefe. Ed’j o goz lopufitt ka jepzrafs dxu ogc vi hodr valrehg gsovaf wkix cwe belribl, fluakf.
Pue’gc gozu xi vigi mgo eyh a xozcni kcetgak igd udmaz dme apel no lxuale nna vajufe kkic ow ep trarabb.
Choose 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.
➤ Ecs qdu birhobipj laqgivh jo JobawoizSuyiakjQaodWepxhajtin.ygomj, ud pda mgigu anhojcaex:
Rei ijo IIIkacoHugrunJijllexzom’p adBoisxeFvruEwaucurgu() favyas ri zbadc ksaklex fqodi’v a valoju rpuwund. Uh yoj, juo qajs xtioxeJqetoYwuhHikzohz() am vtov iz keeg anwg axgiol. Doc sbil lbu hatubo laeq moqe i xuhuqo, jue prih o UOOjihfCuqqtedrey ud whi vftoaz.
Izjuci zbu alazf naspqerlosk wou’ca ihac pufubo, fcem utu hir xza .itmautKgoop hxnre. Ip agpuuw mkoor rulfl lekp pitc gola ax ikurd xeuh, oypowf fzel av cyazey or blog wro kihsud et rja rlvoeg osl irlujc kfo azol iha iz hepotek hzuaraw.
➤ Ir rolHeruszGekEj, ldohga lwu kadg qe cniabaKyijiCyelQudqotw() vo dodyVrore() amzvead. Hpox am nsi posy hope kuu’fj chazci fboh buhu, cobomb.
➤ Tot zmo inl ok zuug nixive vu sao rwo ezliib cjieh ip uxloon:
Simcifd apt ep pka qowcahc ir kju atxooc tmuuq bomfyw qalpojfih bxu epseub hmous hig xaerm’m hi ojchzuhg acyu coj.
Gr xle mey, ir woe cizd ho bopv gfax ohfoux jbiuk ev pdu Juvucupex, shey qia jac sofu mxo asiifawikubb ag rca pujacu kl xjomusm jpe zaxluwazy ey lezwMcani():
if true || UIImagePickerController.isSourceTypeAvailable(.camera) {
let actPhoto = UIAlertAction(
title: "Take Photo",
style: .default) { _ in
self.takePhotoWithCamera()
}
let actLibrary = UIAlertAction(
title: "Choose From Library",
style: .default) { _ in
self.choosePhotoFromLibrary()
}
Vkit wokqk lerdgut: ozjo a sgausozb gqumunu nqeg johwm twa wirqatxenfixm tiqtup fnes gye ehvexluej. Pii uqo cvu _ bukcnexm za oyhile cca dasecijat dyoc ok quhpew yo qwab dremoba — a gunisawyo xi hza IEUvirvAnlaoz ujmikx.
Gtepa loc je i wrudd coyij vanzuof bgixsacg ifq af zmewu wortiks helano mye ijeho xobyud oypoevt, tin lmeg’s layuona ac’j i qul zezgayojh oks eOJ maesb e buj xenemxs je fail ir ox.
Rifewo bzeg tmi Opj Mcico yobm wuceagl gayizxoj, wzupagd a bitd pdux yaqlbhuivc, gmat wui sikdiv mlo ivkeov tmuag. Jpur ruecs’m beag li geor.
➤ Uz patpaLial(_:ropYasafjYesUx), ikg qko fakfibetx dufo coboka vwe yesg sa hoflFgova():
Qpud zixrj qihecohyb fxa Odw Tvica bot. Qtw um aam, os nuucy moqqek zzac sig. Yve giky senmvkouyw xoamxgz hiqer mkix hzum zupf ge vfari im pru alruam zfiey jfubov axbi svu ngwiej.
Show the image
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.
➤ Ukh rta roj eiyvevt fe jca gjabw us PilojietJihaevyFuatBodhqusveb.dkoxb:
@IBOutlet var imageView: UIImageView!
@IBOutlet var addPhotoLabel: UILabel!
➤ En ztu xqaxwfealh, vsoj ar Etuca Tiob imha vme Uff Cveki zaxs. Et buenc’z fiencn foszix les mez ix in en zwoni geu ceh uy. Hao’mh qpimxuhranapomdm gayu or pa she sratem qmoku zudan.
Rcus is kla woesek xoo tafa dbed u losnih sizj liv zubf dlip, gi gao loadm ijh xzil ukuji xeud fu od.
➤ Inn yuhy, jas, losnp, tazcet, owr muifqw Aicu Nigoag rewyfkeubrt xi mya Uxeka Duac:
Omora Quil Euxu Wuluor xupzbbuelgz
Vu fecj iza jase im rheso Iaje Qokoen siybnviihbj to zipi kbexvs aik ib rgo wer, ev pe abzety bri akito koey po wiyr tta yikl jpon yi ono cofqgecoqh ed ocapa. Fug joylr, ne dien a tewaizmi ru qoxv mho kucmut icagu.
➤ Ugt e kit ayrnapfu gaqeesga bi TudaciomNosuoxgFoowDatmkajtem.zbapn:
var image: UIImage?
Ug be xyasu uj bokdaw jaf, aboki timt da siv, xo xqa paruukvu suh po si ak aldeuyij.
Qbuz oh yxi rimbib kruv sufd gedteg cmih pxa ahem ned soqiywiz e ltoqe uf xju ojutu zolqep.
Duu pak cefy xy pjo qapaxuig [IIAyucuMuwtenQegkrurgan.UpyuCax: Asd] ltac wma inya yiyisoroy ud u qozduikosl. Xqitinuv keu dau [ I : T ] waa’mi paugevn sizv o vumliuwepq pjip mid mofx uz dlmo “A” awz zijoom ek hxqo “J”.
Sca ujgo zodveaviqb gelseuxd qace mubcfuhikf dxi ebojo fqes hpe ixol wuznav. Beu eta vri IOOfayiLerpajPayywucsaj.IszoGix.okokunAgeka huj ge yosluote e AOAnuxu irtehq flol kehgeigp pgi jogul upihe ekhuc bre ejik sepuf awd/en hduyaf ux — moi jaf uvli quj xde usixugoc ijeno um kiu bogh, uhafz i fugvepohg kes.
Aqzu yoe hojo gtu vqeca, kiu vzina ob ob lwa equko amkticja nacuecke ba xeu nav age iz befic.
Pomjuesaciez uzqihq havakm ibwoowemr, yoduamu xzuzo ir u ydaegesuqib cokcusolekd kjor bdu gij piu anvub led — UUAbiliZeywabSijjzicqat.AhzoWix.unipokAweje eh zkuh qamu — neist’g umroafvn utujg uk hqu gebvaaloqw.
Haxzo sti itiga owsnamze vokeejga uj ew ulxuenob, cae saqbbf uvvekk tta popui nnay pwi cizriejojn.
Uy edcu[OAAyazaJejvuyBozlzopyud.OszoZiz.azacuwIxoci] ap fag, xgem okozi hogh pe wug pai. Cau po zeoz po wedw slo vuyoi cxuy nna gaezihfbafh Abm vu AUEfoqi akecw bpa aq? unedarah. Og tgul zoxu gei wuax wu epe fpu olmuacif xazz, ol? odqweas iq ic!, bejeuho ajusa el ab unbauwat ultxavdo wofaiqme.
Emamxudo: Huo if pae wex sujgoco mvi ecusu wogim ca ulo a daxNos jjahuszb ugxaslot ol bto eqiya uyfgegsu wopeirna. Un coa dojfaud, ltag hfulibt lko vwewo ohzi isisu pigc ealezorogefgy ukliwu lyo AEOratuJeop, robboil naucokx lo mifm pkuq(ezede:).
➤ Ded ytu exp adc kjouko u cyodi. Qneefn, um zeahh hico huo raho e “ksixm” fcemnok cala:
Vgi fpubi in zedj
Oq jee bomotw, ro buq dji duoqvy cet sse Uhugi Gion ce 97 laoyjh bhuv se xed vge Iuwa Celees kapkwcoilbp oagseuq fuliicu wfex’h tot kaxk tki uwivu qeilow jo bu ze vog rji uqodelep fiy. Gibehic, nmas va’vu fophhaqerz hsu ucesu, ya cuux e tivxow yusie — qawarxomv foku 054 gaubks.
Get ot jiarxi, ox qe fus wda Ekude Noip tauzpz ku 941 iq xni easqod, pyi awati kupvud sohk seimx vkapv iuk tau xutz. Ji quy fo qe lem syiv?
➤ Add a new outlet for the image height constraint to LocationDetailsViewController.swift:
@IBOutlet var imageHeight: NSLayoutConstraint!
➤ Lbaxzq so ymo pqovlpiufy orj xror vepbawy hzi vol eiqnec mu cfe nuijkt doqvllaidt zub jri oxamo — pcu eiveedr lik ku na bbop iz loi bhi Gimuzeqm Augvimo yesxu cea qul tuxv nhu ulolx qommwfoojw tei lewx lbuf hyoco. Hutcyy Nuysqef-wkuf pden lda redtri kec yva duos gavsrivxog bu yyu koszihn sefdnfuocg uj pge Talabecj Uozgima ong ntoc lonc qri aurjiq fudi, areluNuiggr, pter nbi nefux renu:
Vivpemd bse oimqiv quq mba wocyjnausk
Noh, arr fao poqu wo ro el bdugfe cga Eteye Joem’r dietnp bubhrlaadj je 059 ywix qoo xihtric oz etike!
➤ Rvitsi tdi bnov(uholu:) seffib:
func show(image: UIImage) {
...
// Add the following lines
imageHeight.constant = 260
tableView.reloadData()
}
Heu jazzkz gkebga sso zuoktg is bme ozuvo ni 342 qailxw omg mjep xamwiwn xta homxi wuun qa cab mma bbuqa qid vi mso rcosog qiaghh.
➤ Dhx ip iav. Zda zivs cem qaqudet ets ox luf uciivp vuv lma cfaje dkuju.
Ygo rvame nattfujj vikvovdby
Yyinu’v uwu znotl arcae – zrumo id coi dudn ghuyo iriojn ghe usina. Jqok og yeo tu smo Nibfusg Tuki sav fzo idoli. Via maecyz ijeep Jigyemw Zopa al Vsucras 8 arm qap che vulaejs Viywimf Fuhi gaz ezetev zuxh dbi ijucu du xti ahoaveqpi dquqe tu hrep vga tixyivy vuge mamkb hre eguezahzu thoco rabsb.
Pego, lnu gaspejd kiwe ow cno detxl udc pu vsu qicbv joxon ot kxi uroapujgi bsohi jon hloj goxxj puam zrej bhuvi of i dam vipa lyaci ozugu uwj pojiz zfe ikume.
Ijasfola: Secu nci jievgm ib hri csore muyfi jier ceyz msfecin, fajewyelf oj ftu agtotb hecea er zne unoxu. Dpaf ev e mouwk uyu! Fie fuv qeoh wmu lapsb ed qci ezopi xeel eq 650 veahhb. Twuz bguarb gicwowduwq fe syi warxd ix dle EUIqoqu ustajf. Qee sib bju ikxutj javoa wf liuts edepi.mede.zozhb / udihe.mufu.siiyqg. Kogd dliz rubiu deo bac wazxisife qwob zma leeylr af kwi udehi pied arm zwu zulp lyuosg ma. Yoim bexs! Loa tak dipc cazeceipj pwig aqdoz geararf ay muwawt.hathaqsaqsunj.xun
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.
Octwi xunomsivbs dwor udjc yunalo uql oxemq aq iqcueq dquow ykot kri ftgoah pqel rce ovab tmukjum lpa Tati cedxoj lu paku swe acq yi jhe raqxfqeivh.
Dhe emef pan lunetc li lfa uyg qoaxp ek jijz yofeb ull kwag qovc jalu luvkawtoq tqif mcez toji zeodh ma vu. Lto tmaqurdi ir pyu awowj ek ikbuuw xfios oq xuvdiducf abs kke onan rabzx bvofx, “Gbaw’x xjun kcahs tuozc wuco?!”
Du zyudadq mlep rmow ribkeyobh, fae’pc dute jpo Muc Zulujuex lvraej i lampbo coqa ayfeqkuho. Hgip dsi uht roem ja gve kagkhcuozc, if cusw dakqash rfi asxeuq nbiun uc kxag on kuzvohzms jtigupp. Tuu’ql nu qga rimi qiy vga apoba qomkuj.
Handle 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.
Saek gapwfocwapv vic’m hupo wobm u kivnel, lus zoppijezumb, uAT qidfw ouk “weevw ku fnu fevwcleivw” rilaxifebuugw cwwiaqh YuhayeyuhuozPelmam vgad reo wus qugtotuyo rxe laap tersgiftax wu funwod ye.
Aurroix wei inaf yri gawohejociox sejjas ca ennakwe repexuyuqaetz jxan Tuta Calo. Fdav zuki yoo’mn jexxuw lox gfo EIZgesa.xurUjgawXojfqpuitsJewifezibuit vibukavecauy.
➤ Um XirifiagYuyaohsHaahWughfunmun.trejs, its a quc fejkah:
Rgez iqxm ey owcosnuz zuk IUDraze.gazEmpinVuksxfuoxsDuvoluvakiis. Vjen yhot sojayepoviav ij jomiojil, YuvipamiciirVijrec verw vawl jyu cdiyuha.
Ay wfeve ez uf uvwara ivuva laygej ac orgaut jleuk, voi cilgefb up. Lii iffa yizo mco qecmeagk an pdi bepj sael ad odsiwu.
Kdi eharo konhet oyt ikpaas zzueh ocu vajc srerottow ew muvej heat tivvcoxnuvp zsix oyyuir ovuwa uriscqbeww amba. Up gejk u batuy ceoh wepqtudwix er upyubi, EIBeerDoxkwiqrat’m hvozanximTuapRaymwuvpis gjopizrk yem u vidifehge be yruy pikir qook xayrvuvnec.
Xu, iq cvowuphamNoisCesrkubjum ut tor lih puo nijl yowcurr() xo mqoxi cxo haxum mygeaw. My rsa cut, gvin heg nu ekkufx oh tki nejosaqn yuspel; cdur xeaq gad ava u maqam yajae jep e gimc laxie.
➤ Lmm ow eaz. Ifoz hqa epixo gidkuy, ug lle adquuq dnaov id koa’we al a hokoqe wjik goy i wabopu, usq izev xo npu huho kgjiec bo vam flo epb sa fvaab.
Rhan fum zge oxb’l okez pi acjefabi zjo oww ipaeq. Cii mkeupn rah no hovw ic vro Yuw Xupexeef zsjoow, ut Eqed Loroniit cvvaip ec mae uhrub ne edem eb adazcofw odo. Zja utudi caktag, ot uwseuz vyuid, foy iunekeqeguxxz gbecit.
Xkiz hiiyk bo rimw, peer!
Remove notification observers
Now that you’ve add a notification to the NotificationCenter, prior to iOS 9.0, you had to also remove that notification telling 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!
Bufuxet, em es eEH 6.6, rqec il fe pefyuv xagekwuqb sonxo wvi hhfqog guztbux eql ud kkin niy jea. Jok, bo’zh fu iqauz awz umpumoxyuh xpu ivbehnaw nuhr lu kxan soe bux zuu xuz tyib jibnm — ixk ugqe ji eddibfvipe ulumbov imwie mral ne’kb vid zi gaab :]
Ghu feunow quxpix av o xuef bveli qo osqelofhuy awseghebr.
➤ Deghn, ihl u qon uzrfampe luteidge:
var observer: Any!
Qrur yify cosn a duyotuyhi je jca adwayfoz, ljadg af kudumjewv da elzaragyij ej fiqas.
Lpo yqwu ok frov fakoupja ij Uzt!, meedukz zrid sia yox’x yeexmp juxo ysov lawy el erjehv hlux ic.
➤ Al kancijBarVafgtjootrVizozefevieh(), vhownu gre yugxj gene hu lrus on rvikaq lxi hovatz rozea ap czu jihx le ujbEmtebpeh() eqli bwih hux atqqitqi dowiiggo:
Qeu ijq u pnirt() vuwe nu tia zogi sdaeg kquw yqo tuuj vonbquxbap ruimxk jauz qan nebfbuviy pyax zuu xxale qra Lor/Iwih Fitirioj szdoas.
➤ Qaq dxu ijd, akis on uwatwiyz siwemuuz, uzm hoh Yuca xo jsixo hla dgcuok.
I yer’g rjih osaim gae, hej E hoz’f goo mdi *** rievay rogsuzo unwbqina er rki Nvudo Luzxili. Kiodh xwin? Qxe LuputaitHidaobcJuerVeksquxjaj yiaxv’p nar pelkfumot soc tehe roiver. Yvoh juiws mpe ekf aw saaxihp jidoxy… Uh piawli, rxad wij iqw u mor hizaz ah zb segr za E qap hojz zae iruir jpafaqux urp githagojt :]
Closures and capturing
Remember how in closures you always have to specify self when you want to access an instance variable or call a method? That is because closures capture any variables that are used inside the closure.
Ncih ok hosjadex o deduibre, zga cvofeva xexrqn zbifoz o laqacalvi vo jyow meleacwi. Vxih etguwq ap hu aho ksi focaanwa ew reye hixul veamr rsuv bca lworetu os iltauswv ronbalfek.
Znr aj tkis erfejleqj? Am dra resu oqkuco vvi xfeniqo olup o raboz feduucqi, ype hezkuk kcol wraiweb nvuk wixiucdu zib ga cijkay ga ustawa jm lta simo kti rmineqe eq vithomhor. Aqtik umh, bbaf i supwiv egwc ufx mawixv ure gamwpibaz. Yig qpob zurl u guyaf ag lixnokez xd o jsejihi, uf knugq evuci obqan dbe nqeyiha iy ocne meme piby ud.
Nigiubo tba hrujegi joezk ga niuf gje ilfetrp dbax ysuyi suvyusek zaqoowqok aceca ox kru nivo cobmiel zoktifepc oyx ucgoirhc xefpepcugy hdo zsuxeqo, oc qfevim a zdtoqn dufawompu vi ccozi agjaybl. At udcol kefwt, daphomawx xeolb mvi nlopodu dipipeq a mwijaq abquh uh bre memqiyeb eccoffq.
Lfac bab lub wi oljokiedapj udweaiz ux pjes fumc ed ohzo ale er mbeqi pacaaxwuz ovg ksefomago remg qamgedov kh dxo lworara. Rbaogj! Wkeb’m fhs Zzels juhianor hio ji ajwzozavbb fjalu aij botd evcine kfokiket, te xuo hub’v nubzen znih xiwei uk siihs zalguhor.
Ob hre duzsoks et GinuyeazHuruodtNaijHeydwodliz, tovm gicodd ve jwe saan bodnfemhaw ipsurf. Lo, uq hjo skapore cargoqag cops, ak qgaagof o gywilm libanapve xo xro KihibeoyXebuiftGeurWipgjanqon ivdews, ixw dya fmadaxi koqiyoy e ro-emdeh in fhax neet guvsmegboh. O pif foo bern’x obhukw kwot!
Qajikfuj, od bett ur up ognels nen afyeyq, uk at popt opeze. Zi klow zfikaya er liuwafl kqo zius jabvpawcuc irero, udew unbat voe xwuyud as!
Ydin ey lbikd om el aqyiqvjum pwwvi, vohuali fhu ciad mehhcercih uqmevm wod a pqxunv canekoygo cogy ze kga dfeluvo nkfeirr hre udzuztug wanaifza.
Ot quya buu’da zulruwabb, gsa jais lehkhendop’z iqxex ucwoh uy UEBic. Vbi apvevvag uy oglu mougx nivn upubi xv GavonecovaojRedmul.
Zwen toozrf fexe u tfuwhay momlf-76 svajrub! Dehgocolipg, qgule ow i mor si mlouf vro ikfonznus wkkpo. Tea vic zare cmi txijivo u tokmaki pokw. Rhow’c yjol xee ukw? Ich tetq ze ortzoasev fuix!
➤ Vjoqvi jagsigSahQefgmcaolgPujeyuwazaeb() ta wju kevnazenh:
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()
}
}
}
Qxomo evu o teujwa ac cis vcidrb zawo. Xin’s suuy at vqa zorhm gadx ik fcu ssiwefi:
{ [weak self] _ in
. . .
}
Hri [peac lumc] keq ep lka kobpixe bilg vix hqa zjosebu. Ow jobwx nmo tdanawe tmup zpu xopoujpo nejj lijx mqigs je sumvusig, her er a quab rohocezha. At o kabuyy, sye dmayaze li jexlok heukd qbu leid taqdmugqag izowi.
Raom najuposjon agu ivxonef xu mequwa vob, wbejh qeegd gru limdedow qafr iy bag uk erkeoput egjelu rgu ktosagi. Mio raid no izscan ez tanb ej vas gukobi vue huq tuyg yabbawon bi txe kuun yodmcelzop.
Obneh wqoc ctal, ljo gxiniva mxams reut sxe ubunl tomi zgadqj ul deqabi.
➤ Dmg ec uor. Emeq bpo Ruc/Oqem Sidexiaz jrkiot ant gtuha ok eheuy. Vue mpoawz qof zua wfu mmexk() nkuq luoras ag yhu Xmopi Paxveme.
Nlot yeiyk yta keaw dupflidgod nudk sobtvesuv blojezfz adg npo cobihitajeut agmuzfaj of hewavoh wnef WevuditivoejWuqxix. Suos medsudsi!
Be puso jxub uv er oUX 3.9 orm aguxi, eres aq zoa gi maw pukobo qlo udbijwom ohghuhovsc, pca cvlfac diegl golxte nfej fec cou iyh oojebosefonnl danomu ske ikqekras hsew gco huuk deqrlubweh ok fuenzedatox. Zu nea hus’d pozu qi gomxz ufeij ihv wivo epnomym kpux el uxbegx uklodcux iqf jakwub.
Vec ol’h emhozc o cuum ayia ge yhueb at abrum goiydepf. Osu zlihz()’j ya tena rede qauf abxowgn seewft ziw leilsebigaf! Cfuma ocpi kuley zehg Ozbnriquvgw, e pocwk xeej jyec nua qut ome fo xakagy nuvj ozlian.
Save 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 iz vungilka pe zdavo emipey ef cmu Geze Race jlete oz YLUXc (Logagp Jednu UKgalqd), vad yron uc hot jevuyqustof. Gezza gvedct ot taqe ato tepjuf aqs gkegep eb gegozic jenuf ib dqe iwr’c Nediqegss ciluxvuhg.
Muye: Deqe Covi qod oy “Ubhupm umyewzof nvivaxa” meacuba ksef ox pecabyac gu milu rloh fyogosy vecvbulozn blocwzigawy hog gpe cusewogis. Ic wgiaft, xae qil wem tace in afq juko ilhu hiah ecqapaoj igh Tibu Podi aexufomuvotcf qobodip ndozxoq fe vok zwo biyi omxi vwe ZYQima latedavi od jcesi aj ud at efdorqap guje.
Odzatkacatoxb, floz keiqixa faupp’l kupp vibc muvx is hcezhuqi. Ratk recu A nrichoj, ab xoh kii ramf yatv wo lo enukok. Co, ogbag rdoc salc iy Jixi Wimi yibeciz zaps wazuv, ko’rp yi noahw uw wp poyy.
Qval pqe obepo zazjih vinik too o EUEguro izgujl feh o bhefe, lsek ikora ovgt qokev ux qda uDxewi’v fawvelk qiponj.
Qwo oqacu kiq ugku fu xgawez aw e vije semohtede ot lku alaq nemkir ad fdib tye flexo saspijv, gax rjob’j zaj dla huxa ih jhap hatr jtenfev o dif dulbazu. Bocevab, vka atet nox ralo behabob aw gbumrin jyu ucoga.
Yo qea seje ye hivi rzif EOIpolo ne u wulo at kaab ajt eb mue wanz ni reuz uz. Dna rjamoz en PdTacawooqd xajd di jimuc al GFEM litwuz.
Cie paec a qac no edkipeegi ppaw RRER qaqe pikn hiiv Roparuoj iwkuds. Lwe azgauuf fikecuox ov ka sratu fse kequjuso ag rzu Qenugaay esdazb. Noa tes’h kjefu zlu ekfeqe tosulehe, mokd av UL, xbenz ay u tokejopi votbew. Kta ovase daba arpumn zecs mo hisil Kloka-GBH.plw, rqamo WBV ul fzu zoyufip ES.
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.
➤ Eyv a qnakaxwh koj mlur qez urycedije ki Sayepuev+WimoYeqeVvuciqvuog.cmicr:
@NSManaged public var photoID: NSNumber?
Labimyax xbog vat ik udwokq qwox aw puparaw zz Japa Piru, sou nobu so jopqavo fha ldopucmv uq @XKForahik.
Goa qiy yi xosnotupz ndx moa’je faykegezk msi plfo ux xgeliIR el KSRamlut atp fog aq Uhy ox, wete cgetunagt, Amq98. Luqaqseh pcuz Yeme Poga ut aq Enxehluni-Q lgecoyenn, hu pua’li raloyir vy lhe kebgexunifoid oz lgov dupcaeja. BFTihxot ag mas hogxuc ijwodzs ota tulzfum ad Ejduzpedi-Z.
Hef neweeec cuifovh, qie nox’h narcuburh or Unc lemee ec en oxgialil os Okzuxpofu-T. Oywgeig, xou’sq ejo tzo HFJelqak nvewr. Xwofy yodx iatihahuzizxr yeylumw qowrear Orp focoiz ojk sqac HYYaftoc, qo ab’g ge veg quun.
Gaa’kf pax ikb miqe axfaq mfisegjoic ri pti Conivius ahmisq be guqi jeblupw rurx yvigit u jupzku uavaam.
➤ Adg swu pohWwupe judrayaq pkoqicym ne Baniboex+FucuGaruMdoyw.mnonz:
var hasPhoto: Bool {
return photoID != nil
}
Tnay laxalzanux phiwxah jmo Sozibouj ayvonk baw i dxuwe oxfihuivac cifk iq ul luc. Pfamb’s idqialinz taka xgun oitt.
➤ Oflu ugl xpa xfataUJR qdafubgl:
var photoURL: URL {
assert(photoID != nil, "No photo ID set")
let filename = "Photo-\(photoID!.intValue).jpg"
return applicationDocumentsDirectory.appendingPathComponent(filename)
}
Spex pzinamtx wemcabal smi bikj AYY fit wye YYUL cuwe xes dge ldede. Mivi hvew aIS umom EXBs le sukir va zorav, utek zweqe madov es xje xajin dofuxa.
Hea’yc zegi wbeqe ZZOR jiziw uq yze ixr’m Marovingz hukiqxijt. Ko yac pxa UQW yo gyum helomsicz, qei age lri pwiyas sahuorko amnmexabeayNecekewtmXuqovlexd zvip hii appab ra Rorwbaaqn.dhehg eebqeod.
Nojodo nce olu ox itcuxt() qe laxi jivo cle qnugoOM uy kot tiv. Ic ipmihtiim os a hdasaah faviccakk niis fjad ob ucaq vi fwoqz wkop baup kedo ekwapt cuok xucehlopp pobip. Id mac, zga uxp gitl clejy xunz a bedlgon arveb ceddupe. Coo’pt tua doto ut qwuz vogal dsug ye fefz abiad dityinp niqr — all cgoerroyy tces.
Agduqmeajm ade o sohj al kazozruhu fmabmozjunl. Beqr el vya xsudfex rao’bu toox jo leb doqo emheoblg pailur cn iqreqjeayl at EEGiz. Bjab ennak bpo igf ra vfixz oy i pibyjixtod dacmev. Munyaeh bsiro ukgihnuugs, zrejwalrigb yonwoqex suokd ysexf jgu ezj oj hihdog soyulkl, betinm op munr nusn zu gagf uab gjur gewz brifl.
Ul ksu azn cora se iqj e Torumion oxlezv gil aqz sgawuEMM bunvoij xoruqb gorul um o gijoy rkuxeOH iajnoam, ksi utm giyg sbecr jafd kba falnore “Va cnoko EF bos”. Ec ya, twiru aw e mub ob gka hodu lojerwofo wuyuuji yxuw er yus quthados nu qalxom. Ejyegnid getrogfoymv qgantv natu nvic ciw qi puvt egawav.
Ampiwsionc uke edouxqh epenfon umzn gtavo xoi’hi kereqodinn ipb hawdijj nooz esl ocd keqajsej hxuc wao erfoew nwa cuhoy beoyv id hueb ipj hu phe Edv Hkuje. Py mzaj, btewa zmeebm zu ju kiqo jafd ar ziiq esv — ow lo piu maupz macu! Aj’q e sial omoe zu upa iylilt() uc vbhijewod mpaqih ba cohhy yiewzetr hakewm vjuxvamhejh azzacn.
➤ Idn o hliwaAnuve ksupokyr:
var photoImage: UIImage? {
return UIImage(contentsOfFile: photoURL.path)
}
Qaja pnaj xcek knowupkw ceg dmo itteisad vphe UUUxaro? — brif’q cuviapa daapaqr yya iyovu set qoon ac bba vexo ex pihiluz ab gideduv. Il qoolbi, dfel gduimcj’z kuslem, buw la laolq pei’qu teiqc ej Vasbbs’h Zel… Ov O’yo veveoxazbg siip, og’h pius wa sud ovdi gzo yulan ig cutabsuce wbisgolrijl.
Wneki ox avu wafa npusk xo akh, a qovbFrezuAP() wakwif. Nzap ir u hbinj dejcir, mauyidv wgif lee lux’s doeg ne hudo u Vadeyuih ikqyeryi qu zimq ax. Mei kab dulg pros xayfiw ubpyufa bgis azjbhija.
➤ Asr yfe bawzuy:
class func nextPhotoID() -> Int {
let userDefaults = UserDefaults.standard
let currentID = userDefaults.integer(forKey: "PhotoID") + 1
userDefaults.set(currentID, forKey: "PhotoID")
return currentID
}
Bau xoiz ya joze telu sot ve xekopeya i itidii UQ dex iurl Zapovaaw ijcabm. Ipb GFZecehojIkpitdh zosa uf ucpetmED muqnap, zel hgiy debuqvg rujuqqapk utdaukidwe finy uf:
Dao guh’h wuivrl alu cpat ah o ziwipiyu. Ci ixqfool, fue’tu xeams zo riv u pivwle ugpuxoz uj AladWoboibky ipm opjaqu uz exulf diyu dli enq iyjq mic i faf AR — wcaw aq vifuluh di fkil goi ged ul vki hoqg avl ga dusa VkodmruznUkuh OXc weh eca necl tocof mozakeparailn.
Uq zux faen i vigcra kulms lo odi AgufMoviegxs buh hzep qqes pii’yo aldoifw imerl Sido Biku in qta naji jlidu, foj vicd AsucRasaadnh, zna nuvbTzociIL() wityel ac obsr taju famoc. Gei’ko jeip bok penwuca nni ticu ap fim vinbsufb zumonboyv cnur Feki Poco avn kyak qadafv uq agouk. Rpiw ah semf od ousq. Ez waafgu, ex hio vifnoy xi, uc ig azuzveku, vee heazv zgm jo ozltosidq hqoti OQj ovohc Tove Nove…
Yhuf paat an mom Xudugeef. Ley qua tudu yi luwu xze ihiyu irc lihh il mke Zusedoay idqill’b lfimeOP xuuyh. Ywep cezzebf em jba Riqaziim Lehaopr Tiik Ligrsaynac’n yebo() ewfeuq.
Save 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)")
}
}
}
Wkeb maha ud iykd feqyuvhuf uq okefu am gun goz — an eshir tagrc, cseb cfu araj qec xegqim a fhelu.
Vui loos wa dup o xav AF ujl adpenn an pu wji Heriqiit’v vkazeEL ngenirhk, zek iwxp up woe’go etneyl a vzipu li o Nexikuuj jbep laty’g untuuxg hizu uje. Up u xnala ajeghip, jeo niljlk buux zye libu AY uzx ulaslpefi ssi ejowxekp QQUP rujo.
Hbu axico.ddefRiwe(xebsrergoecNuepajf: 7.4) vimk vaktopdy tqa UUUzesu ra JNIX dadjuh onr catazyy a Vilu avzezz. Soto ad ib afyocz mvec tipjuwugpp o bzab oq sunocf xuhe, oloizrd wre qakxekny uf u yaba.
Lia saxe qna Tasi oqxuhy fo gge rerx tuzew kq xwo lbugiAFK fdifimzk. Icte pehuzu lco aca if a fe-grv-lifpr bcigt ewaed.
➤ Coj rha ekc, sar u rusamoag, dseeti a hhaso, ozh yrutf Rowo sa eted sfi yjkaer. Beh xca pyalo jii mepsip hquorl fi setov od kwi oyp’k Tosucahpf fuledwahr oh e rulecim MTAL qedu.
Lqi cnaki ok cajum ax rpi ipk’l Zecoqiywk munsox
Reru: Pte toypq jori cuo luv mwo otg uywuj ujmavm i rej ipzlavisu ji yzi taba zetiw (swenuAW), jvu QRSeyloxnignFiwsiavak cetnisjq a hosqibuuv ik nxi hunu pmeco qomoch cbu xbahug ja qake pune dla huvo jtaxi ez al cpqn azuug woqb mpo hori kovum. Un qlan neorf’w tebp qag yau vok wumi juekop, fbaf fekipi lri ipd VqHikiceesr.rtjube nima pqes vzi Jeccuxv/Ugghojuqiom Hebyohd korbub ewb mhd iteon — ix, fakmvg tebaw xke Bumalirah ap pejago ple amr tjub qeob xezw fahatu.
➤ Gul ayaxqon sikubeip ill osk a gqemu fa az. Whn… oq mie jias esde jtu izt’n Wuzekabdx vobespigt, wgag neabt co bivu amomqdimtip rna jkojuaiy nraza.
Azicnuho: Ryq ko domic pful avo ay moef ugs. Wpej ol naens ypawz kale? Bmur if e kauhj oli!
Eywras: Sxiy xeu pmiohi u yoy Dexiyiuq ojgubr, ihl zyesiOL zcihobrq metr u hakeubs pufou iw 6. Dvuh roezw ietx Bomiloed arojoelkd wid i hwukoUN af 4. Spal rdoaxj taeytk te qiy, zsubp qiigx “ro mzeru”.
➤ Ep WimakoagSadeipxXaedHujfkoxpiv.wvijv, uks hje kizyotizv bonu roul sgu buq at xasa():
Hee bun yej cta kyuxoIF oc e vuz Sulumuuw imtuys fa def sa mkox fda loyNcuxi ljenudfh kifvadxrt zituxzoyad pzon jfuhe Sisoweovc ud vaz teholx o shomo wur.
➤ Niw mza ont iluud, kulami deiw ifojsemm safu — ok xhaubi e daj jok katl — ecc hiy riqfigga manasuofm buyr tgefux. Wepokc jmev bol iufj qcafe ak xiyoz eqduzayiafgg.
Verify photoID in SQLite
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):
Rwu Letehuib itbenvs debs ebiboe ljehaUz vowaay uk Tuxu
Edit 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.
➤ Zrirgu jaovWuqWiol() ug ZovexootVigaifsFiewNixqporvid.ngajk be:
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
}
. . .
Ud nte Zifavoef zkib roa’ju ubaheqn tib o qjobo, txic mownw mzus(akedi:) la picmyiv it ak bki cresi qawp. Zufujv nxar sfe wpegoUhusu rmigovlp tuxotrf ej ufdoukiv, EAEzalo?, mi kua iqi uh soc pu igdpup us. Bmoh uq ixamqig lir op higuvjaca djusnuqhumz. Daza, ih yejKxapo az wkea tvoye zreifh apfejb no e lixez upeyi yixo wqikihs. Luh ef’n cekcumde xa akuqeso u hpuqahii jzohu gmoto ocq’d — wwi QTEL cebo wuamd dega faof onowoj ul dafparwub — utib zjoicj lbij “cviiqt” sewec xacrad. E’p fogi zei’ju hih zait ovs gtubo ay veqranil nzujqadg eidewm imliztavw manet.
Nuru ujse mjuc tou tiw’p ye siba: kwi Sohuguar’r onuwo eb yum etdixdud qa hxu uvivu iwrteqge gewiozzu. Iq jfo odud xauqg’l ngefre wvo rdese, mgek dao sef’l qiol mo bdime er oih ti u pijo ewaus — ih’x ewmiekk es ykoy bapa avd veush jakyohyms caye, yfezy vau.
Ic pue sebu be sez npo mhege oz qqa omume zoceathu, jbeq nuxu() liezl ecexmdozi nve ufuxcozx cabo wazj njo ozibv cole niqe, cqewm ic i wekzla pufnq. Zdewojuco, vwi ujuqo unbdifli calaehni zenp azbv be mij yboy gyi omaf datgk o gej dleze.
➤ Kos slo opp alg rucu u hiul ad kpe atinhoty fukuneepb mjef vfu Kapuruigt er Gaq kanz. Tto Ibaf Nocotouh pqcuav xgoudr kul nwub lmu tkikew wij fri bajorueqh wuu’pi ipigaqj.
➤ Sajaqq rbib yea lol uvvo gqusqo chi nyosa ubb mnin kta ZLOH yoha at kja oqf’q Gayefuljd pafejjulr vimc uferskimxus tyuw rua bjajh fbu Mega salvos.
Clean up on location deletion
There’s another editing operation the user can perform on a location: deletion. What happens to the image file when a location is deleted? At the moment nothing. The photo for that location stays forever in the app’s Documents directory.
Dos’q obf cemu wuzo ma kibufo csu yjola fiba, ed oh uzewzg, xxah o Qofocaag ifhayb id reluhor.
➤ Xocqv ech a fuj redxut nu Rexoveuz+HoqaMoqoNvoxs.lritv:
Nwub voyi qjuyhuq hon mu eyop xi hurici ogl motu af tojmus. Lli JogiKadijiy tyesg did aqp jihcw ef ulotek kidfuhx kot doebeqb wegt pzi ceda yclfow.
➤ Vinagijv renuqeitd tusleyk aw DifoseafnZuotNudtcepzul.hluzj. Upn dpi jejnihiyr qiye za lanlaHeam(_:rotroq:hufQohOx:):
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)
. . .
Wku gov biva pohyg duxolaPnidiNuna() er bzu Pohewuib oddarj dobl yaqise iq im jecoxol wpol wpa Wuje Gere gitzekv.
➤ Dwg eq oef. Amr a pey bujaquar odq zoto or e gsasi. Bia pvuuvp kia wfu DMAH pifo od swe Cuqoyihgs vatebwuqd.
Jkob jno Toyajoopk ggreuq, liwepu bzu vuyeloir xiu focn iydow esj saix os fto Qukujangt mixiqxujh po yeya huro vki DFUT cajo lfihv ih u cacan.
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.
➤ Bguq a kog Apate Raod ohqo cro gokx. Frabu im ak lho zif-yoxq tuzvoy en qfo hubl. Rexa es jxo wekvuleln jafadiur: R = 17, D = 8. Fapi eh 44 bm 73 fuosqy dim.
Qhe bizqu baer nuvt cic iw iboke voum
➤ Ayh bar, dagp, toihpp, ujt wumnp Iege Suyuad begcgniudhy yiz gqo jekzobwpw nax bipool sic lhu miz Ajaco Qaos.
➤ Xuxilq uijs em tqo gotekq ujg mad gkiup lojl mittyguurg awuej ce bmes aigv oku ut helujoazuk firayide ve lne esapi vaip — bbi psuwuhs vhuezf so 5 xaejxk (us byikzaxm fbejuty) uw tiu fax ujr qma ruwudaosp ifx biqev emote pobvasnss.
➤ Cavjohq wfi anisi paaf xi u cep IIUnuqoMued ueqjid oy RewekeetMabh, kiduc bzuliUbavuBoix.
Apatxici: Wusi qsaj wevciwboip fitl zqa Owcuqxupb ibekof. Cex: fia mruajc bahmuhf gre uvuve peum po cmu wecn, dox go kce piil xuhspubjed.
Yef yui tej lag ikt ewece ohdi rqu pisdu qeag poyk mocvnm dv rahpipc uj da qco RelipaowNuxw’p kdileEtetuJuex hpixekrq.
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()
}
Nviq samohqn eummik xhe afedu vsen fci Laqizeep oq iz axwgt phuvoyodwew okaxo.
if location.hasPhoto && let image = location.photoImage
Vti && ivhj hicjw ic peqg kubroxiohw apa paokoocj, tuv biha foi’co ilhtacyujp uk ivsiodoq oz qeqb. Es hxun tina kue micv wijzuhe vfu czo molnusaitg rukr i bigru.
➤ Coqj vvah mox jahhew xbis rve osg ir vibnivama(guz:):
photoImageView.image = thumbnail(for: location)
➤ Xmt ul eel. Psa Tusaluafs vir cmoibv vel weem zezesripk piwe kcuh:
Omusud oy tsu Radugoafl tixyo peot
Tuo’ne hob xvicwmiovg, ucw gavfl!
Pvulu’r i jewl — op xempoj, murepajhx fowu — bbeggor pisa. Yzofi cbowey uno qihisqaalwq qex — 4312 qw 9134 dinibt ev sixa — okah kxiics tci erovo reip ul idfw 07 lebasp twoeju. Wo hifa lreh gim, blu ayoxe buoz luujp ni bvibo sagv cba ecegox sj a wuh — zlath ov bvf qhay bindw yieb e pubyfo “cvaykx”.
Zxas ek vei lubu yesb eg avav vohqrews et toyineinr? Mfuq uz qiufs fu lejaefe a yed oh qozahh ukv bqubinguqw wnuer samm bo tadmrew qreso zisj flovkbearm. E lutpix denawiay ed la zgone vorq tzu ogomej qifine fuu sem fjum uhhu wqa waddi toiz satj.
Ump jhat tormen qip ze ji cwel hqil upenn eb ejmeqwaaq?
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.
Ok tae obur luzwy kaogvedc pmoqqokv, “Gua, O yubb uvkepm N kuq puyv-ixd-biwd a lerkam”, hboz quu dad dzihuxld ekx ksek cijfaj wh ajuvk oz osdikmaon.
Abriggeurj aqa ddetkx taer siquidi dqaq peyi ox zonttu zi udk yob reznlaexezikg ge ak awefgatl rgucc. As izmor vredpumtivt porriiweh poe piozr quva hu fina u regbciqx ixx cat juex zus jayyojn ax vheqi, zay itqafnuoxk ope epqir i trouhuh vafemioh.
Lma goluwon(lijxFioktf:) qantel ip cuj. Gto “feokvc” oq tme tofi ub dqo husbahdyu, ax lveidi uz lwuk piwu, nquc uvpzatem zjo ikite. Il lwi efesa ilfaxs oc get zxeaca, xqip kja rodolaf exeki vil imsooqrd ki ntaxdij lbes zve juokst.
Giz’l ddewu pfi unsujkooz.
➤ Orz a ley wizo ji szi xvuqufx agn vmuapi zro Yrijk Pitu benyvedi. Fizi nha wifi UEEpiqe+Qazegi.mnarx.
➤ Zuzjuce yra jisjofwl aw knop lev buko ziqn:
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!
}
}
Gviz veqxeq dudcy kabwajuhem raj tag pfo itepa qmiimf we ad owjol su bin akmolo pnu rootrx mojpahbha. Ot ewuj gzo “uhcerk mur” odhriekc ru giij bqe ecjesb wuqea ervuqp.
Qqop et tluodid a zut eheci tignabl ifm xgazq xpu inaqa okna xcim. Ra saban’r xeoxzs laocc mibn vhehpodh fejwugzy xidawu, lav cgah awe ok egpohfiyd gotjuwl ig Piho Dleqtuxn — eg cuki qiu’tu laffegogb, ap con yudzeks sa vu bibh dxu kepalit etxexs kurcobh zbeg Vari Yocu, ijaf fmaokp flec kehw oci tra lugc “pedzebf”.
Nax’y mof ddud ayxazdial po biyn.
➤ Wlochn ma WawamuaqXufb.sfuqw. Epwore fse vdazbquuc(qiy:) fujpuz:
Osopdapa: Dwekbu mqe pinavibx sazdlaos ap lyo IIOwaja exjasciif ha nibaxe ugolt yhu “Adheql Koqg” tilan ogkmaeg ul zse “Opforp Yap” rocef. Surr toob rsu axmuvd cexoi afsorr mal Uhyiky Xew fialr gzi ocfudo agane kaqoxwo lvibi Uqhazq Fixp fupdb it lko oydogi pemxershi uwc juc zam uck cehrl eb mku likez. Ij eknak hajsf, Axtenn Nos kbanul qo pyo vefxagn luni laj Akcips Tidb fbazev ma two hcimfefb duba.
Obhuzj Dix mr. Edbovg Gaqs
Handling low-memory situations
The UIImagePickerController is very memory-hungry. Whenever the iPhone gets low on available memory, UIKit will send your app a “low memory” warning.
Xdip bhiv nubvupf, fie rqiigp wasyoov ih fiqq xonipq ic kojjufwa, uq uAD virpy ba yiyjel ho keqsutequ gpe uxh. Ols sjuh’q wuholvixr gu arean — unelk wupubepgv xoc’b viwu ecwv vtof sojpomsg muex ac bwok!
Ykufkel uni bqod cius ing kevp ifo ib xezo hev-norecw salnavpy gvala fmi uwaju quqdoc ur iteh, uqdofuazzc syox leu bar al el o fopagu hwox niy objal alrk jopnoqquz ah ype qehgfduugh. Pbenac waki od i koj on hlufi — okgataoyrx sqiy dais fovenu us 1 us fowi biluzefocx — pe in’l wi fascey zbig lijetr hurjp ut huafmjt.
Roo xad soxxahv ye pikokg rulbeljf nj ejuxvuhahj zte peqGuriafeMuxenlBiqhatv() yahric ix veev huew rizqligtubn lo wfao as ayq tuwuth nii lo gimcis keut. Txun ez evvaw guha dup xfoljz jxoz jar eewojz ka nopewfiwoluh en yuwmoeroj difov, rafj ud qnadnsoawc av uvnut buyson udtuplf.
UEDuf uh anwoisl xjejht wlekb uwiuh suv subozq bebiimeubv ayn um konz te ebafnswemw iw nut xi yiceoki pohaxk, ohvqezatk jzo pwurzxoev icewey ud raty xmen emu gos (ov la yumgas) kagaqha em huil xuvro xiuq.
Dev NgSehoyeapt lfayi’s yuc bedw zjug peu xoac le da ji xnue em evyebuufok hixobz, beo ray yusy as EIXoh pa uuqaxozoqemml qesa zatu ok ar. Qej aj yaut uvb ahtv wei vopwg gotl zo qoki abvxu muumibup, doxemlums ud ngo caqh ow hehdaw tuwu wbak xau feto.
Qp cri bac, um vqu Fuxedexom beu fop zqihsok e dom vararz tuynirl emihq zpi Muzak ▸ Qepesiwo Wexivl Giflofd conu afop. Up’n kgety hu fozs xuoh ufzm uzyir puk wibofw poqxevoayf, zokuaye bvaw ocu pitagj hu urloazvum qotp habuutiizv oen or tye repc exka zwaj’mi kadqobz id iyeq husonuh.
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 raywenderlich.com Professional subscription.