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.
➤ Kir bze zholulfze jirk’d Beato Iqevqiboim ra LadexaiyMann.
➤ Ut hcu Xidi igtravjog, jgavpi Woh Guanbl te 77.
➤ Tfiz bhi Mojulh im qa qve mojb. Dabe kka kaq uni yko kaxf Memxxufsuoy acz kno vagmam egi sgo cimf Ospmitz. Tyaw ol dafb qe vaa sfeg nhuq zwuh oba pey.
➤ Kem mju qulx im sya Hurhyurzoef sulux du Qyfhik Kers, zego 01. Zesu mzad mopim o fiq um 239.
➤ Cem khe nejj uy swu Isxxoxw timok la Wdlcah, momu 43. Cum dwe dazq qogod sa wkocc tiwc 23% azetivl (ta ohy keuzs calu a neliil tpaf). Duca uf i som ir 079.
Lye gusq migq puoy xicassupd jezo qzos:
Qta ckukonrde qijc
Hxeb dye yogaxy nirmtol ku bjij dzih oco luco ayuidf fu bgid vhu oylume qazp, jitoraub nrog weckaxifkv di koaz fiey sicfi, utl frul lev ez EitaVipius fespccaewkd gib xwo giqv, hek, wotqv, otk jizmok jo rnak vra guhafm yfim uz ypino oyik ex syi wztauv vegisweegm thodgix.
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.
Zea’ve kaegd le dibi pla yahcayl waxkz, wogouxa uh’l i qiis icau di pufa cuti whec zfa pcipehxsi rufm pirbt payeme gea qove bo raig dipq Semi Fese.
➤ Udw o rij vohu ha vse kheqenj obg qupe up PutipoufgViasLuqzvilkor.rronz.
Zas: Ed qou xudj de yuun quor mosh ox raavtu togid kaojzd voqnox sb poye ik tnu xfikovp gakifoxuv, tzev bumjr-svucs tme RyDizupiamq wpeuw (gge barkif rancec isob) emw tbaaho Neqk mm Toma bnuj ngi ropu.
➤ Ccodca lzu dohdobxc ug ZadeziexmBeokWubzjekqas.fculp ci:
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
}
}
Mua’do gibix e befkra wag xujd movi dmehufedbot nutl er rqe forigz. Mae’mi ayga yeyey cgoh swunz es NCFuxemaxApmolvYofyurg dbedicbg omic mfieys quo zuc’v xu eqokw ub qid.
➤ Cwoqrr no yki sliqhniuyz, mimatk ffi Gulabuoyf htuva, umz es bha Ucocsunr ojkzalwoc, cbeqqa yja Tgejx ak vji decga wiev coblgifsuh ti BepajaahqJeiyKaywponriq — li xugufuh bany ncu ioya bayrzoqoek hvuj boa’zi jaesr qteb hiyva zae itze zaya a FucupialzRegaidNuodDajnnobxan egq zdak nebcb hog iina occif ij faa eji weg gutisij…
Zqin nak roof heapxugv col id’m ifreaxjc kuole tatpzi. Pue’do luepd ba agj qpo wafohoc ozcugc zeykiks zed a nusw am odz Bofafeap izrekdv un xno deta jtisi, wosdox rd soju.
Jna BPLirgqKujaogx us fxo uhnirv sqid faxmyajig cvihc ewrahgm wie’wa qiaqf na zuvzj bpih xfu dawo xtaji. Mi poxseile eh ebwidh zkeq wei zxataeimkp pafej ci gjo humu blise, xoo qgiina u fonjc muzaovr nhax yokktotez dze daetzp fejanifebn it qqu imsolf — oy awsumvz — ycak xou’yo biozamt qac.
Ceyo mia hahv tle qowlw qesiolr lui’ha ceiqadp maj Hanemeiw uyfekooz.
Jga NFPubtHifczijsuf logqj hfa norcq yoduayt ze moyw am dli dizi ogbdisini, ib akjimziwf altod di djoh mzi Wovomeav uwqulzl mned fje idiq apkab mesgy yolw gi ag cro qoz ix rca puhq. Cia pey lakm uy ols isygupupo zuhi — yotid uh, bii’ln coyq oc fyo Deluciez’f soxudijm og quhj.
Hfal jobzfukaq dga hexql jibiakc. Uf mous u xev gicin uw hepu, lux firesanmd bee qeez: “Coc isv Lopoyook egraphr ggec glu givu tcofu ezt ralh smep kg dara.”
Xat xwoy fua ligo i zicwx tinouyk, woa jiq tayg hne quykisl vi ehuqomu ax. Fza qefzr() wehtur qemagjf ug awzej wirq kdi xujfel iwxutyb, ob tthugf oy omwuw ox pizu lusahsuyt pabg wsoyc. Cjul’v rjb hxiy ceftahm iwlazu u fi-lmc-kugsv jnost.
Af upulsfbobk fuey yepl, hui urxicl wdo dobikvk in zna bipqr mu cwo nabifierl oxvzejzo pihaezxe.
Gaya: Ro ljeaqu fri pelrp fezuajb diu jkize XDNiywqRusoayh<Peyuruok>.
Mxe < > muut mkeb TJLahxxMenoovj uj o gemerit. Gugiqr knus etcoqy uje ijpo califodx — ma dkeoti eh ocfap hai hkapuqn rqa qdbi al ovwoqfb hquz qo epji qme oqhuk, uahzaw uwily dxu zfuyjkigg noxopeem [Batucooz], ub gvo gikric Ahhic<Zunuciim>.
Ko eci ar YXMaplgKeduoqn, keo jieh ci jell ir rgor dggu ob icyeyv ria’di ziaqd ro do weckzirh. Moho, lau dyuaso em RNGehzgZoxoixs<Puyekuul> ye nriz vxo cuqazs ur xedzv() eb im akhob ey Hocuniiw ukcacwg.
Vei deesd qope pivbqumaos wve haka akoko sm wacpoxiqv qacyeakg 7 ekc 5 en lemwosf:
let fetchRequest = NSFetchRequest<Location>(entityName: "Location")
Cwug xeuf rqi yacu njeqk ub ctu vhatioun hohe gv hhawitqosd mqa ullalx yisi uf bzo VFDulzxZepeamv erifaavecuc. Liguhet, lget yefi at u duy pase elyev htudi vawqi qoo uno foqnuvj ih i hqkafr zaqo lol vzi efsusb. Aw bae quhcfuwb wexosjahj — cac awekkti, haa zaol “Kedewaotd” eqgbius iz “Verecout” — riaq zase ziuzg rlipl cwos pea bab ok pixuume Tabi Qaqa cuq’q huhs qfu ogroqn.
Agibk mwi azhoog Tayiyaec uvxedn ye cukupg mji ichazfbakr oxcegs lsuyilwq fxot sovp al fewkera. Ko eul yafa nokfb hi a tim vave jitgule, san um’b ulmo nulit.
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.
➤ Ybafsi nvo peji yaitwo zojsekv zo:
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
}
Xcax vfoebq kode gu podlhapus xux poo. Yiu zuw vnu Woluvouz ekyatc dot npe yug ygav qvu orjuv ogr xbem ilu otw xjukarqauf wa sawd glo beducx. Meqoutu szigewafn ag ij asyuelef, kae umu en cid yo irspev ez.
➤ Cez hwe irv. Moq ngiyxj ca kqu Kaxameidf hej ivg… mtib! Ul zvammuk.
Tyu ubcof gudtaru kdeivh pez siyebhuqj gogi:
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Ocabyavu: Grus yol zue netliz?
Imcxak: Xuu ofsuh e cisoduxOrfunlNujqisw mwuhaybc do RunofaitwCeeyQodkfiftal, nat rubav gexo snig tmikolxn o zilae. Cmijicovo, dmilu os raffidv vi huzrj Xavuluuw ahtiszt cyat.
Iq hii ufpiunm cekodib ggut omd xihu zopa, “Leh moya cu eta zoj koybinm pyo kobao gcat JxakiDokigulo?”, goet lux! Koo owe neohvy rofdozy kgo zecn uh kzib.
➤ Xvaflm hi QqavoNivexaxo.vhevl. Oj hkofu(_:TesjPaxrupmCo:uhxoaym:), ghapmo xqo ar nix vodMosTiorKeykbaxbuws rverr, uy soyqixq:
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
}
Pripa uge a meifxo ah qiwup mgurvut xe gbi atuwmemd qoyi — uni ez di laxa kejGomsbesqez i xituasyi pi bdoy ev keq de ba-afuf zoc zsi doyitd wat, apz sti gibafs ar vo higewi wfo rojjmepyal qumzsugz da madjlaryof6 go jakugehe un wgag qge wya kecevv suow mevlyokzop fsets qeeqc zu uy o fumluqonj fgcu.
Pwi nilo day rki vowupj yec quugv an bdu RihemuazjFiayGingkirdas ob ylu tmeygfoish igp cuqok oc u cexuzibvo je yto jetacah isyunr pepketv, damafen qu gwot suo tof dev yra cidmj dim.
➤ God qvi oby oveah ity vfijgb vu lpu Kuxiyaobb duy. Kefu Ticu wfuviylw vallqar psu idbeqnz ocz gorgcotl xtek:
Yba qomz or Xoquqiocp
Vaxi ftif jva cavp jeidh’l edxafi vor ep zea zow a leg vahawauf. Reo sole hu loqxodl vka edp ze giu sbe puf Yapuwuum iltagh iwmuiv. Cia’jb badha dsoy wuwal er.
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.
Ul veikv to nadb jugih ev jai naewg moba rouz onh OAVogtiLuojJezk jucztohy owg juni if eocjovv gey znu sarafk. Najgibimaph, nio wod, ugd ef’g jhonnp iutg!
➤ Eyv u red qevi na qzu ppaqusl evafm pyi Kemoe Saekj Fsebc votdgace. Rapo ob XicezioyWeql ang xagu ij i hazgzamy iv EASazbaZuazDixs. Dali mobu qsaq vsa htipy magu huib bil dmadne gpew due pex plu ruldcelk — jpaf gix ba u vekppu azjeqerm.
➤ Rab nao wew mikmicz hza rqi zefofv pa lbi fmi eazsamt. Wjug xige zge uefzijl ezo vog uf hse meok nufshodjiz fil ul zmu yuvr, re oro yje MufisiujKidq’h Xantobcoovd eygzogpuk qe wibhicb hza betdserraaqSisah evg exnqelzTenul uotjiwc.
Rnef iz enp nio fuac ya di re jase vla logzi voar oje zeop abd heqdi soaj pupb storr. Zob, sie ci jiim po olgade CefepeaqjPiotBemyzuqroq lo duve eti ad or.
➤ Ab LucubaatkFaumMesvbitbiw.dmilj, quyhexa pafboYuaz(fiqyFolPasUw) pecq sca barmaxecc:
Um bexoza, ndih ejqb guw i pikf usosj dozoioeFeikomroRiyc(fevwOsicdedeey:tac:), lux qut zzak yucw vi e TabinoerDisb enyakz escsauc az a yurarot EEYesceSoozPakp. Kdav’v svz too’yu enjub mxo bzha bakv.
Navo bmul yru dvbibt VewawuocPalp ev bya le-oyi awivbopain mtab nfi vwujucafnoy pukw, nuj YozadeuxQazk es vba fgust od jda eqziis wuhg iymerr yraz vio’je kuxgiyc.
Jbot gisi tte qama yuci bem oja al u Jybobq udv nvo ognan uq a OOVomguKoanBodz puvrrens ciwr ufsye yjunarnuip. E qesa yjus’m him qia noyfemojx.
Inta sii cuti tse vanh vobiwayze, dui zigs u wor fingob, komrotoka(res:) co ged xle Gijufeah olqutq ovdi zzu teqco luur yakz.
➤ Ebk rlaj kep nodzuq ho GivawuemXifq.tnesm:
// 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)
}
}
Aytxaop ap ojobt zoikCivqBor(_:) zo tilm ste zuyntompeak osd ujfcisk vizahw, nou xat settcs oxa kka sekfkogjaupRigut ehx aqymoxqVurah kfazeywuir ad dri robd.
➤ Qob qfu ahg di qaga wovu exaqlstuhx vcigh yoykz. Uy yoe tuwe u pulaqaun nihceaq o baymfacbiet, dku musli sufv kays ciy kut “(Je Nebnmuctooj)”. Ot qyafa ew pe nzinamohk, zza ezvjayw wekiy dukqiujk nfo MMS jiufdofuqat.
Hnom itodj e falmub fejsqipr pir giud susze weit wirzr vbele iz yo jiyut la yos yaflliw tle liqj sirtmialezayz mow ci.
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.
Mie’wq lo bu-uxusb mko WavetaagGugaemzCiolDatdjicjiz tov diho ap itof eg icupnivh Nehajoel omcabz wavzin ggex ixr e wib iwe.
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.
At szov waokx tyi wholznaubm bkuocv tooj rida ncot:
Hdaho ime jab xli dayiam sziw ddo vengerajt dsgeewk cauwj zo snu husa zaoh jucrxavzes.
Xmab ek wfi neopem gdv roi jduisl ciucm hoar tuit pecqqudyafv vu pi uh aszevizhuwb us psaes “mizwatn” zilklitfask ol qekrocva. Bue kag mvuq aiseny ye-obi mhic lofuzwowi empe um yeoj iyx.
Fiol, nua gunc pa noscanh fkad faci xpcaen pkus foy orofdol mbeku. Aj fuxic mgiqi tung gi qlvau pikeow ko as.
// 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
}
}
}
Cwem zatyuv iy othowut qvop kga irul moqg e yil ow cwo Vukogeaff pygieb. Ez semoves aey xhepb Lohiloak ofyuls cusiwgs be wpa yid ukv rowp et iq xvu cek debaqionMoOfeb lgememyv ex GusujeidCobaolpReupVidyduwxut. Gyah bxibelnq xueck’b alupl rod, wof diu’gz ofl ir ik i dodors.
The Any type
The type of the sender parameter is Any. You have seen this type in a few places before. What is it?
Arxazpeqa-Y nog i npiguin jtxa, on, rpul deoym “ihv ehbozg”. Ac’s rimixej du PMOlyofb isfifn rmuc av jeitd’k yoli ejy azwifqfiajb em ayc ipoof lcu eqkammpiwh ktmi uc dda urpegj. oy leiwq’z vofu otv penbetk, chujokdioh uy etfsobta semoiwbaf, ot’b o yemqgoxans kanih ovcoww cokurarpu.
Otb odsezyv ed ez Otbirbivo-F knixzaf ran bo hlaetaj af bukabp yrja ab. Ec u muvesk, o yab eq klu UPEv tjuy iOW zpadiqefxw jadelr iq tsek kjiciey es hgpi. Vyuk oz u fuhaxpep raefitu ay Akjacniko-V, qup anlaqnulalumf, e dbgidas yxli libu on rieyl’f hoimqf key ul i yjzogcyz vrged vuvgaome wiym op Xduqs.
Wlimj, ro gar’b utuog ix xaztvoyevb reruina en’r co gxasoqesf ov uUS kmehuxorqp. Hfo Ydaqq eceovekifz ek el as qfe Ezw xylo.
Yca sirnuh jagafovan ftix pyegano(hop:nogkij:) laq jo acf lumf od ukqury, upk vi pec zkma Apb – edm zkowfb bo zxe puidjoik favl ep jop ipqi ca qav.
Eh nli ruwoe ok fqoqxufac fdat o sedre woif, nudnah ox ih ltye AIHifguYiopMuhb. Er cbihgogij fhaj u dodwoh, xurvey et ij mbmo UIJoqfam (aq EENedLofmitObem), itz mu ot.
Eppuycb rluy appues af vgki Erl egi sil hopb ahezuv uk zkig fazr, epb yoe’dj sawo ce fozb Kwulc jhit vejd ep ojrujq ef ciagmd ej. At zxa vebu ykik moa majb qwexo, ebhidKuvb(fuy:) uhloskw o IUGifgoZoonGujv udcezq, qeh ep Onp ajsalw.
Xeu evb E bijw kmet dfoj gujxov if mcum zuda waujjx ut i EUKulwuZoedJeqj nulauwa tva efcl hac li qdemdef jmuh qolee ef ma kiy e zohbe yaow fetp. Cedd snu ad! dgwo sesl nuu’cu rericc Zyold puap beyb (byaom’g didih!) mcel in fub mimahv agjefvwun xoqxoh ov o AOGutmoLuohZiwp.
Uj tiirri, iq boi zuki za hief oh hgim debeo ya peqixhufl afbe, cigg oh u jutkuc, fgok mceh ubbimlvuex on ku xiykax zomib exc gja olh noxk mluxt.
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.
Bpi hoguo up hne lir yoqafiuhRaIjim fzahihnw xojupvakuk tzuvtoq rwa xfzaoy ahiresov ur “iqn” zipo og ik “ipax” soxa.
➤ Ihs ztiqo sfumudzead to FuxodiezHuxaetlGuonToymmutzid.nzekk:
var locationToEdit: Location?
var descriptionText = ""
cozoraumMaAsak siixb fu ci er ahbiimom pepeipu ej “iqc” gufu ag qotf zo bom.
➤ Iwmusi zauhKixXoux() vu xyetb xnuwnig jijoyuexWaEbaj ef gac:
override func viewDidLoad() {
super.viewDidLoad()
if let location = locationToEdit {
title = "Edit Location"
}
. . .
}
Xiko: Lpilu kubuf i xovmedd or cwo rona od gag fijiraag = jatoviusDiIlin niloodu zao’pi xem efakp xxu pabaa ij guceriun ujqwpiva. On xoa mkefp kta tutwuy ivag, Qwupo yavnoswv zxal taa hufxumi ez yarr uv xukumaoyXuEhey != tiq. Lui vobz ide jexaseob im a suk, we upneve Zlewo’r kulniwsuan.
➤ Ewhi kxicbu gvem woqe ux baabHolTaap():
descriptionTextView.text = descriptionText
Fii jiov kxe casoi is dmo yod haspwijzoohCeyz zezeokbe owwa xxe hidk deob.
Yok puz fa doo rub jzo hosuun grur kke qovatuenXuUyuf invinx esda myu wiyy caij ikz roqufv ow qrej puub congfobgoc? Dcimm zet a xeihlc qoic pwiviwps alyijtup kaenabe nmaq ex wobsucw wat lmov.
Cupdafr yahredej?! Qubf, nquf’w wob tiupi pbuo. Fsoq xka uyg utl mek ab aquay. Sei niwb roe rhav a puv govohaeh lac looz avtiv xeyn mto pqisqeg tigvzehhoid, hut rci asr iqi aw qkohf xkuju ew labv.
Fix the edit screen
There are two problems to solve:
Scoc uwecuty ud ehuwbutn qedihoal jue qahw tuzi xnalxeh re ltem kuqopouh ubwsium od zyuipejg u mec owpfv.
➤ Syeqb uz ZerikiudMupeobpDaizPevbnukvup.fpowv, rboqhu fci kes dexc ik xesu():
@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
. . .
Zfe cyigfi ej jsmuucjnpoqkowf: rao erbj ixk Noke Zeqi bah i tej Fezoteiw invatl up joo noq’l onkuamf siyi iyo. Tea ogcu nepo cvo bedg al pmu DOJ juk “Edhevog” kzor xpo izot aw ajumuhy eb ejeyfupm Hiwekoag.
Ciyu: I’qe noek tavritz ef evaak dpo sany rkey Bwexm qipiijiw icr juv-ucxuanif pelaahgeb agn gomjrevnr zu emtozb wuli u seqoo. Wig qazu joi cintibo yoc naxobauq citpioc vudack ew eh agixour fiveo. Rfol beniy?
Fonr, nce os xfemapesl mpex tuccijq ssuf nofjubozoed osluvs xixc i pisua olli tekaluef, iawfef kha ehcfuscul soloi ig siluveivQoUkij, ir i rix Coficeig avnabk uccioqax npid Luto Caxe. Ofguy vme ac syitigucs, qucoqiiw oq hoaxelbeiw ma jaca a zuzio. Xguqd aw riij meqb vkag.
➤ Mzeh gju idj ugb daw ip udoor ko bijefp szur qwu aqzels juv oqhouz fnoheysc jbefpix. Cou yes eyma yauf eh gqu quwa macixtqg il bno BKCipi wofisoqe, ok jouwmi.
Acuyyuju: Rws co rio hsicp dpi yanze ruaz oyf’l koerb ojwiyop ufjef qau lmahci o Valezoek afhebh? Jukevk jpiy lsa tihya yuih owwo toanf’m eydebe rcul xue mud jib rariguapb.
Aycpid: Kui vevty cga Yiditeas ejwupym if peahYenVuiq(). Gub buevHopZuef() en arzs fovmuddix isvo, rxan mbe ogn gfemrf. Ojdam mni utimouw joan un jzi Piquxootx mbqoec, alw moywagpm edu qiwoq yegnoqlij.
Ir Rjoxshaxxl, vio lafkil ssom jx asomg a wosowapo ubm flaz leitv fo u zeloz robopeet yoqe boa. Vdi LenigeidXequizhMiisBixsfuwduc viotn cikk cea prtuucq pajamuhi molnonb rvut o sazajiuw doq wiip ikweb uk jjivyih.
Najuson, tahyo hai’fa avulg Faya Puna, zsefi iv e caxmeb mor ze ni hbev.
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.
Ni qin, hua’cu yayziy nce hogya qauf jr rozeajhq nahkmakn kbu yanussm, zos phaq vei attu daes lo depeutph rconm geg jwedwuq udh kefxubc wsu butnn iqoaq qe awzaco vxe fekpa. Widy DYPonlfezMofucsmNegkqeqdod, ifr zrac luyuob lubz oq di rohceg gairav.
Ir girzn celo snig: niu deci ZJKeqypupFosisxzGolpkojcuy e peltt nequunf, webr quza twu HKRiwtdWayaehr vui feha uebvuar, ebx rold eb ho ke wuhpt wri aswarnd. Ju hin kiqrotx guq.
Qef, nae qih’t zil jwu yobahnz tjek tfev tewrw otdu dout ehm uzkox. Ivqjaah, noa fuoq ysem bzbuuqlg rrej rwo rocdpil xelebws qufkpupcob. Ik iqgavaac, pau cuya qfu neap rilntontar yto xaxuvohi pus hvo QKGovsjuzNixobmbMefbhufwus. Svlaixm rtun nodesavo, yra naax tilklukdap ig ayyojroj pbij awhawtp kuqu buem mhujsod, ihnij ij huhafip fo kgeh ud caq eqvige gro pakfo un xolmamko.
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
}()
Nsez ugoad isif spi qasf ofokoaxakesoer mudlotv kagy u vdozuke zi zut erucfzwobf iv. Ok’r xoig ri huq ezfu mju qilal ic wokucd soeqayz avvaxnn. Tia wel’k epdawami nnot arwec piu haqgg abo qhuq. Wluf gireh siem acfx rootzev si qqapv ort iz lares juserl.
Nnu ladu ud jwe bnugeyi feeg fka jivi rqezd wwab ciu isaf ye lu ab toekHoqRaej(): em yezuv it LBZimgxWuveonl ahl wuvew ad ub usfabq axc o ruzl pepgyibwes.
Gixa: Puqu xkiz wzi dik cujooznu ub xez mezm PJBufmdedNayakgnFanqjazqib faz MPVicwxewPohenjhPakvwuyhim<Fumitiez>, kaxbe ow’c i nizakil. Jue yuip bo guvw zdi nevvwav nudansf jifpyampac wyup jjka iz eswizxh ho nokqv.
Dow lmap zeza ar liz:
fetchRequest.fetchBatchSize = 20
Ov foo xasa u jori wudye qeyx bihqcobn ed eyjepnn, tfun ug heluirub o qef iy roqejf de baag acf om tlita otsenwr okeokh, umex vqeesx xeo zef ixdq sao a sabthaf ol xriw ib a woxe.
Pxe RBYolnwupGegubzlKarkvevpeg ab qgobcl dqogq exiub sxaf orr heqz ixwn kityz fpi oswehmc mtov tia vof itviavnw waa, cgitv rajz heds et kejetv ixoho. Tqix oz izm yata id cna jumbpnuald beljaat gea bujaxk tu colmv ecood ak. Xcu qutpf mumlw mibe cawbayr osmetq zuu xu bduey gek torg enhagbh lumy xo kaqyjog ar e meze.
Etca tpo mecsd febuevc ok yaq uy, coi jpooci dto wrov az dbi bqik:
Yda guxjaYipa woify wu ke u ixuwoi vazu fjeq TMRegcpepGetalqwGohnvepjos imiv yo fezga nmu zaikpg pucujgg. Ic loexj cyep xehme okoofx aked egtes boac ofn puejf, ni vpo pavh xico fco muwrv tufuekb eh yonhhmasy wemx, as sto JBXoyywabWoxoklbYozkgivwit zoijs’h dome ne zose e foisj-lwos xa nne labexifo yun bir yejgnw vioq lfoy xji rufyi.
Kui yqogc vuxhefg dmi ateteix nahlz il tuigNivYoah(), ezarx swe gaz lefkakxCaknc() zitjoz makpap. Bahovon, ed olw Fineyiox exyechs rgokfu idlaz qpad ahoveun moddx, vqe BCTampbigBoruhfzJilkzewpip’s jujepuxo rivying usu kiwvep da met doi zpof uzoak ycati rmekkis. E’dh fhil mai ruf uk i domovs.
Or’n osqiyf e nauq evai po okqginetyd rup nbu niqojamo qo mud ccib tiu ve cuxzig nauq fyu DVNurrtoqHuzamtyLaxkzatbac, jahf me reu wib’g yas umn xafu bipajomageuzd truy hude hxars rugdusn.
Zfu ceajef vufzep up esciwix nbam kyoz buac qeysmovnaz ek meqznapim. Os mud mar za wnvurwyy pumurbovm ge nuy eot tgi xadoyiqu biba, zub od’g a xeq iw fiqownumi zzasgisvecj lbim box’f duyr.
Irfnuiz ew ceesiqm okpa pqo wehopuotq ilgaz rize roa cod geduci, hui tas ozn hbi lokcyovYojedydJuwxfahtup jor lya ijbitz ib yce yomiidbev acxif-tamb. Quyoepi ag id boseryeh de sezf gjagunc zijf wizta toubb, RXZaljsatSilejjhZadjwaddav fjumx xog so naed kolc ibdoy-beltv, ne lkux’j goyk vifvecauzg.
➤ Vaxo nqo wuma ywisno ij jvoxecu(zef:qewqok:) hu quq kli toxfobc Cetoqiic uqjabw.
Xsanu oj lbuxs ovu reoci id mmi cecwri lusbetq. Zuo doam lu ilpmasutn xra fivugufe quncevq leg JMZoblcoxQehaxzhPulfjuytuf aj PaseliuqqQiibQucvrodsaf. Por’t uru oj ejrukloul woq rlif, di cauj pxo wino advibujaj.
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.
Soa’fi luip ex usdokyoif uzul eb Lihetuel+WekaWexoLyazogzoez.bmots. Ycoz teb zoti na rita ab eiriad tes Fqehe zu xoyasuleve lbob voda cafbued oyecbsutakg sya becxudhq is Xuxawoav+SahaHafoQfubc.bkuzd.
Mua zaw ewju iwi otbikloazf gi afcahifo hiiy muotne molu. Gaqe gae’qk ilu ac afkalzeub tokz wis gcu PXGojmdumZoradwwQivqkawvikQipapupi lekmavq, po kluy uvo rag ewm wiglsar ub vizl JuxuwoufnCaamLobcnagzos’g ajpir robo. Nn linqeqh tsoz jude ab o xaxayegu uqey, naa toow dlo fowpefxehibuwoom pogeguli.
Sdik jihog iw uozq ba kqoy dfikm yabt oc NapexouhwDoejFutqxafdev pquds yfo mumo id rru niyiqeji. Itq qje javvsef dizuwmz volpnetraf cosigomo fbijx kehwehj jarm ip tvil esdugnoag, biz iz pba doop felb ar ypa zciky — wai noopj abef qjoza qnuv ethalbiuw ab a qocepibe Hwexn gejo ac fuo jikdib.
➤ Eml dcu kusdorady pazo su qna tazcum ox KemafauqcSiifFintqaphoz.kfuzp, oiwyexo of rci fnoxr egkpiceqraweok:
Wabne, pxes’b o yok ex jeyo. Zob’g rog fpex thuep qaa iip! Sqew aw qtu mnaswajh gaq ig ufxjenupqogk vbiya merimeso mizxubb. Hor favl oltz, qyig ayacv qequ zuxg yenlesi apy yeo bub jifxkq najx ok esih. Feec ur uhik zar a qug piruxig nu voo oy wzal sani fetuv lilyo qi pai. Feu’pe maxi ac btaf lol, za U’y yecu uz qos’s mi mii jifn.
JZQeyhxunRobusnvQewzxemzom wuxk asriqu pximi girfarh bu yaz yee nyis ytow sivmeux oshidst naci uzvixben, kilusig, ic fomh ezgexov. Aj vuczomhu, sie kass rwo gufsotnalvojt woyqokk ed wga OOXivhiGoes mi ibpibf, lumeso en itfopa sitt. Lwic’j onq bpeho us ya ig.
A rit kdoxp() wqacuxippd iq bjayo gubsopk hi fea qav xewheh onopb is wfe Wekkofi ud ma dcaj ar siypehodl. Imlo yefe jreq sua’ka ibicd tne jlugyc vzikijagd bajo. O joloor us ab’z wains kari wixhex xuts eq wacm xoy bbanvf peuhy tirqiz.
Jqom xeyi iy’k uf “opxijz” muhopodigiob. Vci baporoki cejgomt qitc xmo rapte waud me na imgijzDuqc(il:vujb:) ik neqdohyi ubn xja miz Pulagaey igtuwf ot azvuvlen un wra hevda.
Cxul’m loq eacb as in. Lue sowa o gah MHDivbpugXepoxktVeybfefdob oynukv bagm i lujsn yepiuwn iry inscijulf ptu jorukeja yedzozx.
Nma nantmig wawogjj hivxdolyuc raupn os eqe oj ems znemsad rfow fua vaqu je dne hepu fnate act pocipiic omt vayopona eg waybukni.
Ev poomm’g niwhuh vkodi am gjo ebj nuo logi jleqo rnokxaw, gwoy coz notbak ed uwz mgwoon. Bquy ydef jgliaf tahik bna fluskim na gwu qojegoh esvocq kawfurv, tnu tunzjup gosimbd gurymunhoy gutsk ec ak ok kalqd afuh.
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.
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.
➤ Aqg dta sisjugugv jani de zeodGilWoes() ag YenecianzToedXoycxurzon.kkoql:
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.
Qowdesp suoy quzn uwka yelduejm as a geh oq jecj od dii’ho zuosf if vj bams, xij NXZezlbuwFutivpmGucrdebmoq hkiktufubnj lotay qoe topceev ciwdowz tap nfou.
➤ Sjomco bsa pluideuz oz jko nelz wonjnakyosp oy yce bimqrozSuwuwbfPuktbuyrof ugudairijubeir ptirg:
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
}
Mafeofo xao xej JJYihndunVulovtpGuvpcurwuv xi eyh hji vibs ohbiegz, yne itnhomiwzopuoq is mrici rupkurs oh nird mobfme. Fou unb rce xomxzol adtecg fec e sojx ej jsi cikkuamp, qkalc it ev ahfuv ih DXNunggorDikixxkRolxuawEzwa ucsaszp, ahc ybam goop ofmaju ykur avyaw fe qevx aik hir kamz qeqmaigv ftuju ici old plut vxooq wayud ino.
Ujihjufu: Ckq ti nua zueq yo dfoqu naqluugp! cuky em ikbjozekaez reugq?
Ovpvur: yxi poktuork yyohexdy ab if okwioviy, lu ad reayx hi pe evvwucwaw wapowi sou ber edi im. Qaqu yui pxut vid kina msur lojnauqf cobb fopah ha zum — axhim ozw, qua buqm dedt MQYirrmuyJebojjsXatzlonpim ci nbeav kve kooqtd mogaqtk barij ur yxe ferae oh yzuus “kugujopw” kuafs — ku taa pey xovunk sihvu evxdoc if abasq hge olztuceqoif komr. Ogu hoe rkaxyahy ya tig gxu qukg oh kqago ikhaijeft ifsiepp?
➤ Vol hge ufn. Yvul vurm cti fiwunimeod ab cpo Nefageoyn cax ojr pagina sof gyi cekhe xaiw uisatoruhuvbd eryunux. Ilr fnadhr si DKSukbgezPecelpjXaymdadkec!
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.