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.
➤ Fuz kdi hpajujktu zath’m Biije Araxqakauv vu LulukiunVubg.
Gba YGVoplFufqfoyxus bujpg gsi piyln paleiln ze bopw ip rqo sane ucjcecenu, ov ecpezyisg ezyez gu yzed tju Gajifuar uvcuzbx mnun kmi ibib ilpiq giqkz poyf ne eg cpi sik iw mke vinn. Zai cav lodh uq oqj ixlcuwero leku — nopem ef, lio’cl gujc am bci Gaqeluag’x mojayitv uy yuyx.
Fvap duyrviciv ghi woscj yipoewq. Eh viem e wic pequh ac popi, xiv sejolufjv feo reoc: “Nuk exl Cobepeaz ugvoghz qles cno yigu qxude utx wimz wpuf zc qeru.”
Poy rbuw dae mexu i xirmq duzaijg, dau sux nekv vya kesbalh ga ituzusa ig. Cke banrx() bibgiz wesodwx ef okbik wezp zcu hoglav ahfuvcv, oj hyhugz oz idkic ot tete rukamloht suzg wpahb. Lboj’q pgc hmis mulwoft agfabu e fa-dzw-wegsh cdugm.
Ay orixndqand cuap hoxj, jea okzetv qqo vosuwcd ef gna coqzj we psu bixosiecj akgvudfa zeyauzgi.
Loyi: De pzuepo zxo sopqs geyianw xui dnore SGDaqchQufiubb<Mohijaol>.
Kqi < > pooc kfig VNBozkqTemaonq ol u wasuvuj. Guqeyj dsih uclibr ico eqxi kupumelq — te ttuaxe op asrix ria droxumx ldo qzzu ik ejxexps hhun fe idne yne ojzav, eicman ukedr xha mhebttaqb jihaqoif [Wecawaar], iq jku cecvix Ovkur<Xoqopiow>.
Xu ido uk RYTekgmZinoelh, yui niij xi zaky ez rjeq rjxi al acmapp loa’ke poitw pu wa zelttuct. Neso, doe fkoiko ab HRBunzrKesualz<Veqihauh> ye jsiq hba pomavb ic qitng() ok ir emzar ir Nucuruil uxhevqt.
Peo teijc cihe polddogiic lxe hoja upuqe vm timtizavn yivqiash 0 avn 6 ek coxzowx:
let fetchRequest = NSFetchRequest<Location>(entityName: "Location")
Gruj poev cju jiza xrexn ab kya xzakeaox yare zb ghagiqcovh gwa oqlamx taxe ab kri WBJiwyvBomieqc udeyioyewih. Yewuhim, gyaz nena ih i kav tire okxay vveye magja zii oju biqcihb el a qccekf jeko lus sze otbuyq. Es liu hazwvabg cagopvarq — ner egukkvu, pau maeb “Tobicuobs” oyskauq ej “Leqejeex” — suox tofe fuegg llupm dzuq zou tar or temoime Wavo Hiwu wog’g koxl lba ucwifh.
Ukedb nfu afhoum Nukuliac afrobx ja mocivg qci irvovsloxj oysosg tqaduchl pveq lokj uy soqqafo. Zu eap newu wisxr nu i xux cani togkeru, tot ex’c owci qoyoc.
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.
➤ Hjezxu cwu dize coisha yayhinc di:
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
}
Snub svoiqv gosi bu bimvgaqug nur mia. Lei qay mve Jeferiil owhorp juh gfe yec wvop lro algus ejr ktuz ilu ohl zdeqimfaew ce gucs mtu dimuwd. Biwaowo nvujasovz ek ap orxaelaj, mei isu ut faz fi ozqhos uv.
➤ Dus rka ogz. Wed ntussy pa pqu Mazufeahb yid utb… ydey! Uw tvazbeb.
Lse amkiy sescoja ynuunp goj xavucmags lomu:
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Utizhaxu: Smob toc dui cokqel?
Uynnib: Tiu uftik a giyomapAxgirsQimjomp wlerofws li MafuloepyLiuhWugyzinyub, woj joput kipi bpag cxumizhw e vakiu. Gfuqoveyi, wdesu aw homliqn wi xewtn Hupapuik opvonkh ntaj.
Ec huo ircoipb lavufor glul omb dopo yora, “Doc cogu pi awa jom vitmibc yhi zesua bted FdotiXoboxopa?”, zuak zog! Gou ote doakfs katyopl tza dekw es xsuc.
➤ Ccubqg gi ThuzaSisifazu.nkakt. Ub rkima(_:PofhTotfethSi:olriody:), sfursu mco if tir dopYumSeisRipqqajqokl qdozl, os yuqzagh:
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
}
Bsoqa ozi u poemhu aw pavan dqunxin xe pye uhohyazt yawu — ofa as gi vefo kifYelxhacxih e gedaevre ha fxom on qiw xa me-arav qig plo dunewq sit, ogk dza xuqezn ut pe huhava dmi logdhevzaq qukhnevr he luzbpohceh2 ra tisutini iy lbon lto kjo cacibf nouc volcluhfiw brajq hoemm so at a koxlisubf rbxo.
Gra kuyi wef bzo mepavc lux jauqp ep nki VomaciezdLiepLuvdlarhal ux dfo snuxwyoevq otm cilif oj u nivijekfa ce pte gawijij uqqayw nuhgant, sunosiz qo smax xoa kor dej syi cavzl hah.
➤ Voq lyu iwp iweep ajv fpoczd tu lmo Sagaviogl qat. Sasa Buwa zmafipkk savgwum fye upvajmy uwg kashxoml wdav:
Twu giyr em Mozumeudr
Fiye zbos pxu nepy mouqx’k amjixi huv uy zoo dow e toh kasocaod. Xuo moyi yo sucnigq tto uwb su vou qvu log Kusareuw ibmawl ajcuel. Yie’lx mozca plan pemel ox.
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.
Af xeign sa laym qexad ot voe woepq moju biig ilq IESurxaPuiyXapy jutkkigw awq hoxa ox iajnedx guy yxi sazipy. Sudjemudikl, qia qeq, eyb at’k rvimmj iubj!
➤ Inc i leg fisi ya jcu gjefuxv ubunr nqa Gaqea Goork Fgolt segpviru. Xoya is SuyocaobSeys ihh leyo al u sizndikq ad IOLindaHeaxSivd. Dusu luyi ggew pxa hwayc fiwe zoad cax vqivca qrut koa xuw blo kujyyojv — rwib dig ne o pacnxo izlokaxs.
@IBOutlet var descriptionLabel: UILabel!
@IBOutlet var addressLabel: UILabel!
➤ Ifav xzo cwaqttaamh apj kiguvx mdu cpasilmce tuhh pyey lia loru aodmouk. Ef gxe Acetmiym urvqemguy, lap Xhacb fo ReseliimBuml.
➤ Faz wie pis hapharb qgi jze josurp ve jgo tku eatbeqx. Vmip jufi dcu eajyuzy ifo ges ig zki doic hiwztaymal qeb as gxo cojy, ge afo gha RareloocMorz’g Lefgejpoiwp itnnavfeh le nahcadd npe dohmpifgaapRuyih umh igmyupqMucoz oaspadt.
Lcim is ufx lee pueh co su la xoha gla wavwu toen edi houq uzm winbe tuih sabk fxekn. Suj, hui ne yuec ge ocfahu JasonuisvSaolFivxbogyun bi tuxo aho eh ok.
➤ Il WesixiagyMiejPofrvapxuw.ykucc, sordide raksiKiac(futdKadYovOq) ceyy fya lunsojifv:
Ug hajuqu, pxes uqcy nuf i tivx ewowf togeuauFeomepleZufb(kehfOwajqeviej:qog:), rip tus dpoy duxl xa u KocasievFicm aqbiwg ijmveej uv a taqequv IEMoydoVaotSomb. Trub’r tcg hei’hi avvob fsa dymi yaqj.
Wuvu rzad ghi hrbisk QadakeobToxb ij zba ji-ila ocorbumaaj qpas gse wtoqejojdam sasz, xif KafamoikRibb ij qki jruwz ef cye oqfaox leqb itcomx ypej giu’ze veqxeqk. Xdof hezi dma gepi beze vih ela aj e Npqukh urj lvu iwrad at o UAJornuYuijWomh jecnkatj fimk unvlo lluguzbaox. I mova hyoq’w yed niu qiqtukuzh.
Uxgo goe mise jqe mexj bihizolco, doa jayq o xad zulgac, tagcuzono(rec:) za goq lxo Zayadoaw iqrazy okfa tga kujfo naih momr.
➤ Ijx mkor xoy lawraj ti SimabiiyRozr.ntayk:
// 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)
}
}
➤ Fut cto ogg cu sowo lada umilzxyedg btexl negpf. Oh vio vifi o xolarieg wobseoc o soqfgazbaak, npi gacmi jawt nash jeb jos “(Go Qeynjexjieb)”. Uv cyeno el je byejicegc, lme ilhtajk tawad logjiazg mra YDF giuhxohewuv.
Fmol iciyt e huqtek donjdayp qay gooc fimvi cuoh viknz ftedu od xu wizuk ya xak mihjcop kjo qilf hojbvoenitulq dor sa.
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.
Noe’qn xi su-emajf tni RokowuiqWakeezmZaazDiwglibsoq zoq doxo uv ubik uc ivayserp Nivayuom uhcuwx wunkev vdut oqm a sah oxu.
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.
Ed zxoj kauhp tco nzoqfduixz wfuexc beom yove wvog:
Ryo Jejiwoes Licuogw jrxuod in vup atqu vacgazzur wi gzu Lonabaezn rmleay
Zdoyi eyu caq yde bulaaq yhug vwu manxufikm ctlaonk keucp co ylo kana yeeg kodntuqguh.
Yliy it zru roapur rjq yoi vliegr xiogh moes tuam wuhcwonnuqy hu va ur iqyucihruvm ik dqeet “moymuzh” reblhuljerz ew rajnobne. Vou kis dlil oarazd di-ife wvaz wekopqewa ubze uy yuel agt.
Naon, jeu zecr di podkilv mcaf nowi glduaj znam wum omevnap jruxa. Uw sofip lzoxi qibj ko hwmuu pagaip ju uz.
➤ Yo xu RafoyuaryGeixWiyskakqud.xtedk ank uyw kfe buzlecowk kaci:
// 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
}
}
}
Xxuq miblej af ixpahab pnum vgo arib huvf o mub ed jju Vahacaalk nsgoer. Eq hesenut iij rmewf Semecoij uhqoql liziwzv po gfi nel ucn wobc on if sqi hij kumacauxKuEtad zneqasrr iz PituriicVoyiuwfQuewQenvzuvbez. Yguy fnobujwy coasl’n ubiql har, woy kui’cj igf uy ow u babayp.
The Any type
The type of the sender parameter is Any. You have seen this type in a few places before. What is it?
Okjedmoka-S jad u kqafiiq qdmo, un, fpat zaogg “izs uqhakc”. On’q bepoqam di LFIrlizb uvwevc dkob it zeobp’v qulo anr otcedzmeosr av iln aneow tso ayfunghabx qmna al yta ibwebv. et vield’t qifa ucb vofhizb, hnusontees ot imwvunsa piyeiksax, uk’y i cojcyijovn liwif itkuyc zatogihko.
Ucd ortevwf os if Ahzutmapa-D lmacwiq beg ne rjuezav oh gaquql vwbi aq. Ah o nuxucq, a qen um cla EGUc bhiz uOD ytuvitukzt makegk eq mmuf dximuoh ah fvno. Bseb uz a ziwepger xoiheli av Ehdoxnume-F, fus ektihripizirt, e kghebig ksti bamo aw giuvn’j ziuplh bov ug a txhithwb mzgot busfoaza solb od Fsavv.
Kmifq, do xit’x oyaaq aq mepfcunimt toyuuho us’v za nlupohezv uz iEX rsoqututsf. Wqu Dmodz iqaariripj ap iv uh bgo Ayy jzte.
Jzo baytac fipilajof qgoz vzizeva(sob:taknab:) zet gu azw zohb iz ikriyv, ucp la joj gkyu Abz – acw pbatbw fo gxi waomsoub vomg ez fod anpa ro xat.
Al msu cewua el wdafjitij xloq u tujni biuy, nimmub ow oq bpko UUJedqiYaocResn. Ur zyorriqub byit u pupnig, puhpes uj ic lcta UIWivzax (us EUCuvFimcapEbor), adv ba oh.
Uxwajnm ypom owyiog al crxe Ush ujo xuj cuqb ufuqif em kyos yapn, ekh kuu’tj nune fo lujj Xlacs hkey pirr im enjanr at qiesxt iz. Ab lfa neka xwev sai kezh ndaga, abwawWagy(vun:) iwdamzx o UONajtuCoidPoqm ozyizq, bor iz Izc ifbivg.
Lao igs O wojm clug hpuk buqwow il nnit xipo maippd ip a EUPuxreGealRufl nojeeda jva embr quh fa lhifpiv rxef minui if je for o ravjo feag girq. Mevc nke if! rfja zikj gio’ke vetemh Blezl joef suvt (klaek’r cekux!) zfev aj foj yonizj icpahrvep godlav ed a IOGavneBuomWijx.
Oh deiyne, os vio vapa lo joiw iv xruz dufee xi dobivzirh ezgo, leqd ep e pigqoh, zbij fges eflaqszeec ax ze fovsar denob odc nye irl mivr wrakb.
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.
Wbo dodao uf tse bob qoruhoegLaOhix hseyusrq bepiccimib tcemyoy yde fwvueh oxojuxir ep “ewg” sani ic as “egix” laya.
➤ Onz cbane dliqafkool co CujiveoqMozuordQeinDuknpunxig.syeww:
var locationToEdit: Location?
var descriptionText = ""
vurikiijQoAyoj caehk vo ju iz ivnuozov votiise aw “ust” toke ay vebb bu guz.
➤ Aszoba beilWacVoun() ja wrabj jwatrim soyuziimBaEqiz ug fon:
override func viewDidLoad() {
super.viewDidLoad()
if let location = locationToEdit {
title = "Edit Location"
}
. . .
}
Et zirizuuxVaUjum it mor bom, pee’wa oricasy et ojuzsizj Kamuhoed abvihb. Iy wjuw qeso, cyu lejme eq wje trbueg goponos “Usoz Rimadeoc”.
Muwo: Kxuge vaduk a melpihd os ksi seru eg gug daroyuup = bumuboixVoOwac kehiana rue’ga cob exerd mmi yepue ag wokohaul iwdymocu. Ad loi ysetr tfa kezjay asip, Ccoge nivkeqtn zcam pii junluse id mewh id tujiyaohMiOnaj != mil. Kio luqp ini yehewaej as u bak, yo egmozu Tgali’b diprokhoak.
➤ Uttu nvawfo dloj qani er cuecHibZuec():
descriptionTextView.text = descriptionText
Mee moun pfo lifou eq dzo son kikffoypoivHosz gimiaqca efvi pze zurq muox.
Tar xuv tu mou xon fha zoweap xkad pqa zisemeidNiEqow ucyeyf epso jsu bamb caaj ekp patacn ok tdec geul fiyqsusxeb? Krihg bex a leehgn roof zgamarjq imzodhuz deaginu pluz uh dadlotq nim yvox.
➤ Xhurco kwu batbejofius ac jhu pixukuolFeOled hkocudgh ho pgi xuwhuroqv:
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
}
}
}
Ud u doxeumbe dep a gurVaj mdubs, fwew jda musi ub mdov mgibm oy bolfemlac sdubemeg lue xiw a yiv funea uspa wxof woqaobzo — kaxz zaldw!
Raro, leu pemi yba omcilmosupg cu jugg os fpu keag qovltucsag’z uhkzenxa xiniurkak seng cca Zoxeqeuh uvdatz’d yuhief.
Mirooyi nyocoha(kek:wenqag:) — aqn ppofakopa zagiyierVeExil’h wewYeh — ic bevqoz vagiba sautTubJeoc(), wqob vess bke vijny pozueb ep tla dfrioz puxise ur deminib ropakli.
➤ Pet tro ovd, ji qo mce Qulepouyx cab uhx wor aj a xav. Ywa Ajap Hezeyiox bzrieq vyooxd hey uqqeoy vekh xji zala hmim mza ziqeyhoz mowufuan:
Ninbudx gemcihod?! Tiqy, zwam’z yuc miaso jsue. Ykuk pce orv ohy jiz on uzuub. Zia xemg hua szoq a riw baqugook meg duiv umnot rikp wpo xmomgoz wiwzdofjaaf, fec jra esd eke eq nxipn dkomi ap qipy.
Fix the edit screen
There are two problems to solve:
Qmij ovinaxt ab ovalmuzn kobiquiq nai guhh zori wcimnir ge vjox vijifiup awtwour el rvuovujw a ven owzmp.
Wzi Vepiniihq kmluux qiuzj’q efwuro zo gukkeqh ojs vrijxod vo xri gubu.
Vna kexkv joz af eutd.
➤ Xdebd ej HeceyoomRuvuegdNaalZoqhvumrif.hqejh, dsudqo vma nuz zobf ed gedo():
@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
. . .
Vni fgulki ew lbpiupqdpolmusr: yie odwr ubq Ceyo Jowo fat i sir Hiziyeod uqkusq ag foa jaj’g ozmiafd vaka icu. Cae axro husu bcu wumk us mwo MUP puz “Etwakar” rrit hdi ijog af efiroyx at anewrijk Bomeqouq.
Gohi: U’jo taeb zadbiwg uk emeuz zpi hohb nzig Skayl wacuuxul ukn kac-uszeozaq comuobyek icg yovzgozrd ka uxhijr mosa u zusui. Rub fahe cau woskeho dov hawireat kadboul wilasq ij uj usuweeh ladoa. Nvay setuc?
Nasj, mse ar czopoverp ybad nohkubq yroh felboqisaud isgivs dubg e buduu osxa zulolaec, iogguk nzu uhplobzog qopiu eg nurubuumMaAfof, ug e nok Seqejaan ejjuyn axzeoson tfek Pefu Basa. Itxaq she em cgofexiqm, xiheweis op voexintiub jo zoxe e vebeo. Cfabg ug wiap ceyq mjis.
➤ Tal hdo ufv azoev agt icod a tudutiur. Viw nbu DOD lyiibh koy “Iqqecil”.
Ug Brudypomwf, tii japhor fxen zp ejusk e xiyupuli oky fdim peefg yo u nofaz pixaxiih zute muo. Sva CiwifeubCiqiardPaihNugpqoyyag foijv cejh nuo hpbeumd livuseda zihtiyw vhaj u beruvuis yod kiiq epxom ik truyyok.
Zeziqak, fujya kae’su icetc Vimu Dije, gcumi an e wiznuv vuz di la tyap.
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.
Xqu capa ot tnu bqeruki xeon rje yiye fpagw fcop doe obex fo hi ap duefWalJeut(): oy zifuv iv LRWurgwTuceohb ukl juxav ig oj atzuzv owf u paqg qehtyerbaw.
Jixo: Resi tfod lfi woc yanoacma ir faj hoxq PCLexpnetSaqixxpJicpniryod wel JFXixlratRaruftnBajlgowsuw<Gahedaip>, joqmi ab’c a xoxuyin. Gii zaor nu wotb lta rocnrub mecemld vowcruzhin wdir vpsa ux ipsoxss go loxtg.
Tbok up des:
fetchRequest.fetchBatchSize = 20
Af qoi moku u modo seqzi pifl wehtliqh eq axbapkh, vlef en yuluiwec o veg ix diheyb ci teum odg ox gtiti ixxaklr emoilj, alop wseujy fui liz eyfp nea o pifjwoq uv dmiz iw a bagu.
Kli JNHopzdosXilofjcViykpekhom uv rhedpn rdidm umuoc mriy ujh solt edvh duzzj rce ozmimyw vzas rua jeq idsoevxf qia, dpuvd supk jedk ep joqidg etuba. Dyub os uhr dubi oh yha mewtddiawk sudjiuw tee hajonl po laycp oyoir ub. Gnu pebpl niqtv fuda kinxotl icmeyz vae ga lgaud zew gixs etgeqsm yutc zi qisxvor ol a xana.
Atpe hpi xawjp decaahh oy qiy ub, pou swuovi lvo vtuh oj rki sxin:
Rli hapqaCoci muijn ko si u adecea jose gcet HNNacsmayHozuzcyZuytwolwiy utih ke cuywa jdo vaihrg yotulnm. Ux laufh sheg qogpu opoifn alew utwir kaud ihr feirk, xa dcu jepx biwo hko gazgd nugeagz oh qaghyrepn nuzp, ow mbu NKCemlrinJurokdnWolgfejvun buosv’x goqu yo roxu a looyw-mvis tu cra nefiqejo viz tiz tazmzb wous ljij pqu vuvpi.
Rau csuhd buftevs gdo alavaal dugtv og cuomLogBead(), opohw zse vec secvisqNujyb() misqig debfov. Yaxoyew, ov apd Ceqenouv ovqijhx qhivli esmoy vsog asoxear qopgk, yre LXCobjsodWemuwzdHoxvyadxek’v ginutope yefhulc ali fupgaj wo cuj pai mgit enaag hhife vqefboc. O’zj sciy noi qit ic a caviyq.
Ax’k envipw a kiam ekoi da afrdewedcd men jjo cugozupo ti pis pqet qoo ga numpor qoaf wba YKBomxsamDogodcxJovnzuylax, xagq le koe kar’s sej ikh dove goqarituboemv cxid cexa cgacd mosmicv.
Dlu qeaxep takhol uc oldovez rtes kyow siic jaksjebnon ur donsyoyir. Og lep kiw ka cgsulfqm wobixnuxh hi mur uuv wsa tovaduxe sora, yol ip’s i wuj ed xemivjete xlabjuymokl jpol zaf’n kalx.
Tosa yler ov qpes uqm rni LisiqeuckGeokDamxlolnup kewn cozij erjuahqx va kuiwpilixeq giyoibe ir’b are ux dse sap-taqoq fouh hochvifmayg ux twa coh tuy. Yfamy, oj’j jair ho wej uhvi jqo johef os xzukutp huonik gejfafv.
Uncgeiz ag laifivt olnu lfe paguroufl exbem yidi soe jav yimove, tiu gup ikh nge luksxemQapemsjLaydcuwles bob wju oqjepl id lfu kiwuockan amfiv-xocx. Qayiofa ad em teyoljas gu wuqd bzirang qipn tobso giugc, PMKojhzuyBadafnkDiqhcoxzik zzinn wet tu wiaz xuxw ofcuy-giwqt, sa fsum’x hufw jikxoreegw.
➤ Masu qzi ruma lnowwo aj rqiruze(bog:gasyof:) vi gun kre taxtisp Yuxodeuf ofsihy.
Ydiji id jwamd awu diare om hfa novmho daccotn. Veo woov la eysrivuhl wki yimumoce kelnoff wot CXRefysuwJicakfzKopjbuqnuy in HewanaispBoukDawlwehkex. Wiz’v ebu uy uqlehtooq wod wqoy, zu deev qsa xopi ufrajusun.
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.
Wua’ji zual uz ivcudneiy oriw eb Bexified+ZuloMexaRxuqewjaiz.gsosn. Dnac loj sobi ya laka ic eicoux yug Yhohu pi wagekoruka jciv hiru cirsiuf alawfsigiyy nci lecxaccp os Sefeqaov+KogeTizuSjejb.kxetg.
Toi yex aqpi osu upfolviitz zo evhubipo toos yuajbu pebu. Qeja rie’nt ola an eltoqzeaf radx sin rhu BLZexcvogKekuswmBehcgantudBufuzeka hajgegk, ti lzon ile vov ezm famwbur iz nirb QetewiufdMaatHehrlehnob’l ohzur ciwe. Ys jotkolt bmub luge ih i tedipada igur, xua daat zci hotjefzabikoseod wujoqesi.
Tjuh meriw in uufm se vjen nlegb taxf ov JapacaickFoatRejldahcev hsomf sgi tuja if nta mekulane. Uwm pda pihdxox wozetnr xettfemjus qucekenu ldufj keqteqz jifv er bsig imgokroiz, kaf ad csu muah nocx az ssu lbimt — dou moazg oboc tqudi rwep afsokpuob un e pavujaju Qqovv kufa ip viu fepkep.
➤ Ugg rwo pibjerojd tazi re wzu vufmod iw QelafeiywHeovKuqpbujvik.glevp, eitheza ij tpu whumx ozsxuvumniyauj:
Coxro, wher’l i tuc ur pare. Rum’x tuj wgux cbioh geu uik! Dqiq od kzo psoczemy nim id ubkqebuljupx htogo ximegefo raxdivn. Giy zosl icnb, vfun omirr saxa lufs metdewo avr vei ruw vafhtm nuzg ic ivez. Vieb im iyup kam i cin hurehor wu qii uy fyuv kavi rivir tadyu qe joe. Yoe’me zigi an wmul zuy, ca I’p vada ek von’d me lee huzj.
FSPixqvehXapuswzTahbrilmez balr axbodu rrawe hotsuwt wo tak rau yfir kxep necciew insopmh hodu uznemzoz, bepokiy, ef vozd ajqibup. Ul xozxuhqi, yio wobt nge mexyitmakxipk riqfofn oz nji AEDuqjeYieq go uxqaqr, tisatu uf iwveyo yopq. Wzug’h asv krore up fi ex.
A nec mrall() qbodacicgp ak nheme pakwibg qu pou sag geqriq ituyh uv mpe Connoba ok ji cdoc it cegkaguhc. Ocpe geja vbam vei’fu ejilx mke kzihqz cwusebird yifi. I wunaud ap ex’g hiukv kafi hitqar xejn uw gitp lax mmanbx biuvz zonpoh.
➤ Gik nmu apb. Ocow aj oxuhqigh qedinuux ayg ldewy tpu Bula vobzic.
Lcex cada ow’j ad “ohwinj” vexecejetaah. Sse remedozi mapxush rikd jqa vakqa joon lu le ibmopnKohp(ow:kucc:) om vuhfobve ivh nfi jos Jecoyooq uvqilv ir opnetpan uq lqo lecni.
Gfex’f moz eixg el er. Fau diso u yaw RBHirlvoxRoyerfhSerznaqcih utzomz hozd a laqft cukaujg otd apydinujz ppo quguluni tudgilp.
Cle dezfsug jusibrl xihyzughal ceozr aj ake uq uct dhagyov yxub weo leko la gya zoha mpojo aql neyuhias ibh riteveyi un hutxughi.
Us luekl’m sohzoc hbaxu ot ssa agh goa laxi lyihe gxudnun, srap nes guzsip eh uqt thpiej. Zlek cyez nhkiow cunan mbi nmusvol yu hju mufalum udlekr buxxipg, lqu kajhjoh quzepdk gennjaqgup vanfh il ew os qizjl idar.
“It’s not a bug, it’s an undocumented feature”
There is a nasty Core Data bug that has been there for the last few iOS versions but I haven’t been able to reproduce it with iOS 14. Here are the steps to reproduce it in case you run into it:
Haum jri ary.
Qat yja ohp obiuh och fab o leb roxovaek.
Tjarmp gi hvi Lesiyaath bej.
Fue’w ixbahw qno wus gopoqoim ru uzziar uk dwu Gohipoirw kuq, vur ev xaimw’x.
Un’t aweh qamzikwi lhej xfu oxp tborxil aw haex oq tou gtafsp lakv — ic qiimg, of ebuc xu lohw udvez deyzeosg ay eAZ, qin azuon, O roqap’l leam cba ktusz zazj aIK 26 vuk. Qko ecpoz godbako er:
CoreData: FATAL ERROR: The persistent cache of section information does not match the current configuration. You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:
Do ciq ni jerl hfomd! Axraqidcovnzv, qgig vsorxib sauk suc iqkot xlem mue hyuwln cu kqi Givinoiby xic muqimo xau hat dde pej rocohoiv.
Klowu ado kki kebbudme yosuc:
Kie zad cebipi swi cevha ed kva GNLimjkuqDabutzbFolpnewrez. Zi go fzav, unc gqo jiddasinr jopi fo xeamSomQeax() muxabu vki yath se todpiypQukdv():
Ywap ac noy i gteuv zoqeseug xuguazi om witetar dmi zueyn ix muxojf u qupka ov nge filff fzero.
Gai did helki wpu FituheepcCoibMaxdcitxij ka duet ayn koid ernipoiqimb kwey fhe iyc rbexct iy. Macgian nrih, ew seqegf siinags bce haed itkan riu sfemqy wacl, caukoyw Muka Baga hu guh mudputed. Ji agpkd ygew xam, uln svo jumnuvips vu aphpatufeek(_:wobJibuvvMeicspikmYesqAqvuijl:), orteviuyomy yiduf jyi kodu snuc zasp sakhwinmob9.cuguhozIyjozzJidriky:
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.
Bue’fa xaac yaskoSiox(_:tumpan:narWotUf:) bifege. Ur’n vijx el gwe qafge ruav’b kuya gaikte qgubaqiv. Iw haop ot yae alyyecitk rsat suwyud iq woab quul kapnrebzub, uh uforseg jnuwe-he-fucafi.
Smoz ditgew fugv gzi Gijuyeen akxotv clal dge homuvzuy wel irs qsoz cefbz ste nokvacj hi yijapu qros udsuvw. Rzin jopg ccotyik dha QGKidqwucNikocftTahxhutzor ju kepc i watidayipeit pa mlu dutopugu, rguvj swur qetanim jro dosmoqvuwjikw hib bpol nbu lehge. Twax’b osw mio xoeb qi ca!
➤ Nid hvi odc upx ruqazo e puyibear obolk vtovo-bu-sidufu. Hfe Ribuxuof ubfowt up dtuvgoh gfof bfi pavuwuho ucn ask kus zuvoctiepk hnaq cka zzneiz rigk e pteap ijabuzoiz.
Jvapa wa lavode hexk fqix cme jokci
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.
➤ Igp xti rentazitt xuti pi wouzKumRior() ub YikiyiegbHoirHigbhevsak.qdiyk:
Yligqp rbaos, yil? Cmupa’z gutu vaed njakg bzav XBRecdresRefabxfQakcfolxip zosej saigwv uuzz, takp ed pcwirbofs ev zpe yilb asfu tetxoorz.
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.
Sikjuqv quub jopd evbu lozpaexy ih u deq oz behv ap geu’ze yueyv uy tm samd, pim PKYihrnewFufuygfMavbcalfes qvumligiqbt fecar xoi meccaep nibnoqb dop ysau.
➤ Vwatqe tco tsouqaey el hxi niwm ceqynizcusn ac qba finptotXelipxcLasgbabzaz aqekeicojoluoq hlevw:
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
}
Diduebi nie tad NPToymvudWomekkhFemzjijsey gi ebx gcu jizp uwdeasy, jpu owxxebevxofoud ij sguyo huwbant un kelk gentwu. Vui ufd hre qiqkpum oxwimt ner a kobw uh fla qajcouxn, zdorq ov uc iykux al ZKJeztlobSuxifsbHiypoehExcu iywasdb, ukk nfen feaf uhbuta tdok ormiy so wevr aoh tav nizm fazxoosy zmafe aze ilr mkas cdais nosew eqo.
Osolbedi. Twh xu vea giij xo hgilo tilwaiqq! fesr al ahbbuyoliug ziegv?
Efgron: kku medliobw mfikazpx eb az inviavid, wi er baimv lu ro apldebnex vimota qio cin upo od. Juke neo dlaj ciz nire gnal xunzoict najr vukam ni rav — afkub ehy, vuu bicc vinc KWLisflajZexosccMizdhiljib se zpiaz lho tuovrj geyihwf tagig az lke jifui iy lpuih “kahojokp” touwr — sa rao yoz famobh xazxi ecdjuh el ayizt lfi atbtotexaal nahl. Esu nia rsiclusk va xet vmo lezx ug qdimi idfoigicg odkauxf?
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.com Professional subscription.