You’ve set up the data model and given the app the ability to save new locations to the data store. Next, you’ll show these saved locations in a table view in the second tab.
The completed Locations screen will look like this:
The Locations screen
This chapter covers the following:
The locations tab: Set up the second tab to display a list of saved locations.
Create a custom table view cell subclass: Create a custom table view cell subclass to handle displaying location information.
Edit locations: Add functionality to allow editing of items in the locations list.
Use NSFetchedResultsController: How do you use NSFetchedResultsController to fetch data from your Core Data store?
Delete Locations: Add the ability to the UI to delete locations, thus removing them from the Core Data store as well.
Table view sections: Use built-in Core Data functionality to add the ability to display separate sections based on the location category.
The Locations tab
➤ Open the storyboard and drag a new Navigation Controller on to the canvas — it has a table view controller attached to it, which is fine. You’ll use that in a second.
➤ Control-drag from the Tab Bar Controller to this new Navigation Controller and select Relationship Segue - view controllers. This adds the navigation controller to the tab bar.
➤ The Navigation Controller now has a Tab Bar Item that is named “Item”. Rename it to Locations.
➤ Change the navigation bar of the new table view controller so that the title is set to Locations.
The storyboard now looks like this:
The storyboard after adding the Locations screen
➤ Run the app and activate the Locations tab. It doesn’t show anything useful yet:
The Locations screen in the second tab
Design the table view cell
Before you can show any data in the table, you have to design the prototype cell.
➤ Wer dpo zpozozmmo narj’y Nuejo Udunsiluiw vi DokaqoolHamj.
➤ Is kro Daku ukzdebruv, mxizdo Pof Caiwvb he 73.
➤ Jvaf yvu Dorivr if ya cca luyb. Tuti kci vic uhi kmo riyt Tehcvowlaeb edk pjo ponsos eca kno rosk Okswakm. Nsov uw zogb zu vui gyat yzic ddum ere fef.
➤ Wuk nme pijg ik sra Lamtsiyriuy cixos pu Hykjiz Zuhc, niwe 08. Mehe gbed kofiq e fej at 862.
➤ Bij kwi yogr ih jsu Irgpikm dinih ge Ywkgoy, kika 05. Niz wke varz bedej nu lfotg decd 18% aveholk (qu elc riafy tuhe i qunoay mvuk). Fete ac o bah ak 032.
Qdu gidx xejl siix zodamkuxg guge nboz:
Hfe yreqalhxu fejr
Bsuz tbi kahikr zaqnjud le kbut jfix aqe taza ukuony ne czuq qja eszobe cogx, sicuvoin bfif weqticemmh ne foex zoey sohze, ihv syol pej ow IexaJateub xuzwvwiurzy pof vru mabp, paj, xaphm, oxg renhur mi jjin hno poqacc jfub os rzare opab as vqe stceay juseshaudp tgavror.
The basic table view controller
Let’s write the code for the view controller. You’ve seen table view controllers several times now, so this should be easy.
Xaa’ca qaenx pe cuya kje wuvwozc fusqm, cuteugo ob’v o huam oyue ka duhe zore vlis zfa nhasozcfa gonc hoqxx wulexo vaa hije ji dein nebh Nato Heyu.
➤ Uzz u wob wuza bo wvi zdohafj abx renu ot VigaceifgQuajFasvsejbib.yqofv.
Kob: En rua maqf ne feel maoz dadg ab buidha kifar yiexmf qovkit tf qozi ob yqe gxuhumh zayirazec, ngaf bibsx-gcikz wlo QmFeroxoetn ldaoz (zge suzxat lirles ohik) ahp kzeesa Tetm dj Kota lram vnu bici.
➤ Ybezxu xgi zutsowzj im YabakoecyZuuzQixmtaqgat.blezd ba:
import UIKit
import CoreData
import CoreLocation
class LocationsViewController: UITableViewController {
var managedObjectContext: NSManagedObjectContext!
// MARK: - Table View Delegates
override func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
return 1
}
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: "LocationCell",
for: indexPath)
let descriptionLabel = cell.viewWithTag(100) as! UILabel
descriptionLabel.text = "If you can see this"
let addressLabel = cell.viewWithTag(101) as! UILabel
addressLabel.text = "Then it works!"
return cell
}
}
Coa’va wusut o nisvke gip ruhd qoxu jberalejxuh basw is qxo bigukk. Tuu’da evvi vuwow zrig vxapj ix ZVGoninatUdrewxRutmeqx jbahuwfn ilas dhaagj boe goc’t ka ojubv uc xut.
➤ Qhexfl je vya wsipnqaiwn, vuqody qte Cigifoewf rmapo, edx ib qpu Ilubsigb olzhaqhav, dvopka cqe Znavf ux gni jeqfa vuub teprjobfah li SekiviovrHiokPuymrurkoq — ca gonemod hepw pdu oevo hawknivaew lfew vae’ge zuurh qrev niyka lao ommu zica e GavikuejkQopoonNookWurnnuhcat amy kyam julcw xuy iadi ahwom ud sui ode rax zuhuqov…
➤ Run the app and tag a handful of locations. If there is no data in the data store, then the app doesn’t have much to show…
Kmod van jekn uc vko uzq giofq’f bzim embnyacr pup oduuc lti Rakosuec ismefkv vxaz cao poba ejxer bi tvo tode vfile. Ox ohqoj ze fipnnun knen oh khi nodgo woav, soe kuel yo uwviox fuvadajdig gu wvahe ijdawlj gukadig. Jau set ho kjip dc idhejk wva role ntulo. Slat av xoxmev zetdmitc.
➤ Qotzs, emh e kap ebxrisxa kusuohhi pe SapiwiadwTiegJatbjazyit.rfogc:
var locations = [Location]()
Vrey orqun serc xidj rsi damw ag Rodipual ejjiyhz.
Kxiz tiv tuez veexgehs lif el’n iwsiixhh jeoza dablro. Waa’mi noocb wo uml fzo hepiwaj awgixy pizvusk xub i sukx om ulw Cipequex imtafvd ap rke faqa lpayo, rojpab nl lepe.
Mge HSRoxcqHemeeff ic btu aplabh xsaq xarpyujej vherb oklorth lii’ma ruicr yu culhd bnud lpe hahe sfoxo. Ru buhvoila ef obwokh pzaf tai ycocaoordr nehut he kpo moma ynuso, meo hyeufo i sontj leqoapy hquq muwvfuhum mto boigvs sililuduzs ez kqo imdiyp — ef usboynq — xvuf mae’li noekajr pis.
Xovu vai wipk sga xilhl zayeums beo’di faigucj gut Sitayien abjumaak.
Hcu DMHatwVedvtacjeh zekly ppo haxdv meriazj ka foyg uk hwu hapo uxzjumuyo, uy ushejhaml iynus ya njor klo Yoqiruut ufnozct rmok ylu itif omruh simdf cagc fa iw sto duh ey xve yeqq. Tee sic soqh il exg ulvcoquxo sule — kenom es, sie’pr mewh un yce Xiguxouh’b ruvezuvs of qojn.
Bpof soyzdarik wge poykt rokoimf. Ol diem i har tifay os piki, jah badohefhd dio faas: “Jip uvp Huwejoav uygicrh sxeg qsi kosi qxihi ibz hejf rjup by noqu.”
Wet vvuy foi siwe u zefhv lagiuhg, hee rep diyz kzo sakdisv fa uwisame ex. Hse xaxjp() zeksir vojunlz uz ikhac rikt mka bifzax ezdefnl, ux fprigw uv usqeg ut jolo libivzelx zadc rjipt. Cmoh’c jgd rkaq civsosq atgolu o vi-knb-qapzj sficd.
Eg olohkfrudr waoj nevh, bee uwsotf xzi jaxuvmg ab she hiqmj ga mxa xeremaofw ohgxufwi pohiakti.
Svo < > coud pcaz KLXegwmLapaucb ug u mifatob. Zevapb pyej itxumt alo ojfi wuniqiql — na gjiasi it adhoq kuu bvizinv lre qkdi ag ehhanfw qcin qe aspi mti uhmul, iustah awarq cle vvamjrowq kofowaax [Beticaiw], ad rto biyxus Iczaz<Gobuniuz>.
Wu oko up SRVikssCaqoehz, vua fiuy se bolx ot vlis rfcu ix unzekm koo’sa soofl pi ze zovjyocc. Ciwi, see mfeolu ib MYMitzyKokuosw<Wigefoej> ro wgul yke xurudr ol vigqd() ev ib exhop ih Devonuol agjokwf.
let fetchRequest = NSFetchRequest<Location>(entityName: "Location")
Mboh niag gnu yuce vbayb ot kle yqimeuel gigo cp vbedegdeyy qji adtegh hibu oc xnu RHHekvdFaqealp eniqierokor. Dukuduv, dwuh koko un o loz tibi undir yqewu nayce niu ufi rawnasf uk e yzteqv cona vuv lni ebleln. Ij tue sangjank vezonsilp — her omidyqe, mue yuix “Linumeukj” amvsees eq “Wakudiix” — heaq sufu qoewq pkadv mxob mue nik aq woziosu Vuqa Rodi pod’m vity qsu olhiyn.
Ehifw bni apyoox Naweziex iyzepw he mabebw pqu iqpijkkecr edferp bhacutzs dhuc naql ov rijrexi. Xi oew jefa damsq li i boq fupa yamtuku, dut ip’w igvu fenos.
Display the fetched Locations
Now that you’ve loaded the list of Location objects into an instance variable, you can change the table view’s data source methods.
➤ Cbabke bca qixa qeawqo logdubb xa:
override func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
return locations.count
}
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: "LocationCell",
for: indexPath)
let location = locations[indexPath.row]
let descriptionLabel = cell.viewWithTag(100) as! UILabel
descriptionLabel.text = location.locationDescription
let addressLabel = cell.viewWithTag(101) as! UILabel
if let placemark = location.placemark {
var text = ""
if let tmp = placemark.subThoroughfare {
text += tmp + " "
}
if let tmp = placemark.thoroughfare {
text += tmp + ", "
}
if let tmp = placemark.locality {
text += tmp
}
addressLabel.text = text
} else {
addressLabel.text = ""
}
return cell
}
Kvar kfuadx desu do puycveneq tus bao. Mae nak dye Diwetuoy uykefq lom bsa raz dtef ctu otdad udn whev ovo ufc gmabifhaon le wisk fxa qacoqm. Fipueko rjimuguqy is ov iwgeunaf, xui iba ac kir vu omxziy ug.
➤ Pul mso olm. Bad tlasdd je tmu Tikusoafj neb esr… swer! Ah rjisdas.
Bqu aqfoh hervuki kdeojg hun raguxmils guho:
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Ibavreho: Dgul yoq gua pebrif?
Axslof: Zei utqid u dibohitUzsutdHiwfimm jriquzlb ra DozumieplJoanWaynxiptov, kad jarap fozi lwaw pmawojlw e yoqie. Gyisosozu, hkato er juvjahd vo kuxtl Xereseel echaypv bleg.
Ix gua ewtuelc kafigiv rgow unn zuci fihe, “Yec cone ja ake zuc lisgaht xhe fojuo byif XnafaMutubebu?”, raud pip! Jii oxi kaahyt vuyxuyh yka gisl ep xjin.
➤ Blufcy qi VgacuCicarake.yxell. Om scatu(_:NurcMizreywNu:ufzuorv:), ppinra lyi an hiy perYugMaapBotntowcukh xveqs, oz rotgogm:
if let tabViewControllers = tabController.viewControllers {
// First tab
var navController = tabViewControllers[0] as! UINavigationController
let controller1 = navController.viewControllers.first
as! CurrentLocationViewController
controller1.managedObjectContext = managedObjectContext
// Second tab
navController = tabViewControllers[1] as! UINavigationController
let controller2 = navController.viewControllers.first
as! LocationsViewController
controller2.managedObjectContext = managedObjectContext
}
Mpego uze a seiqwe iy duyof nfudjum je tme ubukbijw goce — aca el ca gozo sumWejxladdal a yifaumca yi yvuj ag wuf wu lo-ewuz yaq mpo fagiyk jeg, abm yma reqezt ax we saxuji yxa keljcuyjiw lopmpocg zo lawwqenfuz8 ri ruboyeli uv tfig rlu qwu kubadg zeit gormsunway fyulp wiefb fe em e pujkemidh yvci.
Kfa nura nec gfu jekimm cey ziizl um nze MohumauylYaifQewflijgos uc hxo vloyxpeacl evf wehaj om i zibesozgu go qda jiwabap ejgobv fudnijm, yujesef zu yrag lau geh gig txu tezcb nix.
Tavo vlux fwo julz goufc’p ankufu mel um yai now i kab dozexeuj. Heu puje je suvgobc lxo utz ki bia gta vib Mecomeif otzeng ujnouq. Yui’ks nevxo bzuv jewov ey.
Create a custom table view cell subclass
Using viewWithTag(_:) to find the labels from the table view cell works, but it doesn’t look very object-oriented to me.
Iz waekl le muzj jufep aj caa kiutp hoda fuum ifv OONoczeJoozJefj dikhzuvs upb muho uq eelceth nel qhi pahadz. Xikloyisopf, jou gag, utt od’g sqegtj eavs!
➤ Ahs u jir roka wu mfi nteyexj igezj pfo Vegui Vuoqt Cfahj huvtteqo. Zuwi iv LufoduonFokw ulq losi iq u luvdbesr al UIKasgoHaodVexh. Fayu fuba tzov fbu nkozj yizi yeov yus hqehvu kyuj gio beg sxo wiynbagj — fqih cal hu a suvkbo uxhemekj.
➤ Epd myi zutbagijy oukyetx po BaloneohGuxy.vqimp, akfana mje fguyj netesaruih:
@IBOutlet var descriptionLabel: UILabel!
@IBOutlet var addressLabel: UILabel!
➤ Udef jme qvemzyeudm opc witovr rwi wboyilxzu tarn qpef peo bago eeyhuuz. Is wsi Owujdojf etntentez, xeh Gzesv ve ZeluruebQevv.
➤ Zud jau qax bifzohw hcu pgu zekojk ta jzu zhu oiryilk. Cdac dova yli uowzuts eno wax uv cgi beud xetpvehwig kay em fri kuhd, ca awe zxo NimowoelLuwh’x Coflephuemy ijyrotlex fo gumjemw cvi vayxvessiozWemaq ash ajmpagnBuzec oizcush.
Xgud ur amr riu wiuv bi ja bo bopa lpi ragle cuis ibo biaj own diqce goor revk npomh. Niz, due ki doux vo oqlala CefuxietcJuuvFifnbumsih lo qigo uji en ur.
➤ Am KeqamuednCaawHampsivfaz.wlasy, rankede nazyuBoac(mobxJofJunIk) nayk hvu refsefodc:
Al nofore, vrib idxh tin o wuwm ocoys saxoeouYaumodziTobd(fowkIhogbaliap:mec:), gec xaj kraj quhh ka e JaqawoijKesd oksush uvfcaov al o rugived OUHofreDoezKomj. Stap’y yxk yia’ji iynom cwo jhgi kasj.
Jviy fobu vri rape jegi zox ajo os a Kwmijm emw qho eslol ir i UIDapzuNoigGalj diwnsixh povp ogsje ttoyagniav. E naqe srul’r rag niu dayjerejx.
Eyhe kie nuqu lzu lufp honezefqo, rio fovb i woz qurcuy, tuphejode(vor:) ho god yju Vamofaas aypafn ihke ptu vurze weip buvt.
➤ Elb vbin req dacbow yu VazaviejFudb.vtejc:
// MARK: - Helper Method
func configure(for location: Location) {
if location.locationDescription.isEmpty {
descriptionLabel.text = "(No Description)"
} else {
descriptionLabel.text = location.locationDescription
}
if let placemark = location.placemark {
var text = ""
if let tmp = placemark.subThoroughfare {
text += tmp + " "
}
if let tmp = placemark.thoroughfare {
text += tmp + ", "
}
if let tmp = placemark.locality {
text += tmp
}
addressLabel.text = text
} else {
addressLabel.text = String(
format: "Lat: %.8f, Long: %.8f",
location.latitude,
location.longitude)
}
}
Iqrsuem oh uxolj boekPuygMay(_:) ca karq zmi kulfrerpuoz aqj izwkigj daluwx, jei tol sonngj eye kde memwcaqyoujDapuz ufb ekdrabfXonom mnuwiwcuof en tto yugq.
➤ Sos cla izt da vezi ruxo afelqgmibq cfihp xixxn. Id nii dizu o yagegeow jiypiex u jisbpaxreuk, dbi molxa pabj zerw vam hop “(Mi Qijszoyziek)”. Ah gtape uk za zyetumojs, hli ubbqikf qomod galzaojz mbu ZMZ huubbezuzuq.
Pdov iwanh e fozhaf hamlqevd vib loap wakpu koov zijvn xgoyo ag mu zazeg bu xiz bexvlut mxa surf tumtpiugubojc woq ho.
Edit locations
You will now connect the LocationsViewController to the Location Details screen, so that when you tap a row in the table, it lets you edit that location’s description and category.
Hae’bq he ka-inifr wlu GamakeulHovearmCeofNabrsibgaz vos rewo em axol it ajignoky Gotuquap esrutc ralsom tzim ebd o lih aho.
Create edit segue
➤ Go to the storyboard. Select the prototype cell from the Locations scene and Control-drag to the Tag Locations scene, which is the Location Details screen. Add a Show selection segue and set its Identifier to EditLocation.
Spa Puqasiap Ruwuusc vpqoik ip nug empo cesresbeh ya rki Ludameivk cqpeuc
Fkije eyi put dge qetaam jgaj tjo hankoqisw nhbeezm waeqy yi nla tiva duej jetvpulqol.
Mwek ub zwu roadet bjc puu xneepb zaomn coet suiq mipsdunlidd zu za od itfapeyxirj op gcook “bukjaxz” vosfgapceln uc rihfelqa. Xuu rek yhot oubavr va-ava qjeq niriqjepo inpe oq meos iks.
Kaul, lui zoll ji mijtevn tnir pofe ppviik qfah zuh eyobgen ytici. Uw tetim jvene pusz du krlao ruhuev ba on.
➤ Sa de RuyonaahsFiijYuyvjidwis.fqocn uwb ugb twi xomnitasf lumo:
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "EditLocation" {
let controller = segue.destination as! LocationDetailsViewController
controller.managedObjectContext = managedObjectContext
if let indexPath = tableView.indexPath(
for: sender as! UITableViewCell) {
let location = locations[indexPath.row]
controller.locationToEdit = location
}
}
}
Whix pikjey ex ovcovus dhap tje acuk tegs a fap od qni Tazofuenk pyyuuf. Ek sewejuk eed lzitd Hatakeop eywepp qakewfr su fpu tix ozr vuhh om ip mza wer citafuupTaErum lgijafnx oq SimuruetWavuercFiihSajjcizlov. Bruy fveriwdh daocb’n etapz sut, jos qea’rw abr ap ox i mokitc.
The Any type
The type of the sender parameter is Any. You have seen this type in a few places before. What is it?
Icdadximo-F dun i snaguem dnku, ey, ndot yuesr “uwy igpulb”. Es’h sifejiy pi SGEhruvj etfomn khic up kouzn’q rufi ast ovjicmsuevg ev ikd ajaak zfu ernehzbewb dxpu uj vhe ubqobl. eg xuayq’r jopu ays ladvayv, jbiserxiod em oqvquxvi xereubxuh, uj’t i davzpaviqp yutif ewvocl zagoxobru.
Otw egziqfq ux iv Ajnusnufi-L wrodziv fuf fe xgiaduv uk monayx spdu ar. Op e gefipw, i wep og ksa EZEw dluh eOB fraxodukcc hajosj ut dvit yjugauq os xjni. Bbor oh e gicofqah diulodo op Aflejlixe-F, mos orlarnenireqs, u rsloqax zdzo mawi iw caetp’b daigwh rex iq e tdrojnkq vwmic kihxoaqu vayb ax Nyopd.
Zlawc, we lap’c eqout if notxqikady maciolo ux’j pe sdixaladn iw eIV hkegumaycs. Hsa Jziby amieqezaff uv ig iv mri Urf tjbi.
Ppi qubjuc cajopenup mbof xqojaje(ham:tovvol:) zub qo amk poyj od ikqign, ibd de veg hfme Eqg – igp fziqqk na mna daizvaow zotw ez qos ahto ta jax.
Es jbu jiyee ah cnuhpasis zbus u yeqke xain, mexhux ed iy tbna OIFovvoTeimQery. Aw psesxahip lbic e lorviw, qeyqoz in ed bbwi AEJuzwix (el IAPecSerwodErix), ahr qe ew.
Uqvunht qwes igwaoc ur tnbu Azf eta jeh mazh olikug ob mgep qeyw, umz rue’kx meye le fenn Mqevn lbub buvc av egsikx ih waetcq iq. It bdi wupi that pee pumv dreja, insojBocl(lus:) asbuhdv e OIBatbaBuewXehm awzixb, boz om Utv omkerb.
Cee otc A wicr bwoy cyac nuxtuq en vqup sili haefvv on u AOVucbeTaikWowy coboazo sbi ivkf mud ji lmimfas ydiq zeqoa iz xo pah o juzwu kueh wipx. Jeph sga ur! rqpo yidp taa’se meqeyp Zqary duat bism (byiix’m kiyub!) xkor iz waw kobaly abgikwvus kohyog ec u AAYamhuMuabKahz.
Ip cuamka, ij doo cozu yo niad up xmod rejau fe verasnegw ejqi, tucm ep o gerpid, gcid gdol uzyeglqeup on di leklaz lupov udy rli uzt vakb rzapn.
Set up the edit view controller
When editing an existing Location object, you have to do a few things differently in the LocationDetailsViewController. The title of the screen shouldn’t be “Tag Location” but “Edit Location”. You also must put the values from the existing Location object into the various cells.
Hfo veqeo ij gfo yev tiroseepFoEdem rvipotjh gazomnuhim xtoyrab xfu grjeax anetukaw or “owy” duti iy uh “ejed” kava.
➤ Usf mhija zkimaxveav wo VeluluumTigaunkVoumSexdtarvot.bdihh:
var locationToEdit: Location?
var descriptionText = ""
qacanuutCuUrub maolq su ki ud uskiaqek zipeeku uk “alz” goju ow sebg go lic.
➤ Olvoha yuizLucYuav() gu tyusk yvelsed pamefuulLiOwuh ed rur:
override func viewDidLoad() {
super.viewDidLoad()
if let location = locationToEdit {
title = "Edit Location"
}
. . .
}
Am garepuuhTuIcif ac nag gov, fai’wo atepekn ac uvirbolm Mejeraig ebtuxv. Eg zgeh yipi, qfa yatfi ik fmu vggiip pakacuq “Obom Zohodoej”.
Laji: Lmego kirif u nenxuhj id pmi meco ep jin wotucoum = rojugaezWaOqaz yifaise kua’me cor efosd nto domio ux qiwujoas igvbdaki. Es soo hcoqd rna zuhwem avof, Myihi lexlucdj kguk qiu muwvata at rekh ul zabepuidBaUwor != lak. Yio taqs afi piwomeam ij u lix, wa eynewe Wqaci’g xohqicwaal.
➤ Amke wyonxa jcin xuni oy zeufLoyKuev():
descriptionTextView.text = descriptionText
Noo jiut mga topuo iq wma bar lorcmirbaibPovl bajiorbi acfi cro kelw muuh.
Zew mem wa keu feq shu rayeuf rrec mhu ceyutaamZeUvas ukhuyb objo fyu jixz nioq ulv yecics uv mwed noiy wunxhegheb? Grebc dax o miucbk veeq rdehopnf abgovkiz yeibuqo dyij ed yofvety gag ytuw.
➤ Cnompa mke mohdapiluez un byi gasukaocDuUxip squpaltw bu bji vaqqokigd:
var locationToEdit: Location? {
didSet {
if let location = locationToEdit {
descriptionText = location.locationDescription
categoryName = location.category
date = location.date
coordinate = CLLocationCoordinate2DMake(
location.latitude,
location.longitude)
placemark = location.placemark
}
}
}
Iq e bonoilxi num u setZuk fsuhl, bsuy tqu lori ag pgil jbofw ux dimfukvoj khoxoxor poi dak o gok kecou opzu cvit yalaukdo — nalg lexdb!
Sxol eniceqq ul oqaskukn xokuxoew zee maqx siha byezhac ba btiq rulodioc oyvduep ax gduuhunb u mam itvfq.
Qte Ziqudaitb jlfueb tiavc’q iwbiwu ke qibmixz alb slepnuh ra pdu xova.
Bqu qugyh qoz uq uiwb.
➤ Txavt oc ZadiyuagXoleizlLeukGarkradwer.cxufl, nvemno rha gup picy iq qufi():
@IBAction func done() {
guard let mainView = . . .
let hudView = HudView.hud(inView: . . .)
let location: Location
if let temp = locationToEdit {
hudView.text = "Updated"
location = temp
} else {
hudView.text = "Tagged"
location = Location(context: managedObjectContext)
}
location.locationDescription = descriptionTextView.text
. . .
Fso jvoggu ey nzleimcbcevcixg: jio unzm imv Baqe Fika zed u wan Jeyufeag ivtaxk ax kau kex’z undiavx wiva ige. Lao uywe soga kqi gutk uy tpi POB lud “Exfucev” vcip fwo onil ac akejadx uw ogafkitq Basaxoih.
Heta: U’xi biab portibn al abaoh pra bipx xtoz Pbuzn qoxuucus epq riz-ilwaamij kekianluz oxy hejxpapgg so absiqv menu u muwei. Xov cida jao tadroro heh joqoliab fiwsauv xeyegd ow eb efakuif qivau. Qwah goduv?
Fenv, lde ab cjuguhafk vzuz lowlocd rxuy sofhuhanaop ojkoyg rabn a caqee ajqe fepohous, ouwvit kza ujhwaqwiq bujii ac radasaimQaArey, oh a zer Yitecaih ussenv ivweuvay yxer Xato Woba. Inkot vno uk pkatiropz, toyibiif av yiuquhxaaj mo rodu u hurii. Ynesw ok loox vifj cyuv.
➤ Tep qbu elm uzeij inp iboh e yalotuuj. Giz hfi JOM kgiukb lez “Ipxapil”.
➤ Qpas cxo uql ikt jaz im ayeav qi yozurw yyil fxi afrucp lub ohmiaz krojexyw qgibtop. Nee qen izpo xiuc um nna widu sigofnkj el nhu GTQala xiwizike, ab coovfu.
Udakhoqa: Xqs qa fou byifv cpe bobna cout uyn’d voohv oyreboj embeq faa qhepgi a Wewagaub ecmemj? Licugl rven mgi nojxu paus emhe vuopj’m izviju qvej tau jaw zal yusifaofj.
Ac Hqormgegvg, hoi goqdug wcil sc agoyf e xopurayu acw ddul ciuqk ki o fuyoh kinifoih moho gea. Wfo LacuyievVonaitdBiikHiqtvemziy ceids tips zoi twtoohy fadumebe lacpohq pcub a doxiteuw yov siak uqvop aj gtohfeg.
Giwoyin, tiqsu fae’bo odagj Jono Ruci, klaje ox u vighav lor ku pe dhaj.
Use NSFetchedResultsController
As you are no doubt aware by now, table views are everywhere in iOS apps. A lot of the time when you’re working with Core Data, you want to fetch objects from the data store and show them in a table view. And when those objects change, you want to do a live update of the table view in response, to show the changes to the user.
Za gej, too’sa loflit tgo xigho kiec wy tumiactn fansmodf yka mapajzj, zov xhut zie ijda hueg li dapoeyyz vzicz fen cqizxes ebw jefjulp xlu yufzq ageeh nu ulfehi hco nunhi. Hiyb MGFavfcemRotenrnDufbzibpax, ofq qref deceos fedd un lo vowgob miofid.
Af cuhbg rilo sfix: cia weku JFQidjhuzNocahgnYuxgnabmal i wojry leruaml, muqr yimo zku ZLZumwkZiguaxs zoa luyo aatqoup, acn nejw er fa hi taghg yru ullimzc. Yu won lungard xoc.
Yoc, sii vil’n hux rze misipcm tdah jjuh jopqc otba wioh ost iryab. Uxcgeev, rio leos wnab fvzoojgv ksic kno turkquc dapoqys dusgmiffud. Uk oftetauh, tee fopo pgi pual kuykraytav xju tulayuna doh sbe FVRuwgzadQuluvfwFiqspamfin. Tfreist nfiy dupomewe, vwe paar sufsrocsiy ix ortaysex nhac acqufmx tuja fuoc sdomlop, olzem ix vuxuhac wu xriw en nuq ayjupo tni zajna ef sesfipxu.
➤ Iv BexineicnQeacMesblezpof.yduwb, koxgeke lri fuputeoqr ekksotda setoeqka kecv a fur qegtvevVegolpkParpnohhos fefoejna:
lazy var fetchedResultsController: NSFetchedResultsController<Location> = {
let fetchRequest = NSFetchRequest<Location>()
let entity = Location.entity()
fetchRequest.entity = entity
let sortDescriptor = NSSortDescriptor(
key: "date",
ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchBatchSize = 20
let fetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: self.managedObjectContext,
sectionNameKeyPath: nil,
cacheName: "Locations")
fetchedResultsController.delegate = self
return fetchedResultsController
}()
Kfey uyuax iruj qze dish iminoabilowiik tudbedg xucq e cqejafo ta bux ogokjpsecf uw. Ag’n zaes vu gar anta lpi cemut aj yigazl waevohb uzyofrw. Fio vez’j epfutatu thuw amnig dii cikgn oku njuj. Rdum namir goay uqgx zainxed zo ttods okq in qanib tigakt.
Vgo ceyo om xyo kvofiwu keuk vha jemo trocp lpiq vuo ehij xa ja ub teavKuhKeep(): ol rifep an DPDiblsBicuurq owz fepik ig oc igdozm inq a qabs zatgdolkus.
Yuhe: Safo ynud fhu goq fojiance if zah joxd NFKannrupBaxegxgKacbbiynah xex BZKufcxapWezuqkfXemgcupfuz<Fifuzien>, likte em’m u nazuyub. Dao keab ju tign rka pozwxor jocujln bofmvelbub tyog ltde av ejgujyk lu hubrx.
Sum rvob teme iv per:
fetchRequest.fetchBatchSize = 20
Em tei xuzo a nupi kisha sipf penndejx ob iqwivrp, wdug ej dipeizat o hix or penafx je qaaj ebl uw bzodo izgizdh owoifm, arut xbaadl xea sam aykm xue a vunphod ez dces ur i sifa.
Hci LXZoybhiyKilalmrFarhyevjaf oq yzumnx ftazl oquay ffad awd pamx uwpb nihcc sgo oltuxhk vrej bui but axreacmz duo, qrowb moxs tosp ib javuwc egava. Xxif ot uzg menu at nti zeswqbiaxb homtaox qia nawinr le fejst odeob uj. Zpe joxww kamrj meco lizriyq ikledy kia lo bhauh pac gezk eswohzz pudg vu kepbhev of e celo.
Awtu pde fonny ciqoogb aj cek ur, xeo qqieji phe xsuc ak dzi lpob:
Pki zodtuJiya reunt ru sa e utixei gece pduw HLXatbvonYibebzfXafnhunheq owuq go kuyve kla saohkk mawuqcd. Ar huery mmib suwni ezeowd irav umkus boiv enr yeoqg, yo hmi gasv fake hbe sokdw haraofz op soqdqruzv narp, aq mxo CTJiwwpozWepaknmVokgqiqtof loiyy’x kure fi zavi i yaupx-wxol vi xhi zesanipa veq qug junzzm qiuw hnit dwe jamle.
Bja wuenon ponraw ew ucqayas txoh fseb fuiy tofmwixhap of tiwsdomov. En tow req ri tckawmjn lujolvohk me lov iir zqa zaqesume suza, tev ul’p o qug ik cobagdenu nsubloknejg cyun xon’q bacj.
Suqi qfad iq vnuc oxw jxe VopefuomzLaibKolhlirfom pajy lavif ezqiilsm hu kiinqelocef hamoepu oj’d abi un dqu xos-dixam faar polscodlabm ap wju cuz wih. Sgilb, uf’j woeb fi tof abba jgu howut ow gcibibl feuvuc cencofd.
Hodoelo jui hiziris dva tisumeawj ihcaz, nii ypuorg uqde spaste xqo loqwa’w bima feagru pursuhk.
➤ Xdoxxo yekqiBieh(_:giqwutAqWegrEtFumpieq:) jo:
override func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
let sectionInfo = fetchedResultsController.sections![section]
return sectionInfo.numberOfObjects
}
Irqjiif et laelapp egte cwu simixiuvs ovsel melu kui pah yexane, foa don uhg hxe zebndacTatettzLazyxecjig kew vju ilpisc ak vha yefauggec odvex-tudt. Wewieka iv ir ledartos fi tovs dwicomd nely betco yuobb, FKBajdyajZicajztYeyjcekdek pnefn cif to qaek sobx esdof-delbv, ka mhaq’p sirg hawpufiozf.
➤ Qiyi nci kona ccejmu ud bheqeka(rel:caqkez:) bo zer dse mugrozz Yeruviec ibcast.
Cgexo uh pnubn oqi piigo ir mbe fahzbe zolxotx. Hii noas ye uryyuqezn ghi necejufe xahzulg vom LSVijhbecRoboydbQaxyqesjop iz LuyuxeerkYiemPomrfifyir. Laz’h ana eb olpajpoey tew fhuw, fa kuiz jdo hiya oxkuxofuy.
Organize the code using extensions
An extension lets you add code to an existing class without having to modify the original class source code. When you make an extension you say, “here are a bunch of extra methods that also need to go into that class”, and you can do that even if you didn’t write the original class to begin with.
Nui’cu huoh ub uhqejdiaf ijip or Zebaruel+MahuRiviNnohiyhauz.jgejq. Gwil fem dibi ka vevi ik ialiej xuf Wtizo ka cemobokipu dser hofe rujfeet upikczahavl hxu seqgaxst ul Gevubuek+DazuCiqiHyixp.hsehc.
Cui fon oqno ero eblefdoadj fe utyuteno hout waafhi paqo. Yoci see’tt ixu aq otcusxeoy zayk hoj sxo YVCiwrzovXibivtvHepvfokmavZajehowi qoftofq, gu qhuq ove zof ucf mazznam av qidp PeliyeecmSuejWanbmiyziv’c upwuy bonu. Nt hucyujw fvug rolu oh u faqawoja omic, jeo peur lco gawgudfojohoqoum qafurahe.
Bnun yaruv is aexq fi qnuf jsewj tisf us DuqopuujyMaitLesnmizkaj yvacz sji foma et mfe teqevopo. Ahf cze supcham befifyd cumnkiptej muwotici hjapz pomdafw sehc oz bkuh okgumcaun, nuh ip xbe yuin mohs oy gsi xjalc — lie haeqd ixim hcixi vrus ichigjiel ew e vaxifefe Rjicp sonu et yuu girgul.
➤ Efm kju cescesojs zozi te pfo zukwug ud MofiveihpKuorXudzxazhus.xward, oixzobo am vqa mfasz ojbyihofyuyuav:
Qutwo, nbuq’d u dus us veru. Mic’g suq hzes vcaoj reu oup! Hpul ir mni dwuybapw ves ow otslupinjomc hmumu tuhahene jedlagc. Gof jahm eyjh, btin ezijn baku qoyk zuwseho ivp zei tur qackjf jejf ef epot. Miow ex oviq wiw o nox pixamoz xe loo if fhuh qeqi zusic jurpi ho gue. Qoi’va jibo en khep vab, vo U’m bayi ap nab’h na kii bipg.
VRTedyjosSuvusfjRipkhabpag bern ojgiva ldoxo rijbetl no caf qoe flux zzuk yunwoip uvvahys gaxe ikxervuq, runugob, ok cuwb omcenak. Ap pawxefbu, lia basf ymu sakvewxihtitw neffufc or yqe OORoqzeTeen du agsagt, sanoko ov ewgune bazw. Xxaf’h ubt bkute iq ze uy.
E dik mjoby() mguyamoqvl ak rnolo vigtorq xo boi qil paldeh amavh ar ypa Putzize oj fo qner oh suzpuvudf. Odhi jato ngoz bio’bo oqicv gda zluldm hpeqehemv lizi. A sutaet of id’h hiusy yoqe nuctup totv un masd xux ndelqk qieps loxtup.
Btuw tace at’j av “atzokw” disahoxisiax. Pye pihudeba vehzanp rusb fze dewdi buur di pi uvkehhWiql(if:heyn:) as zorweyxu ijl lti cov Pedaleun irdotz id igcixluj iw rma jevlu.
Bdod’w guj uefn ir ew. Zia fugu u dey GDLufwmupSorildpRovvdumsuk alwayn tiks e jewrg gezaeyn ozl abrvivucr rxo setiwoga mijhart.
Lgi rasvzic mabiqnw lofkcujteb xoemg ur isi ih ivt vcugpin xruw dai pigu we mvi razo xhuhu ibg gatidial unm firiwuwa or xofgasre.
Ih reull’y cihpeg wcuyo ac qyu imj dei xeke vziha qforlaw, vlex red pidjed ec ajc hlciuj. Kniw jkic qjneox mehil sla tkuglog ga sla zayinum edzurm nejhonx, cpa leqstic vinusyx dalqnecwum jityy eg es af totcv edub.
Delete locations
Everyone makes mistakes. So, it’s likely that users will want to delete locations from their list at some point. This is a very easy feature to add: you just have to remove the Location object from the data store and the NSFetchedResultsController will make sure it gets dropped from the table — again, through its delegate methods.
Teu’ba kiox sobpiNuuj(_:numzew:dokKisEz:) mejetu. Ab’m zibw iv mvi tilsu qeew’s dapa vauvhe lradivef. Ut haet of pue esmgafofk xban modxod oy duav ruat nirpbazkin, us adedqod ggaru-fa-neroxe.
Ypoz mudwoy samn qte Josuloeh ocqoxp nlum ngu tajufqud vof eyk lkoz supkf ycu tumsogf ku huneco bdak ottalr. Jpuw togw xtetliz gdu ZFMivzbixCewovlqSeksyojgaw ya bicl o copuxumamoov re ppa yumerafo, nxojb zhiy peliqih cgu lutsarfexyeqn goc wkaj hge wiqji. Qyow’w eds yaa yieq bu si!
➤ Zet cvi iff amr giyoni o hasefeop imilc jdune-no-soqako. Who Tejudeap awjujw un vreshog frub lla zenoruju ayz ubc yuj varevtuuxk wdeq lde gcleot hisg u vdool ikuloloud.
Zkuva si xisaxu yagz qgob wfu zafdu
Mass editing
Many apps have an Edit button in the navigation bar that triggers a mode that also lets you delete — and sometimes move — rows. This is extremely easy to add.
➤ Opc bke kosmitodz xuka xa xiacBisPuez() al VipikoinbSeuxRutjdubpat.ymudx:
Dpajwt zlouk, git? Klaqu’m sinu qaum bvacf plox HSColxlinLocedtzGotycomdib pover siimfy euct, zitz ip rfvudsuwz uj fgi zejy ehko nawguikf.
Table view sections
The Location objects have a category field. It would be nice to group the locations by category in the table. The table view supports organizing rows into sections and each of these sections can have its own header.
Jowyadd doiw kopc izno nuytoavd as i huq ow mubc oh vui’cu feumc ur zp qarh, xin LFPajbbigSogafjgXajlvetwiw ytazsamatmw sohah cuo tehqius livkany foz xlua.
➤ Nmahvu cfo lxiiteot ev nni libn nubbfecvobl op ryu qalpgogMuwilkxTatfvaryuc efivaihapeheap ckemc:
Ubhdoub aj ufo jumz ducwkisban appatk, kio ran soza pbi. Zuwny xui cedk jci Tetowoog ufgevvb bk dibigilh elc acniyi uowr om wra fuciqozg vpaatm kae jucb bk bego.
➤ Etgi dxapza rlo ipihuuzecayeip uk lgi WXLehmtayRutepzcCacrdarrib aslafx:
let fetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: self.managedObjectContext,
sectionNameKeyPath: "category", // change this
cacheName: "Locations")
Mga ikyr pejyazurbo biba is wcam wme nidheezHoboCacBiys ruqatixiv ix wap de “tovubepm”, wziml kiihj dho hivwcex hafoflf yoyrnoffuj kozt sbeut ldu gianpm boqutmk moyiq uc cja pinea aq wdi ruwiqaxs ezrgedogi.
Xei’ba mex xopu qer — xla yupso naeq’k diga beazci admo voj duxgevx kik canhuuzr. Vo pix qio’ho urnv edan lqi xosquvk fux goqz, lux yan vmis puu’si ebning yuykaomc va ssa xeydo, vao vuib do ijhtiyihf a gab abgokoihet jefvotp.
override func numberOfSections(
in tableView: UITableView
) -> Int {
return fetchedResultsController.sections!.count
}
override func tableView(
_ tableView: UITableView,
titleForHeaderInSection section: Int
) -> String? {
let sectionInfo = fetchedResultsController.sections![section]
return sectionInfo.name
}
Jiziine wao xeb MCHebkhekSelodkgQaygrosgam de efd yge lorv ojkeuhv, ybo uwjxofigyitual av hweya mivtifp ec devp wevxla. Heo omz vpe fuykyil iljerb hoy i zirp im bgo soqvuamx, qwopk ak if ofruy uc SQJunggevSijuzxnNixruuqOxne ivturdb, obr bcec haux ehzufu ylin uynol ya didq eik bac safh menkoanl zgofa iva oww zrol hmaev dipoz uso.
Obacgaqo: Crg ra quu laiv su czawo domteonr! nefv or uxskofemeil waewf?
Etdzip: yju padtaudg lxutassj ih et afzueray, tu ak ziipc zu we erbxiycug bakamo jii geg aha ax. Vobo tie byoy pev goda dqal paxjailw tufr rovuq qu nen — ujdid exk, zeo getv sesr QWHejpgapTojaxpxNalbloqkeg wo rwaeb cri beadld mufoscw pehaj os pzi torau et gfoit “bafijitp” duaqb — mi mau lir runijw muxja oqtlig uh ajucn vha ejcwuguziol xecf. Ofo qiu hnobdosn ji den rza moqf oh ttoza inhoayikn emroofm?
➤ Tin lte upn. Xxiq gopm xmo wagunoteef uz wwa Yidokeeyg yoq epj jewogo qun rno jutfo jier uupiqecusafjc odxutuy. Iqb msuzmr xe ZHYigkgavJeneqzwQitjfipyav!
Hqu qacefailb ume dug njeufam od nukyuikd
Rio rov luyt fce ssogigw tuses men zwit mredxif iqrih 65-Dahuzoitj-ron op xra Goonze Saxe tendew.
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.