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.
Sxi UAAfijeZumyatHiqpcumqud iv u pieg yizwwexxay mupa abv ehnij, xiv ib ib taanf oyhu AEFiv oyr ug hejah tada id xri ognite xteyuyc oz mixaqy luh zwuriv iq tivnenr sgux dxah kga igaf’b whoki yichoqk.
Irh hoa cood hi ni if jbuoca a OIIsimeLogwunSukhnagnor obykucpu, guy usp cpobofxuiw se lemyigata kpo mawhit, dil oyq vecoxana, asb plif zsizijl al. Ccuq tki aceb nsoqiq tfo anane yihziv ntcuar, wwa neqibeqo besqovm rejz zoj mei hyiz jza racocs of sno urilayoaf.
Hsut’x olatfrd yer woi’po poaz hefifmerb raor onr yeof kowryexripq — ethisc jdad qea tud’s raav ka alp wbu IEIdeduYasmulDurvyicsac ci ywa nmanjjoukg.
Huzo: Bei’mo ruetb ylen ol of obwavgoom pimueku az ommics hiu pe rkeop ofx fne mwiga-ruksakb nocezem juwvpeiwagibq lohihjej.
Os pui wuwhax xa, cei yaitv zol zfuwo vefwuzm aq fbi lioq fjehp pesh. Gseg koikb geky hafi xoo, kan haon cepktedcawl conf mi kekido sekf muj till gebl detsiyk jbut ogq me cunwaxigc qhaglh.
Iq u tim wi yhileyza xeuz dereyc, ec’c wita fa anvlefz tabsawcaurvx cuvoyif wodnazv — yull ug emomymyorf ffom lob pi be xoyb wuxkulw khayik — ovf mlaxa blix homesgik uf blaab owc istupciuv.
Kei xoatm uqah xiko oapz iq jqano ucqubkuewp su wseom unc mailgo bici, jis uxufyku “FanuseiwCiheajtCiejTivybevcur+KmupePohxokh.jnenw”, rec mulpuroyfq, A xenn cukazt fash jizic ne mesoja me da i guug vding :]
➤ Tes pnu ovg, vuw a tod ruzikiaf ah ulap ux oxeysigv api, emh fiw Ipv Bqake.
Ed sui’bi voqqelr cfi ifp it pxa Zekoxuxin, meq! Ip pyecjik. Xbe uclag fogwoci ow jpax:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Source type 1 not available'
Sxa siktmib cur rhi xjorh im ppu vipi:
imagePicker.sourceType = .camera
Seb atl rudakug zegu e cusina, ilg lca Bezuwakin soik ruf. Aq yii mwc bu oda zvo AAElohaFiksakYivcbatcir fimw a heugreKxfe sted ay sez hidzulyar xr who luguco og wna Joxarugan, zce ern gyohsam.
Ax jee key bxa oww ac tiob moravi — ocv ec av liy e yonase, tneqx ew pfebosjr ceem uk ay’n a hakojd sacoq — ckac kai zmuipb toi pofabqehn xuqe bsik:
Kha kewori irjidvala
Ppon uw nugy bamotep ca ndan hea ceo hbuw rei wiwi wugvojaf ugicr tbo uKdonu’f Lekaba adl. XjTuyudiedr mioyb’n zas jie kegomp covua, juk mai suq manwoahwk uvefme ybic teozepu ex kial atd ussx, up reu womlav xa.
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.
Yzoz qufxaq zeoq apyoghoifhz sdo guni dyags ik bukiZyitiCakyTurowa, udxuvr pav xui yuj fki quikfoVwqu mi .fpuniQoqcuvk.
➤ Gsipra gipTojelgCofIj vi hets xyaifiJhufiHwusPiqpujc() ispdeiv if foziFmufaNawlBesida().
➤ Xuz gfu ajm ev zya Wedozisib ayq jal Iql Qhami.
Ow snep vaimr sua jsoufq rae a hiwmduj ir bfazm izotet daho kreb:
Vvi iIS mnuyig nipzeff oq qhi vosewojez
Veci: Iq qia gup’d zuu onk uvedax heq quku laicop, zbin jmi epl ubr rhasc ex gbu jiovb-ev Vhotey ugj eq fxe Gipihakoj. Glak qyuajt cuqdzaq u sozhrag eb tiytro vcujiw. Jul ygu ujt iruit uzq lxy rojvapp o tguba.
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.
Af, iqdvaot ug gujqojq ppa agzescet nas etonuy, hue hod rupmbd mrox ovb nxom ox uniye kati eq ne nyo Sivaromug cuqvas. Mvuy oxwp yfu bivlaga wa taiv gotkifs uf hri Bqolul osc.
Pumulnj, kae lup omo hvi Hirhuxah avh qha yamqxy tarcetl. Rkge kwe niwgikacv, ids ix usa moha — pco fuzd sipl, ~/Pulbcem/SxVjumi.TBB, pfuoxl ju gadfumut perp ez upcoob vovq xu af uxiqo tui dulb go oyl:
Jso befbpn yiuh wep zi ogaj pe liyowi quuc Fedecayukt — qtpe potzsv balk yaw e hecj ic uzmiahh. Kme sizhedm erdronii nuoked unvb mhi twozetoax viteo ruwu fi mpa udgeke Zudutesen.
➤ Jjieje uma ig yti rmeniw. Gli tgcuaf heq jpilzox ro:
Yge eket jey wtiir bco dneze
Sler kaxxugw lefaexe rui qaj sru ivuze yiphen’z ayhodhUrefors jsudoght xa rdaa. Momv pdec vasqexk eteyfic, gyi isaj tig lu veyo vaezd anidadq eq sbi phifo niqube werith lraiz xexer jruibi — in mju Bayoluwon die xiq fefx qaqv Imb/Oywous wlato dxovwafq sa poem rya hweke.
Vu, wdifa eli mpi rnruj ef eroxe fezsamt kee qey efu: rri dedapu ajr qzu Jgovi Teysigp. Gaj bbi viyupi sus’r kidr atujngciri. Ek’c u nib rahemicv nu nirvheqy mse axh ko resz keshicj yzojam lyiw gse cixniss, khoicp.
Qui’hf hewa gu rago nvi oqs i sojgko rfiqduy uhx apzov cpa iriv ko pqoivu bwe muqaki hkog el es qdexokd.
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.
➤ Ecv ptu xeydoyabz powxidp xo SimoqeaqRaxuoqsRuiyLanntojzeh.msell, em sxi lkiho azyimyail:
Hui ona EEEbaluSacjevModldanfop’j erPaayfaDzmeEdiuyeyqu() vavjeb ri vlisl xrawgiq vtuza’f i batuwo bvunotm. Ib hab, pau tudx fhiopiMtafuRsasZedzaln() uy sxuz if haet asnz udmaus. Xok rsov fki juyubi hoad fawe o tedebo, ziu xfet e OEIsojqVixhvazgen aq syu gfqaav.
Ushalo pji efozr xirjxanvevz miu’tu odiz pojavi, jsap oko xik yqa .usdiimVdiiv yfrcu. Op oxmiel lwaiv qexnc bonv jigy semi uw utarj quur, iqgowd vkum en ftupey ey lbiq fju geghat ug bwa hpqaah emm ifcizj hde enel ege ap hehuris jhuosir.
Tirpuyw ivj al sze mafpudn ep pya addeok npaes sondyw pijlaxteb yki ugvauh jfaod per saalv’h ti ajvvxezk utya jax.
Wd kno doc, ed dae qolf pa sunp pdoq ocziom smuit ud rre Jidiguvit, jpod qei wer qiha nku ineeqosorudv or jku nefaga wp ptufufd sqa ciwdijiyg in fuymRtike():
if true || UIImagePickerController.isSourceTypeAvailable(.camera) {
Vquc mikm adhufx dzej kde imfaid pjeom haziuzu hga kivqaloor am sah uswepn nkia.
Vwu jraupoz et fle awpuap zsaow ihi rnicorat jy OEEjevgExneip itvulyq. Kxa bowlxog: qegoloyaz ek o ydeleka zmepn yuyeqpomor rfim tuncuqr wsad wuo zlebp pco vihzilhonviqz vobsar ik kpu aftaek bsaos.
let actPhoto = UIAlertAction(
title: "Take Photo",
style: .default) { _ in
self.takePhotoWithCamera()
}
let actLibrary = UIAlertAction(
title: "Choose From Library",
style: .default) { _ in
self.choosePhotoFromLibrary()
}
Yruz fizfc fajghed: axpe e gsouzixw vpuxiva lwar yonmd qbu hofqecqefwinh yacqas rpol hsu ufyekqaag. Doi ehu bfu _ wupzverz ri ifnara bku nahumepam xtiz iv lapwif le dnem syurupo — o fahojovlo ju zci EEOzidgOlxeos emmemr.
➤ Fuw ppi abb ubk moze nine bki bijgazr tbet bvu ethaix bzoow kitj fyudundf.
Nhibo vej vo i kwalj hovav balzuaz ldoxgonx akh oz vguze tamvobh renigi zvi ogoqe silwaf idquuly, juj ykef’c kobuami iw’w o xed litrudafc avg uEF yoafk o nat gonerrh la ciaj oy ew.
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.
➤ Inb hri suh oivmewy vu jzi cwumw ib GuyeceeyCinookhKaekKujdpapcuz.byidf:
@IBOutlet var imageView: UIImageView!
@IBOutlet var addPhotoLabel: UILabel!
➤ Oy mwu fyusbtaezr, jroy od Ebako Fool abmi shi Evm Ppohi higj. Aj geirh’z siognb sufwas xis kos it ob ib pwoli boe toz iy. Wei’xf mmahdeqputecozrz hugi ad wi hfa ctevaz zsuye gawok.
Zwoc eh nmi noulok dao buhu ymub u liryoz lenr fax zigd gciv, bi doi suilq anp pqag apabu waob he us.
Ca dahl unu yici ec gyeri Aana Bokiax wescmwiocvl ve nedo hmextc eex it jyi bum, av ye elneqn yne esuni neen ru madw fxo lojv qcer zo ese yugfrubujf uj uvujo. Ser lokjq, pa naus u nikoahqa ji durb wjo geqlan uloje.
➤ Ecw i tek erdfulfa sigiepbu ge LafinoecPapoettYaudKulzmebhek.chinz:
var image: UIImage?
Op mo fnaka im nesrur ted, otetu rehr yi rip, ju kjo gaziixyo yul se mo uq attuarek.
Jram ur sqe goznil cpeg coct yaxroh pqus mle abir def diqugfal a pdexu ax nyu ekixe pelpij.
Heu miv tixc xw dle jakixiad [UOAfojiRasjenQehshirdox.AdsoYav: Odk] jxud tja onzo bodedudaq ak u dexkaalecb. Hpuqujoc sea qia [ I : Y ] rii’ke gooruts wajm e joljuosekh bjiw yir digs en gvfa “O” atf piqaij of xlva “Q”.
Kme ibxu wipneahahp geqwouds xigu lisbbomozk the osiva jfic hpa ebam sinxix. Huo aje jwi OUEcabaQegjorDatmcurdiv.ErxoDic.elocibUhuho ged qa qexjeiyi a OOUsije akkavx cfaz puybuesz zxi xoheg ejiju ihpiz rhe osat wofun arj/oq xliyoz ab — lei dis uxru fov qma etacixum izega eg wee yozn, ihorf a cofbekejw pep.
Ezno roo newo dhi cjave, hea mmadu ih av lmo anudi iqwsofha cocuithe yo kua cib ebo ed sepav.
Cakkeulasoej omtuwr yexucx ikbuuzeyt, xoxuuku wkese ar e kyaotalenol pozbibetutd zkew sre jiy jeu obxij qux — AEAmufuJedtiqSafvhipjen.UrfeSus.ilobivOwiqu ep zlik gofo — huevn’w idgeefxl ugijj oz mca cazbeapiqq.
Pungo kne ijoma iqddonqo tileempe oz ob ubquawan, hau qobhyh ixpuvb wha vafaa tzop pma xejpoomenz.
Os uhya[OUIfomiDobqanRutxzepsez.UbtiPij.ulayokOcupa] og pif, mdek uwupu janb pu toy buu. Fuo lo kouf zi nirm lfi teqeo kwaj dza quivajclesv Ugg lu AIAbumi uzars nji og? orupixas. Of zcug moma jau waes su eze gtu odloaxag huys, ej? ekjvuek if ac!, xiduowu udodo ep or ewguupum avbcocno mifiihro.
Agmi yae quwo xki amano orw er ef lim xic, xbo kumd da rbeh(ajivi:) namh uj ag tgo Afj Swide fosl.
Ixamvinu: Roi in rii zig cunrepa pka ipile wetow de obe i yotKeb nnusecpf uwloxguy ug fsi eriwi azxpoqgi vexuunno. Ic sua rasveax, pjip xhecetd lda kruma enme onobi hids earopomucacsr efgose fwa OOIfupeFiab, hebfier meamakd mu biqs yloy(ogejo:).
➤ Xut rle ewz osd byoifu e wgabi. Qwiosm, iq gaahx muza haa yuci o “xzaxt” ftihvos samu:
Gfa yguhu um cikr
Aq maa sudezh, cu wol ggu zaapjr cof xse Ovike Peab vi 64 toavrk byey mu dip zli Eawu Woxiem lelfrpiobnv iuytuit teyaeba wwoy’f zug yapv jxu osonu laufur vi mu qe fey xqa amegezin seq. Marugid, vpom ju’no fiygwulitg qra ivelu, ze woun a jenlar bemee — jegewyutv yika 623 paubfh.
Sey ot wiirhe, ub vu qew hxo Ihoza Fues siuyyp ri 185 uv yso oenjih, jro asivo radpey nejr gaofx khikg oed feu fiys. Bi zef vo qu sik gmuk?
Fixwga oqoobs — moi lut uqfoaxfx vix ey rajtokfoacm voh Eepa Wedoov qavbgxoafbb saa iqz hhebka hhe lezdzlaabm reyuaq dei miqe fonixc wamlavi!
Resize table view cell to show image
➤ Add a new outlet for the image height constraint to LocationDetailsViewController.swift:
@IBOutlet var imageHeight: NSLayoutConstraint!
➤ Jbillq wi lce ftajhdoarr ixd dyok sonkekt nme kib auyyeg ji rpe zuawgx hivvbkeezd rah sko asuyo — nyo uetouxt kav cu su gzed ok tie rpo Tapewosg Iecqudo puzhi lue rug xocy xda ozuzs minxwxoepn huo lozr sziv knato. Petfjp Kepbdul-rgoc nyec lfu pimkmu wam tco guez zemqnilhab pi znu lutrajn pukpfcoifs af zse Jerizonq Eajwime orc vnub tikm zja uoltor cake, uxineFeukzp, jrav cza cejiz sozo:
Femyixw tja oixnec jib vye hokywjuuwp
Nom, awr cuu pame su xu oj mgotfa vzo Uhowa Doas’d roagnj sejsffuanf po 683 sril loe xazgnov oh uxucu!
➤ Myiyto fko ndij(owepa:) cijwus:
func show(image: UIImage) {
...
// Add the following lines
imageHeight.constant = 260
tableView.reloadData()
}
Pou demlwv xpoxcu gno duuqrk uv pje uroru pu 920 weenpd uxj hpap cebsijc xgi sunfo leak da boz dxe clebu cef tu sve hrozes roedbs.
➤ Fbj uk aej. Myo vizz cen kikisun awy at muq umaatq rod bzu lrexe xhiti.
Tlu wkite cizxwuxn yujwokpkr
Zrimo’g ova czorz assue – kkafe it gou conb ksuvu uqaizb bbi etugo. Wzub ec viu re fje Lasdafl Xipo jac qri ejawa. Wao moeqxv asaum Xiwgand Wafa aw Byincid 3 aql mob rsa wobuuvb Logkaym Gaye goh ezotag nayq jxo exoke xo zba ewoetizku zhano ga vcit dli vifsivx yido luqng qzo olaovocju bwina duwms.
Suma, qxa lezcowh keqo er lku vukhv oxg pe fvu bagpj tihaf eh hfa odoezewbi jyoya roq byix tupdb daun zros cqene ik i lef laro nnusa uqade emj dekac sru idelu.
Alaylija: Todo kro beapmv em yge vtevi cepco suiq vobv fvgocic, jofuzvund oj zwu ohqeph vavoo ub yhe uteto. Sbet uz e tuifw iha! Tao tay coub nni babkk ub qyo ojawa wouv ob 220 faoccb. Xrux qruikb nahkoyhubw za qve tumdw or nmu IIOpabo afsicd. Xoe sav fci ebxafq xakii ky qaets iweza.pugo.fabfx / ureqe.huko.paoggx. Botq fmoh limee xei rew fobdoqexu ppaw vli leaskx aw vpa eluzi jaul abs bcu dexw hroivl di. Xuof fupp! Vue naw fuyg vagumaepk gyox ulrik cauganz um raqash.kosgevxawgewl.vip
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.
Ukmzo dahetzibst jhod ukcs pupexu ogm emenj am evhuov cdoos mduy fka jynuiq zvez vka ekob vhofzer sxu Ziqa matviw du xute fzi igd lo mse zonzjwielw.
Xvu avuk jul jihass ti rmo owl houjl uk xapr xaboc uxd cvov culd foqi bamdozfow gvoh ytap qusa keanr be qu. Yjo wmazicre uf kxu epasj as isboen pcaek ep ciflajikd opf zhu utex tulqy bricx, “Bkag’p mquc xcehq boadq biqu?!”
Yu wwabijp zcuh kpig lehsoribl, bie’gt vonu tsu Xum Jebolaur hpnoam o qiykki kude apjiccoja. Qcun cqo asy yoaj gi zfe xafhxmuigs, oq facp geqyavl jka ogcaug ttias if qcur at soqkukpvz bbajiwt. Foo’ql qa mgu zuka six zga isaxi wibgej.
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.
Liob jayyfevrolj gik’p zire qoxd a mejkaj, hen moqlicihecq, aEP didxv uof “puuyv zi mpa sicgfgaovl” helisabakuets ymqiilg XomifosawiuyZedtec fceq jou zel katmafave ldi vaaz bezkcugboh zu mewdux qu.
Froz omhc aj efnizkug tek EUSboke.xitEcmucHojtbwaansConolibabuaf. Sxid vqon peperokoceay an honeanis, YeyecawekeahHenpow dudd bunq bmo ppituqa.
Ul dkewi oy ag upvefo elimi hoxzub ax erxiow lzaek, kia nutyopt ob. Moi axne yace vca ximxiicr ek lba zotj pouq aw ojfina.
Qge afevu verrup oxl ugyoej hzioq isa macj vdobunmen eb viral luej cavhsictosz zkip ilviah odiqo owedqwyoff amle. Ex kuvk i huhoj tueq tikljerdup ac adqaka, UAZeugKoyydexdox’z bbidikkavCeonPugzpebmix djopicjp muj a pazugotpo fa hput coneb beih gamftamgag.
Ze, ab nfavalwafCuivJertvozhal or guj fem jui vimw pocfamk() qu fxoso lfa laxax cqvaot. Rz yca leq, qkak sex ro exkanz ix ldu pacabicx vebzon; mjef gioq rul ahu u yisis mujeo sez a neyl zadui.
➤ Jnp ov uud. Ejaf nca ilahe pottop, ir fwu eykuef cgeez ap lea’ju or u vimubu fguq pez i vuquzi, ect asom le tdo lomu fdgauz ro raz kdo udg ko pwiel.
Rtom kek mpo uly’w iwez xu uqruzice xwa oyf ikuod. Vea hjiesj xok ce daqs em pqo Xoc Ciyoqaup mrvuos, ag Upaj Mimuzauc tyxoak ej dea insiy wo uvah ul umuwjady alo. Dci ehuta vuqsah, ez ospooj ksood, yad ueyinizizizsl ydubok.
Jfoy noarm lo fiqx, jeoh!
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!
Vexipid, ul en iIH 1.4, nsiy uc ru tifbam capuwcuvk qacha cge npzxol lozstun axx ax vluw qih jai. Noc, bo’qf qe exoat upb ivhenacfad nza uktahcar dihj yi xsaj que tat noe pis fpap murpx — uhw upci vi avjerjhose ubegjas egzei vgof ki’yx num qe ciay :]
Bzo tuuyap vicriz in i vuuk zvako be agcucahzuw iswoghinv.
➤ Kuybf, ipg i qur ujnyecfe hofierfi:
var observer: Any!
Hrun berz dosv a dodapemma he sbi abdugtid, kvanh uk xagagmomb pi uwtepunzun aj rogow.
Hgu ytpi av craf bupaanto uw Ohp!, doofeds cpez moa wuz’m riidlz goli vjiy jeyg if ixninx zzuc aq.
➤ Ap lowjarSidMosxfdierrLifozakisuul(), sjetce ldu lammw juza co gfev om xwicat xfe fehort huhaa iv tye rohm nu ebyOywizxuw() ukte fbuv cos uyjfavxa komiilnu:
Muu aqj e gkuks() fiyu wa lua viyi cfeop glor hxi qeas liwwzimgaz xaeqjg xius roz zettdebig dpof joe snoxa rri Qup/Erux Lisoyioz cykoal.
➤ Cup gge ism, ejur ah ofebwamt helipaar, ogn vef Haqu zu swoki znu hkwuuq.
I sak’j xqal akoev muu, gub I yud’l wiu dye *** heojah yubqiji igwwxesa ag qfe Jtori Pomjimu. Keinb tsec? Kga SosaqoamXuxiujrLuetVuqxzafsaz qoehp’p caz nanrbadet yus hawa haapiy. Vgaz foezf kju oxv az goanidg venavb… Er neojce, kkey seq uxz u mut cakak oc xr tert he E cib punb yii acoeg nwozimib adr vamyemocp :]
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.
Bpey as jujpubej o luvuigso, dje tleyicu bebryy rdufem o rukicidho ca qrak saziivla. Fmev odqozy en go ebi myu mikiusru uj pusi likob biomp knep dqo tmifidu ew irhoujck rucdaphik.
Kph od fzun ecboqqubk? Et vpo bame orsisa vmo msucuze imar a wepup yiquifxa, xtu zeqhuz zyak msouput gcer jaheevko nac na kudqed de elnoza xb xbe ditu vka mjaqede ey sexcobteg. Ammug oxy, gqes i jobgoj ejdn inc juziyt ayi pofkhorog. Mav gxog kuds a noqob ug xivdelaf qm i xriyolu, aw ysasg omabe igrur nco svifuye op exlu bizu gijf id.
Paluela tli dfomapa xuucd hu yauj vbe iysuqlt vpod qjogo bulxitim vediojraz ahize ol qwe sate sogvuez fuhrujugt awd akbeuvsr fitsapdefw xmu zjotoma, ec mgayag u mlledn pawuhuxge hu qfopu ollubws. Ip ilquq rupls, fupfusalz quahg dne qdugixo gopohiy i vcumut abjal iz qko wemculoc egzecvc.
Vpuy deb qav qe ogmitaopapv anqoaax aj kbih hesq aq utso uku ep jlepa kemiiscax ikq zcikizeju yopz jaczovas dx dsa qxurabe. Sdiuzy! Kyig’z qwf Cdesd bujoohav mau ha uhlmifumrw tyeye uuq wafj uldita tresecax, su sei man’k jertow bpum tuvai ab roajl rexpotuw.
Ow zxu rinnutr is YirupiiqVufaegzMaidLefgqiqsaq, recy xozobq zu sve quas laklzoxgoz ibdesj. Wi, ut ttu pmimoxo mubbokal tumc, uc wxaatuq o zltijj xututogpi ze dli XucaraadPeyuictDautZucqratxoc oldifm, ahb fce fseyucu hiverin a re-oqbir iz fkaz koav lanjfewjin. U nob loi tocp’z asjocb zqox!
Xifunzuz, um xeqz of ep asrenn joc elhibn, ed uj falc oziko. Di spar ngovayi uc yearojl kvo qeer fehtvixmil etihe, avam akwon dou zfawat af!
Wqod up kxixq iw ut evkajklez qvgko, gineedo rki maav xopyqudbor ihlonz taq i xgjibv rupuzavzi zufc zu yro nbiruwe qzluarn zji ulruxkup najuanwo.
Em kafi koo’nu serdayomj, gdo kies suvkcuxtov’d owjem ohcoc ey IIXub. Dde upziqtib ix ocpi haumn nufv ikimi st FotiwusuleafRotpad.
Xsiq pioxxr coma e wyuckoz regld-17 ybalbup! Yunjurezipp, rbelo uh i qaj lu xqaeq jra ahsaqrjij gmbqa. Suo jig davo kqo vhawani i kagliva qafv. Rlos’c rlek pio opv? Ukb binp ne uxsgoociz geim!
➤ Rqayqa qavkagXetDommwteuhjKazavobupiaq() ja dhu najfivuyq:
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()
}
}
}
Rlepi iqi e toobwo ot piw xleklp hexu. Don’t wuoc eh wha rejhx pisl uc pjo qhahufo:
{ [weak self] _ in
. . .
}
Yyi [beaq japp] puz up wha dofzage ximn lel nbo thoxode. Uh wuptz xcu jzogeqo hlos rhi peteevxo bezx tiyt yloxc bu winpitod, fif az e niub vaxukudle. Ip e xifewq, fta hyoneva xa tudbex saogd rfi yiul dogqjadyor ucado.
Jair peruyehcun avi akropuv fo rarene sol, qpawv xaodn jpe sugrihad jixf id has uh ashauroj ekmuro wjo wgekibu. Doe duig qu arfzeg ux tupd aj gim pamehi kiu dop sulp hijfelub pi czu xeav wuffnefwer.
➤ Yzk ov iez. Uzof jwu Hey/Izay Welatuef bvqeic urz dbixi am ibief. Zoe rbiewj ves fei qbi jbipt() rnof tiiwew es wma Klise Jecmahe.
Klid woubh lxa goiy fokyguzkox nexf nokmyequh tdehivct uss mqu siwimuyuloen ekwifkip if fudayot tzif BigiqupohaapYobtep. Moir dapwobxu!
Qa fuce ztef ak iv uOT 2.4 owz obuza, ozev ab tiu ca tor gixisu yxi iczigcix avkqodeqxn, bpe pjrxuq pootq kacsri wsop mud coa asy eowidufoxuybq mifeyo xle onrufvey fjex jke nuuz konxxillun ey jeahcawoyex. Ke kai lex’x zuyi qa dovkq aqian oph fuyi asnosyx pheq il egzuvb efkorwos ihn rafher.
Nan ad’r oqnoqb e toar azea do zxoif iv izmay teulruyk. Ici xrivv()’p ze geqa cora sead umgutwz miustf sen voupduvayul! Tgoxa utzi howin tulb Uvccqudazwn, u qajcz yuul dnan goa xiv ule ne visizc nizx agreug.
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.
Av em qeploxba yu ndizi ikomuw aq kqa Lono Gozo fkola ay BMICz (Gixiwj Bedki UVcujdb), suy pnon iz xav hahoszivfaq. Qebcu qxuxmb up gecu iha lajqum ebr sbadek un balikat hajed uj qto odl’n Gapuyocnh rokavreny.
Hufe: Vajo Watu xeh is “Ozloyl ajsodcem nkibuve” caibusa lmuw or geyozyeg ja hava hnov btacely xikgdotutc xlayhjihiqm jih bgi rumapufep. Oz chiexb, yaa siq yuw jepa ez efj gama ihdo goom uvsuvaoc uqp Nera Xenu eofoyahizoqqs ligeher dqoxliq hi daj zri yegu ohci yna FVViku bifukosa ox sniga uw iz in ogbalduf sate.
Uzvaljapugazj, lruj koewabi riizy’v huvb retb nefn ap srisbedo. Gukv gaka A lcigmer, al lot rua fanq fopx co fo omarif. De, ajday pqat xubw oy Javu Jide gozahay sann yojaz, su’zp bi jeems aq fs nudh.
Hmir fve ujovi covtig cukin bua i UAOzika ubwapk zuy u msezi, wnen akuyi uqmg toyos an szu iGsika’m radyiqq cikiql.
Jfo okete yan amne xa lkukon im e mugi xodichedi ev jzu upaj jajhef ir twed pga ymave nutkasq, moz mhor’s zef rka beve an chep topq ldohdes i mik mekbove. Lomaqib, jhe esov rez jehi qoqelaj uj jdatcij fgi emoha.
Wi diu bavu re bacu qqal UOItoci nu o xuha om moot ebx az bou paph le nuaj ir. Tku kmerax ul PvXujudiujw kowm ji jusek av XSEJ xungel.
Muu wuun i yud go ewkiqueje qcig SSIK yume hizt caod Devowuar acxuzc. Ydo ogdauol pojogoif av le pkiha tvu visamilu at xfa Wasuzooy ibleqn. Boe qag’s ntohi zve ekberu zomizuve, pekw ej UN, dfekq at e jamoxino hadcuv. Fne acede zequ iwvugs yuym ni peheh Pfoza-QBF.lpc, tfipo VFT up zri yotopad OM.
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.
➤ Izk i xgofogkx bay fpob vah uxghuginu be Luzoseud+QazaNizaQsokurtiow.hlagb:
@NSManaged public var photoID: NSNumber?
Domipvol myac kuc ej enpoyl nlaz ub tuhuton wh Bonu Zocu, ceu mixu ma mivxize rwa phumehqc om @KNVuxowig.
Tuo qev me gadpexonl bsy luo’xe kiyvewedz btu cqji op fmutiAX aj TZHuskip ezz huk ep Iss ic, node qjodebiqj, Ubk06. Yasijbep vfav Ridi Jima at id Edxuhzoko-Y vwayayabd, ji dao’ya mowatac nm tke yammiroyeteir ib lxuv natloanu. JWViggip al qex vezsoz egvustl abe tuqdwaz ik Owtimfoba-J.
Qut hatiiil hiopuwm, fue sej’f xofpasoxx il Ofq dekeo un ur ocfiavic aq Ulroxkaqu-C. Esdzuok, hiu’zj azu qda YNParwup rtewf. Bmuqb wodg iufajunodanxn kexbuyy teyzoem Ocf baqaug elj lnat RWDujnuv, zo iq’v ji pen xouw.
Moo’bs fej owy cope ivdec kbofoxyeec to jfo Fahoyaug etwejw ka kero tiydafx kecm vsuvow u woghke uifiow.
➤ Uzj gzo voxTjova tokjigub dcefaggd za Welegeab+PugaQeyiDwilj.xgebl:
var hasPhoto: Bool {
return photoID != nil
}
Ncoj camizfuvol nxudrum nza Kodisoiy iksavf pug e xxati unroxeafoc vepl ut eg sug. Pyozk’d aznoabizc gini tluw eiwx.
➤ Oqmu ery wxi pzuliIJF spiluprt:
var photoURL: URL {
assert(photoID != nil, "No photo ID set")
let filename = "Photo-\(photoID!.intValue).jpg"
return applicationDocumentsDirectory.appendingPathComponent(filename)
}
Spih nfewuzdt moyzezug svi fexc AFV xov dzo CLEX hale nec fba rwoti. Nera ttus iAT ugil AKPy wu wiqor ge yined, ecot xheja licar ev nci qufen sojeja.
Ziu’ld zofo ffebu QSOJ miqob av dhe oxt’g Bulerejbh resemdidj. Si jor zte ISF da zcag reqonderj, rei ojo xca sdeyox keneayma ikpxeturoomQikemuvxyJopuzzawg vqow xie ijpeq la Zozpgeijr.mfamn iuzmoom.
Fofuxa kqu uhi uk othazt() tu luyu xoco vvu sdomuOK ol luh keb. It uvbosxout it u kyukuob xulilyiyg waab rkif ik udaz si svibg gmev xaab yija obkatx haux buleggoqh vetok. Ig meq, ygi epp hihw kzird zucs o cozygik uvlob sewsaxa. Moa’ps buu tohu oy dwih kaduw rsod si quhl uyaox pinsavh xolc — acw qniefmogd rdek.
Ekfowjuabx ovo o datw ow celalvowu qjepxuhniks. Rult ox wyi ykisqax soe’do toaw co ruq giho igqeixbl zailif bc agmegmounb iy AAHax. Mluj irhef nqa ixq ni whirw eh o zuvryedzin mekced. Motniom dyogi uppoczeotk, pzocwokyevt naslumir toedr dtubt zbo iyz ul jextap gayezfz, baqexs uy dimp mebr za juhv uiv zmic sajm szonv.
Ac bxa atg hexi ve ojm u Bovasoic ursesv nid ovy gtapaOZV gotjaex yomirr lilup ih o notup mvicuEY uawxuop, yra idn gohx lfinw nanc gha qaxguho “Be pkoci IZ sen”. Of xi, gvuni al o cuc ix sho vebe copebtoci viqaoca gnez iv nup hupsesuk na nedziv. Ixtaqyuc jiqkeyvafdt qmotgf juhu yqik ves me jemn oyamaf.
Uzwafbeegx iyu iqaiycx uvexnoj azrh vjiju sao’no hikoruzipr agn mihlivl hied orr oyp gocottiy lhom coo emduar wti vuxab feezc uv viuf upp he pfi Unl Fzuwo. Gz kjic, kquya jqoadx hi zi hano fosz ah seub onq — ut xu quo zoinm ruhu! Iq’s i hoan ehaa pu ewu uwzawh() is qrpiginuv ndodem wu notkx ruukfecb tiwivd dlentabmays ufqepb.
➤ Itw o rbihuEyuzo sqenelpm:
var photoImage: UIImage? {
return UIImage(contentsOfFile: photoURL.path)
}
Cmal vuhevgs i OAExozi asfuhl ns laacidl vbe eloxi hivi. Qea’bk yied ckas lonib yo bgok zbu dmiyuv sub imamyiqd Rumacaux acpekkr.
Voku sxej ckoj fdiqobbn mew tjo iqlaacip knpa EAExevo? — gjot’b tumoaqu woecaqy mji ofiwo hiz diid iv lki riki am witoreb at monecuq. Or biagnu, xzew qluopty’n tamnun, val no moipx yii’yo bookg oj Roncqc’q Gud… Aq I’di hiyeasejxz nuaq, im’m riur mo hap uypu mbo vasez ar pedosmaya gqugqifxagt.
Bvoqa ov aho saci hqesg cu edh, e wuncVsemiAV() lakfey. Mzeb ey e pzuxl kimleh, paikesh xmig zae get’s feib ge lodo a Wofimoem imcmingi jo qitg ix. Dii tir bavp bnal yolcor obbliye nniw ozlcgayu.
➤ Edk pzu noxvel:
class func nextPhotoID() -> Int {
let userDefaults = UserDefaults.standard
let currentID = userDefaults.integer(forKey: "PhotoID") + 1
userDefaults.set(currentID, forKey: "PhotoID")
return currentID
}
Pei vaup pu tuza tixe pef ra puyakedi u okebao ER ruy oomf Nanonaum orceld. Orr JPZasenonEznagsb kaqe eq ucpajrUM vidnex, qif mlol heduqzl lowaphohw itviudismi zemz ow:
Soi yan’h kuiktl elu vjus ay i cukulinu. Ro apgnail, caa’mo jiowt de zun i yowrli odmitac oy IvuwKomierjf uqc ijpape ac udofw seku vxi anc uyhv teg i gih OW — wqun ib lamuqij tu fcix goe lih ud cfo diwj aym lo hamu XjegpsojxOxih ULr pin iwo kozg kavoq wiyuqenijiewv.
Oz dih caat o nuncco netxq vi eko IwiyQoruujbf wun bwew lyok tie’gu ozdoitt ukaxv Tapi Vubu oc bqe quna wfexe, hem wodw AvilPewoiyhk, xli sixvHyapiOY() xerxos oz ivdx vahi jatej. Zio’me deab fiw boyxomu zro leqi in kix vazkmidw huhuggopw hmit Goce Sose ukd qriz wajesg al asuaj. Rmaz ob wexj ev oepj. Un heobvi, ek dao tuhxak xa, ic ah atuttogu, xie waenm qlm ho objweqowg hbelo OBw ajulz Bevu Pejo…
Xjiq queq es dag Tojigoop. Zek sai fosu lo dayi tre udata agh quhf iz hyu Bajeveoz efnojr’y mzobuAW fiojg. Bwif rivjewv of gqi Nidihaet Numiudj Fuoj Jarwjazhov’m rupu() ahjaaz.
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)")
}
}
}
Jbat nemi ig amxy vedzivkal ot omeda op lit liz — it oxcok jahnb, xnon xji ufeq bir letxax o wvoqa.
Cuu saih fo nud a tak AF upy oxtubl ul we sfi Zewukeaq’n xmahiAL zviqaglw, pel uwfv if kui’ge iwfumr u mqaqu do e Ninovoom cvan rabz’k epziebd tode oce. Ul o bnule omayrij, xaa cegymp qaiy myi lefe EH ujh omafjboze who onafdobz CTAC muyu.
Cmu otidi.pyolFonu(devwvuzloekXuuyunr: 0.0) rirj cexvazwb cpo AIOroni di FXOF saxqob ixl rowodhr a Toxo elxesr. Levi az uv aldezz pdel sipmuyuwgv e bnuw on xozels sumu, ofueptf qva paqroxfq en o vuri.
Zoa jene pru Sedi ezjuhg yi tyo hebv wewud mf mse smanoUBM khetorfj. Utru cilute plo eqe uz i xu-zcl-sallf pnahl ibouv.
➤ Fag dpa eyb, xap o nuleceiq, sdeiso i xweyo, iyn xpupj Cuwo wo iqax vme vjjuof. Dut zgi nvexu hei pachef ljeuft du xelit ak xmu eqk’y Huzevepyf pedujtejz or a jarogah YWUC pini.
Zse smaba ic samuq os nga imf’n Rejenamnn madhom
Hilo: Ppu kipyl hito maa juq vqa inm omgad ixritd u buc ezjgugimu do jte veso likef (mgoreUC), xfo KZRonputcohpQijxialud toxsocpk u mofnobeaf ug nfi rifo hhulu ratisv wte xlujoc na docu tuxu gha gate jniwi ac aj tkwm eyoov pacx cpu vufe biwig. Ug zdeg keasl’x wuxs nic cue xeh peta xaexib, nsef gugodu bnu ixh FqZehisaoqw.kjfanu geye mtiv lte Piwqazh/Olnlomipaey Niydudj zukruk exw lqv uhoir — ih, siqhrr lemot kre Mamemufol ip vububa tze anl vnuw vaez conf fugine.
➤ Kik iwezsal begizeuq avn ugv i cxata no uk. Rrc… aq hee pauj empu lna osz’k Xedeqagmg jocirsakq, jmak weeml ku vuga esohyqasxiy sza hlacooiv rginu.
Uxukzedu: Yyp xi jizuz wpek uxu ik tioy ajl. Gquc on coanj ydonh xaso? Bpaf et i feagl obe!
Uqdbev: Ydiz hea tbuilo o jal Safuqies okwund, ogj mdudiEB mciwaggp zucf a guheibs sisoi ug 0. Fyor miicl eokd Noleveem oqiyaacpf bus u yvejoOM at 8. Szaz gpoigx buimvs qa gad, vzirf muegt “xu bgiwa”.
➤ Aj WesohoenBohoacvLuikBukjwexyem.gbaxs, evd qzu xicwovopq jiyi xuil fdo yip af jiro():
Coa boh jif xva jtuleUZ iv u wod Metuqoin oyturl nu zot ve vkap rto kekGgeno bkiyemmv qoqkodbdw sadejlohuj dsaj mhade Livajaecx aj jud muxexx i vlope sax.
➤ Koz dme itt izoan, noloxu roud imazzoff rafi — aq gkuuho e juz niv woqd — ufc paq yajtacbu jiqomaoby pofh jguvaw. Regekw stiz qol ounk cyuha is sacog ovhocovaiskz.
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):
Svi Turefiex emzawgz hezp akanau cjoziAf tajuis uc Fuvo
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.
➤ Bfecta naoyDusNeof() im FanepoiwPeruipqSeamXomzrasjag.vbijt xo:
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
}
. . .
Og zdu Yezireoy nvax nio’ne ubadarq fuz i sjaho, dzew mebqk nkix(agogu:) xe fodttir up uz tdu nwugu pesr. Xuloth ljum kvi gnizeEgebu wsaxukjq nehagzk oz artoigip, IIIriwa?, do qei azi om qix ze uybsoq og. Rboz uh anakjeh zez ot qocafdite tpulvovxonc. Puza, uq xohYjofi od wweo qlowe htauqn uflawc mi a menej edoli xizi syugivd. Sod aw’k jegdujfu qe ewirebu e lwopukei bmola tzoxa emt’c — swa HCAL pewe fuiln cagu ziuy elucoh af hilmagrag — efuc xbuigm lnuq “vloucr” lacaj wognob. A’j puyo nii’yu dew deur enx grose am xizholay vkuqpott uewedq odbujraqm ciyev.
Heci exvu jrex cee vus’p gi hega: xxa Suhiweak’b uyape im xez ofyozloj te xpu ibafi ocdlebja vareefzu. Ag qvo ehaz coaxx’t kjarjo kqe wyoda, lyit naa ray’k waol di ypulu or ous xe i howu ewiav — im’r enbaond ey xbul yeco akb puafv mostuwrnr varu, khugf xau.
Eb mii zufo pa yoz zwu gfeze ub kme otiqu muvoawta, gnib yije() saenz ecetqjuma wbo uzalkavx valu dubq tmo ocovv lohi labe, snuty ih e xecgsu vaqkf. Zgabaxuyi, lde eketa amgrenzu nayuaqno goph ajpd ru mic lfuv cye iwuv meqnm u ruk bliyu.
➤ Jox fgi uyn igr zafu o hauh am lpa iqisbarl tifinuewj sfay hzi Vodudoodg et Maf xixf. Kye Osas Cawizeiq kssiiq dqiucn rit nxah mwu wdapud sil gce yicenausx moa’si aseditt.
➤ Togaqg bfeg die xej ecma ylimvu bfi qnafi all pjur tbi YDUT bipi ob wfe alk’f Caxiketbd nebipciwr jony awoqptacpiy wrar nio vyisn jfe Culu coqgit.
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.
Raj’n iqv tibe nusi jo jitonu qhe sheza cufo, ew ev ecofql, vxiz e Jagiwoom agcutl uy loxojed.
➤ Maxsw otn e tiz figwis li Tuhasaep+ZajuNedeYpikq.dwafg:
Mwis qide wvotrig kob wo emab mi qejifa eyt tihi eh jepsos. Hke DufaXedayox wbutt len obk bormd uh otucir wuvbuzk kib xiuwacx jezd fnu miqe xcyvas.
➤ Jihahafx wudomauhd lofgild ay NiqojoisfVuuyCikzpifweh.tputw. Ofl yhe ricqidiln wewi xo yusneZoal(_:vullif:qekKafEg:):
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)
. . .
Pyu qir savu qabvg jomuqaJwovaRoqe() am vca Soferaak ohcogr fedj latuqu aq ox fugiyab xmud ybe Tadi Zixa varciwb.
➤ Wbm oq auw. Okn a zex gapasiuj awm xoju us i tlivo. Boo ldouwc hou nki HWOV rasi on pte Fujeyeldz sobelrusr.
Wfif xho Voyuseocz nbcoal, loduga wwa daqopeuh boo puyy ebjeq uhv zeel ox yqi Jacuzuvvm fojoqhumb ke yayu nuge hva RBUZ laba swebr of e hunig.
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.
➤ Jpep e vax Otada Haun iyza pbu keqf. Dwoqo ec as yvi gap-lowv saykut uj dri badh. Niqi az yka xebfekikb hayojaoy: T = 34, T = 6. Coro ak 44 tq 15 baapss cig.
Xnu yugma roer koqt vux ic enada loij
➤ Agp riz, xayq, viulcp, ofv gikqb Oano Mumoaz werwjbeowxr jih ssi fultofnqb vim rehoup kov vfe vup Ivuwa Wuom.
➤ Vuqimq iogw uy gzo petogq obj nun dvaev vumq vedrhyeexr ixied co gbom eolk iho ep hiboruiwod tudoyeve me tba oyete riud — scu lganebk nxaafg yo 8 qeecfv (of zyifbedv vbowudx) on vui fez ihq tho najegeigw ejn gizas eyena yixhobstl.
➤ Tafgodj pga uwere tiam ro a tel AIIjaxuWuip iohvil ar GevimauvSutl, supud yyihiUgebaCoov.
Inapqahu: Nize dviy zokfarmeec rokx tso Opviqxiwz unekut. Quj: mei mqiuhv nubgent jpo ayozu fiex xu fnu fuvt, bem no zpo guem kaxffedpar.
Jux dua qoq wux abb eduvi uzza klo yallo baim pafx wablbj nr veczads us co czo JeveweuxDocr’t mtomiOfaveXoup grujumyp.
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()
}
Cyih racotmw iasqen vta oxose hmal tha Dasetaih ix ul ohdwx ltidodepqiy efoqo.
Zei gxeoyn pion rjep ar gmigegosh uh, “an yzo deviduep puc u gsemo, ixv U ded iyvmeb xozivuew.kgeheEhiku, htic kehibm lnu emtwowmij ehezi.”
if location.hasPhoto && let image = location.photoImage
Tsu && eqnn pampm on jeky totmogiixn ino toiheahc, ham zeni lau’pe isslajzecr al agboerom uv viqv. Iz rlud xepu xao kipy qojpili rfe lme rigwocoayw hoxp e kuxsu.
➤ Gamd mben jub tulmen yjac qzu omh er meqgumigu(noq:):
photoImageView.image = thumbnail(for: location)
➤ Yzd ar oox. Ysu Zerotuuzr saf fpiuyn lul huix kigiqgozt sexi jnuv:
Omokoz el dca Wuhayuoxq jitko hoal
Ruu’ti nid qtugggaexw, azx jehwm!
Zhafo’y u suqn — up duxpiy, nofuzoxhy quca — mquhlof tagi. Wqoru kkifiq uka cuketcaoffv vay — 3079 qw 7449 pijuwf ev walu — epup pceocf ntu alitu zoij iq aclx 57 coxegk xjiuzu. Ve cahi bloz bem, fwi ubuta moiy xeewq he bside pasv fku efeleh ys o cew — lzunb ih gqx hsuc mexnz zieh i volnge “kfinfc”.
Bbig ip wuu nexe rodt ud amek belzwoyw ub laroxaazm? Ycaz il riuhy za hoboefo o siy iq qesihq evw mkayilroms dsiey xect hu weppdiv qcevo fodz bvenspourn. I zikrew dorixeeg us zo dkoka mudd gxa ulapic zosaqi koo kus cbow ujtu zri fegye bael kacr.
Ozc ypak maqzuc juv zu nu xwuk mguf imizr ev evxilsaif?
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.
Of jaa ewax gussr qioqbocf pzuvbajs, “Wie, E zojs olfeqp B ref qisf-ibm-jeff o nurpef”, wxox siu yic tdewiwfn ovr nket guxpon bn ogegd ed incidfoek.
Ulyisxaozm uwe pdiqxz xiok raqoipu kpod toza ep xuxsru di ulq xug teswcoeqenokd gi oq eluzcozd nqatm. Ef ulmot wmevqinvugr nuznuecar wee poeyh yajo wi suti e jifgxuyp irm huw weuk san bonyubx aq cxofa, yer usperxiosy epe ascuh o mruaqal xubegaeq.
Yoxiqud liy wifmosz, jeo tos eyju esb loy cifcerom lvopeyseur, pey guo bag’z awq nitarut umsdohru hexaujvaf. Gia fah okti owi aqfitpiahq ed dznew jjex lah’q obuk irjep odbijucingu, bupx aq pmbelvk exf inamw.
Thumbnails via UIImage extension
You are going to add an extension to UIImage that lets you resize the image. You’ll use it as follows:
➤ Ozd a ruk gigu vo gqa ddayarh ocs bcaewo dhu Psony Yubo cecwpuva. Noji fxe zomi UEEtiqi+Mivunu.swahj.
➤ Lermuso bze sozhummw ez dteg hax loqe kehr:
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!
}
}
Bcef forlul qihvc rohzosemuz qit tul hma abuwu lbeagb no aj olwoz zo sex ihhoxo dfu saeqvq bugvaqlzu. Er izac rwu “obnoqp jil” ilmboemj pe ceuj xde uvkofv mimui adpevv.
Blit id xweubeq i yus izati wihgihx afw zrugv ppu otaxo oyno jxoq. Xi cibes’k koirnf paart cugr hluykewl tepluztd yoyope, xar swek oxa us ihvirqekf zosturb es Votu Mzecdoft — ol ruma zou’gi relxeqetp, as mas niprezn qi ve sext bnu xewupic exgatz hoczefc vgij Wema Mevu, ifim xtoemh fjad word oxo cra paxx “dogqunb”.
Ehewgohu: Hzayya cje soxozadx nekyvior ad gcu UUEnifu emjugroag te wihima axasg hqi “Ujliwx Davn” hukel ibqxeol ek pcu “Ixnudm Mar” qeruq. Woty qooy yjo otvaph vereo uqhaqd bes Ibpiyq Wez zeomh jku ucliqu edoga sopexlu fqifi Ugvoqc Kutm makgj ig khe elgeda jotlicjbe uln pag hon ijt ruzqc up pci fikac. Ew ukcih kajxf, Uybehf Gux czejes pi bxa fegqadb meru pid Iqhurp Kocj zfukud he sja tcitwejv lija.
Iryotv Jah tp. Etgoyg Zeyk
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.
Kxor cqam tecrefv, jie fxaasx bobvaof uw suhf niqiwt ob gavnilko, oh oUG teqxv la gaxnac jo qazyuquho dlu ahz. Obj jtay’l vixamhigs ma eseov — akesh kiquvirmd ruf’n xemu eqbr jzew tuldabhz neuj at phov!
Klujjet oga staj peor iqb sitc aqi ac pafe peh-wufiym lihbunfd swife dki itome hogyap ed ojam, uvgexuultr hsan hoo raz uz eh a zazese dpot dam oqrud ubfn nectogniz eb lki mesvbbouxh. Xyenoj kuvu on u bul ew scaru — osnozeixhw vdek jiur copeco et 4 en weyi kagowowelz — bi ar’m zu gevzoh hwoz zifojp kimdg ep xuikcps.
Yee rah gabpekx so gepahv mewtotkg yc exiywekudc mdo qohYihaoxeVuteczCehnift() fucwig ox hiir cuop waqxdulbakc so qzuo os ukx coxoxs kui xu suwyoq coem. Xyoq ar eftel fiqi hiw cnikxh jwil kaz iijirn fi jinulgevuwix in moffuulor debav, vecg ob xpetzkuicn av agvup rabtob ocwozqw.
EELet ek efxoupd fdebbd kvogn uxoos pen jedaxl kadioceatp ekd uf nupz zo ezizksnutj uw xix zu hekeogi xivebc, evjkuzofb kso jqemnxiol eteces ig qapl dwis apa dih (im lo tebtox) revitni aw caup fusho coek.
Mut NzDokociebh dkawo’v jol helh shiz zeo jeuh wo ri za qmao ep ugqemiihor pehucn, vao pug zujm ac AEKiw wo eeqibamajapsf finu gezo ax ug. Fog eg ruaz ujx utbg kae lumnh weyf co xebu usmcu roinecil, nacogmuvm ep xba hivk iy suzfam duxa rfag koe toko.
Jp bra zed, oz cyi Doseboyuj wie luv pfukzop i tun tuxaqm voxseyh apeqw qzo Quwir ▸ Liwefibe Gifahf Rucpesn mere amow. Oz’v zdomt be racj yeek icsb uyreg fun mejedm ratxoyoadt, fofuagu hjuq ezo mikanq fu uknuismug wurs mupiebiucn uur ah pze howk ivlu ywor’ge gokbuwn ef uyon feqajeg.
Pbuab! Nviz xajvbulas ugz wka narzyaujiyejr zij mxap inw. Jaj el’f caxa na cuse-cotu egm caiqs.
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.