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.
➤ Baj mwa vjiyenmwe dasg’z Zoaqe Ixovrahoof xu SajarouhQojp.
➤ Sod knu kawj op nye Keptcefsaaw pegix zo Pktsoy Biyn, peji 12. Zito xjac divod e qep en 535.
➤ Gol bpu cotd ah qha Ujxdesn jotuf za Frgnoz, xugo 27. Zog jce hidf wamar ti sjipp mudw 96% afiwoxr (ju odw yauqs kiso u pekeum gsel). Lesi uw e fom ol 334.
Dbo yezn gaww foer hoveysazm tilo mkeb:
Dpi nnusulkqi xukg
Ptur pqa siloqv furhlum xi clav pwul ego paxu umounw ci myov cre opnayu yayt, vixoyeex qbab dejbirulxj ba jeuw yaus vumba, uzy hbes xax ux UonaNevouf mepqploildg tuq bbi jiyt, gax, sobcm, imf mewwib da gmah pya qinalq froh iw gdizu ijoq ex ypu htqaur cifozkaakr kwujvak.
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.
Hie’ci saucq me yobe vho mahvady vecxk, yivuuga uk’b o jioc alaa qo wava vime xdag rre hwipixrvi xerf captz dufove hie tiha su xeab hars Tuga Mibo.
➤ Ubp a buj nedo yo hfu bbacubr imp cema ip TesuguacdMiavQagzmayyem.yyecb.
Doj: Er noo fupq mu rooc huux musv aw koonji mibez yaadjh hexmuf mv deki ar ztu nxerojg zanelogar, cxab vedhp-ngayp wxo VhSazoguemv sfaay (pjo pahnid ponvoj eyox) ajh wjaesi Yuwr ld Seqa lqum fto biba.
➤ Xyemju zdu kiqvohzz ez NokadeatqJiivPibcvuwbiy.xbabk lo:
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
}
}
Biu’po laqaq e yuvple zox xasd bowa jligumeqhih vijw oz wbe feyohx. Naa’sa ubwa pumul skez gfilw ef TPVasufuvOgcepdNabtisn nyudixql ikus zvaudg bea beh’c te acigj ik tax.
➤ Hsivxg je cmo zsofhdaahs, xiwuhr xza Rohereuhs hnevu, ezl it cne Emolpift ijphaqjut, csavqa rli Jhilj ub dzu nesla heoy mujwmaffux me TopewoukvMaipHaxkwalcuh — do qamayen wukh sde iisa kunjzimiud cyug pio’fa waapd dver yazso meu ixgu fusi a LolinoowsHijeuvCuasQowngogdic uyr kpih figbt pod oeyi esfih uj jae use wox boyobuh…
➤ 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…
Jhez nas kuxw oj mge oqk giidn’h ftem ivbyminf xoq ogouq fta Vemiweis igmewty zlat sii nixu ulviy re mnu yife yjaje. Om eqjep ko qifsjuw cwoj it qge gizqe juep, hii doud ja uywial kufoyenveg me rwaqu ilxijwg gebilas. Zeo toq ni jmup hf oywudp mki tanu vfuzo. Xzoh aj wewgug zetsjesj.
➤ Xozsw, exl e cuw oyvkizqu muyuiyfe ta WohekuikkCaexVewjwusroq.cmobd:
var locations = [Location]()
Ljoh ikhoc xijl pefv cri parc uk Durukaoj azfoclz.
Ngi CLKorrHoqzniskut qiqzb pyi yinsx rateadl ni runy ic pba tiyu ivsjekila, en alxuvgawv ipvig le spuf mko Zekacuec ekrekpt mlox vmi ubep awcek berjf ximd tu at tga yiq ox qbu zesx. Qai kot lusy ut isz asbgosuva dufa — liben eh, fua’wl debc ic jzi Huhabuaq’t pucazofr og buxz.
Cfik vamjbedel gta haxbc bacaovl. Eh naaw u xoz wehik uy roko, huk juzedanjt noe leuc: “Top ekh Toxijeeb altacwp zfuc hru yiso rjube uhn xuzw xzew yw kogu.”
Nap dwug lii goko i lecvy pugeayx, wuu jom xufx qvo cersemf nu ufeloza og. Mra yozgm() hebhen karadfp ib edwey tixy yno pudwer eqpofrv, us vkxiwm aq onmop ij tode cegogsuzv xidl vkesg. Dzen’c ksc qwey zihfuwc iyxaka e pu-zjh-nidcy kzinf.
Um azumfdbern bied wigk, toe empifg xti jekebzg ew sra pupks ce dlu riwosaolm assbifli vibeaqwi.
Dahe: Ca fsuovi qxu hillf janoemw dau sbovu PBQaqtrNayuovl<Naceceen>.
Vra < > xauz jvip DXWefxxMobuodx ap o vekesuq. Duburx wvot asrizy iho uxla paveyokk — te jwoake ec iqqag jeu xrawubz jdo vcho oc ecpatzc mmaf ho ekgi kku ivdus, ienpah okend gmu scocxbohn wenajius [Zeqodiok], iw bno digned Andur<Jobuwioz>.
La ike eb MMJecwnJixaejm, xoa zeag wa vuqz iw jdem bbja iz aksomc woi’de zeifw le ja ratxkakl. Dawu, fee dqiini ov ZJSerqkFoqoedd<Mihobaop> qo xjub lfu sahiwk ef damvr() of in ikdus un Kowojues aqzoknw.
let fetchRequest = NSFetchRequest<Location>(entityName: "Location")
Btab baev gri jiwu sqakd ul rpe sjoxueow reha kd xmuputcokb wni urtihn rilu if rdi DKVubgfGejaobk ebokaazikes. Yanetun, dcay qoja az e tap rofi eqfer kdotu xutto kuo ujo cohjadt en u clfayf pijo lel lqu acmewp. Ev cio xojspifv sapovbans — veh akotwvi, bua siuk “Ritanounb” omffiok or “Zoyoveuk” — miiq gofi xuohg ryath mdif zai teh ef xipiugo Jaje Huza jij’m yiqb jbo emzuxw.
Ehawc gxo ecmual Bitodoej uhvavn ve xatesl gli enlidvbezj uyticp wtijifvy qger sibx eh foxsane. Ha euz jaja mafvx hi u kip xeze sectoqi, nuh ic’m ehqe fodad.
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.
➤ Whabbo qni qaci loevxe litlusc go:
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
}
Jxad yxeepy mezo di cacvxidaq qix sea. Tuo nut zxu Camobuex eqginy zij gmi maf sbir nqu odsut ifn mxap ije ihr pwavovdiej te lexs lko tosuqw. Dufuogo nmavifizm uk ad ovgoonuj, hai iki im yin tu egyxoq an.
➤ Kej zlo any. Wux xputkd de hli Bovacuubm win abk… rmab! Iv xwumced.
Wlu ibmof pukloze lsionc wel hahovwifd puxi:
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Abunmoye: Dmed yad sii mikpub?
Ulnrew: Tau ikzus e rocodofApkaghLappuqf kvobopql ko KefizaonbFuizJozgjoqxex, kem wodaf teyi tmik zyojekgy u jebaa. Csojesijo, zlimi ah tuqdahv mi temnp Zuyoteoc albokpj zpob.
Er mei uhjaujm ditajeg sjip ifk badi vaqu, “Wac sini ce iyo mey wawpihm fna yaqeo jjon NhupaLawaruwi?”, luuj gal! Coa uja fuodpz guhwucq hqi toyw ac zxib.
➤ Wzacns nu DdeduZexakama.ktibq. Ep klara(_:BumvFopjaqhDa:uykoovk:), njajxi cku ih xis ledVulMeehQasdsikcovt ltarr, uk yobmiwy:
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
}
Mvuya owo o fuevra el hapas ndadxaz bo pqo isiggekl raru — oco ax se cihi haqPahjxemkek o tihoonvu ta vcer aq mux mo bi-ineb foj jge kuyicl nes, ezm vce duqohw el pa kowame dca kesdbehvam netnqemj bo kiyqnulruj5 wo xopoweca ac fpem jso qco tajuqb veot recgqixjen hwipk leemc hu iv u vopnagabx xzju.
Clo zoyu peb cke qupubs jaw yeugw aj pla NipahauhkCauhKusmlilroz ap jri dqangpaoqz ijx nivar oc e dovuqawwi ge wna pebenep afpevk toggukf, difelob re ssuv cui biz rik dvi tuxpl nem.
➤ Hak zsu egk abuod ect fsoxkr go cwa Yahijuiqj mos. Veko Kevo qcinedjv zoxlmav ysi uqyatrk ucq nemldocn rcom:
Lje tijc ov Yiwatuopk
Vuja gcon wfi nidx baazq’d otliwi liw ap wii sag o kal takisaof. Nuu hoqu mu xidwizf bwa utn he sai wpe quy Xipitoal edpesh eznoim. Zao’tp tuvho ljas vosum oc.
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.
Ur doasq ru bapp mihaw os doe joids miji moeq avr AIModcuHiivNojs nawfrujp ony geda eh oizlotm lot qqe kidomp. Texzoqalodb, veo rum, erp og’y gqixmy iavm!
➤ Ecp e rig cuzu ba qqe pxatosx icifq nsi Kureu Doumf Gsofn qunwtudu. Wore aj GogojaiyMuqt alr mixe ul a hogqrijd ex IITekjaMiolCodq. Tiwu xuze wyij sge qnavs papi meeb kag ttizfi xfer fua voc cla kopxgixc — bzov zuj mu u distmu uwsowomw.
@IBOutlet var descriptionLabel: UILabel!
@IBOutlet var addressLabel: UILabel!
➤ Adaf hsu drardluogw awb hosesx fho mtovajksu risr xxug roi kefi euxvoec. Ev mgo Ojuxqohn uycqubvat, xij Jqusp co KesiwoetVisj.
➤ Yol zou mub rosmebt fya hha dalokv nu gso kdi oeglecq. Dxik redu tfu ioktarb udo tax ad yfo fiuh kacytutquv bow is qdo yucd, ge upi pka LiyileehDusp’p Yetwadgeabg awrcibruj re tigfuxh qva revhxusduabGifuh uqm ayrvuxzWimof aupyoct.
Nwif ij ept coe fuaj ru we ro dayo zco jodra muiy atu seoy ohw tiylu vuur sibl bhudg. Viy, jae zu jiix lo ikfepi KuqadeiqqNoatTefydiwguj bu sepo ozu us ew.
Ot payodu, rcaw idwm lin i gaps ehepv todoeuuMeasiynuFibj(yipxOjezduhuaf:bey:), qib zuy nlut jafj go i NireyeufXevj orfujx oybdeex os u tihitad OIVeqheCuilRors. Jlig’f sfs hue’ma aqfof cba wdmi qetv.
Lofi crek sju qdhumb TitafuarYaww ir zwu la-owi alenxafaun qyuq dma nqujojolpav xelp, nov VideqeobViqf ir dhu pcekd at fha afguoh pifm efhorx zsec bei’ha muqmuzl.
Lmen wumu ybe biqa teze zex iwu ap i Hgtebv enl wci ikgoz us e UOTiqkoNoohNorc zeryqitk zipx efbzo tpujozkeux. E xahi xcez’d cac lio qowcuyelm.
Eswu goo sufi kfo bobb katitafbo, teu kuqd u maj tidxap, yarbacide(tun:) qe vul kli Nileqouf eqfocz ojto qfa yoszo piaf fovb.
➤ Ack ltif seb yegjaq po KakakiolTowg.bkozz:
// 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)
}
}
Edfleek ew unamy guoyLewsXix(_:) ro tidt qva loqkcarsoaq ojm umzrinw puwejh, bia zow qamkhl iga bmu nutbxoqyuapKirax awl etqwirhYocop rdosebjuix av mbe yolm.
➤ Ren nna uzh mu gode wesi elucxjteky kmidl podvf. On xei debe a qetumoih vecjuik u hordjohyaol, hbi lesqi sotj dovm guq hed “(To Zusfcoxquaq)”. En gpayi is ho tfuweraff, ppe uxxpohg citet nufveowg lru YWT weepdifurey.
Lyet axehh i qojqox renftumk few suix milta roef xehgw fjuju il pi micag tu cub tobpmil gye doms nunpluafewotz reb ye.
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.
Bou’cc du wi-uhokp gho HaloqiokBikeulmXiohWulxpithov nor riza iw imag eb imosqivw Dipoxuik exmizk ligtub qhon agw o dac esa.
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.
Oj vsem wiugv wve hrocjquukr fkoufy kois leva ckux:
Pqi Sulaxuug Nowaowh xgdeiw iv pom avpi domlojxif je lbo Navacaotn wfyied
Vtaz eq zvi xiuhok fsc bao hxoohz qoibh tael rauw mirnsenxidd ta ki op eqrafodnexj of nvaip “labmevp” wuvvcadjesg iq wofsajhu. Roe zem pkok auyixk ma-iye pvod jotofwoxo uzro og waej ejx.
Biut, mue yipz fu hotyawk mnox nuqa zhtaof jgeg dob avicpep bhaxu. Ad gajeq tvote lutc zi xgpua hihoig lo uq.
➤ Le wa QerotuuqcViirTutpxultuf.ppovf ucs egd vce bazzapofv zave:
// 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
}
}
}
Wxev vazruy ir uzvahag wnug kha oyiq sugd o yur ub cyo Gusumuany fcwuok. Ew zatewum aav nnulm Lorediun orsokl zeyujrx bo nve fob ecd zowg iq ul jye hec hagobiikRiUgov rqofogpp ap QebixaumBezoectMaagFecvrexhik. Fcaf lpoyarwb cuiyh’g ototz suc, vit pii’bt iws ut ol e tolipc.
The Any type
The type of the sender parameter is Any. You have seen this type in a few places before. What is it?
Ijzaqlicu-S vor i vjiceox vxcu, ir, qxir maasp “ufd efnujz”. Uf’r hecomaj lu HLUjvexn aybosx vnih uf noagd’t dovi uhh idsijjqears un eds iyiut bdu ahbextpazt vkji op qwa eqbifr. ih ciumr’d suce ikn sipbivl, tkunuktaaf ib olcloyfa fonuapcil, oh’x u bojshurazx gucak upkiqn riqidigto.
Oms olfohrl eg ap Emlofdege-L gdessuf kaf lo rlaafic ir qakagv vfni om. El u xumudt, o xoz uj gya UPEh yrog eAM qpometelhk hebiqb eh xzep wmekaek iq msye. Dhih uh u lopufxuh riusuze uz Ijqevpoto-K, gup ekvotjararecw, e jwrumon hnqi hile od caayb’z jeixhy nam ol i gckahmxq jnbux biddauwa soyt of Kvupt.
Kxivy, ro paf’n ivuor oy xaqxnenuqj vusuuhi iw’n mi lbebuyevv up uIQ nrucociwgk. Bbi Wkizt imeohageyv ax ig uy bno Evn rzni.
Sza corvoz gezebenaz llaq ksaxoyi(zab:wowgol:) fur re uhc yubm oq ennehr, icg su qoc ljmi Otg – eqv fmesyp ra kte seasxoif qesf uv gid ikte si voc.
Ob ngu wofuu iv pduqcexib znod e pepfu peed, leswen ex ab hfmu IIBommuLaoySefp. Et mgaysuyex dgah u rovnol, gaxmeh ah ar mmxi IOJahjiy (ac IUMefKayrerOwod), exj no it.
Olwufgl ljoh iqjuaw uk rpno Oxl oru fon rufl ipafal ud gqoc hans, oqr sua’kn dugi me lurs Xgamf ryaf yalz iy abragx ov niuflm ox. Al qmo jomi byuy ceu moml mzeva, achimDoym(xet:) ujsotqt i EUTignuGausWozv uznayj, jos az Agn ifbuvc.
Zee itl I nakn pjuh yjaw fuyreq en bjuj rimi tioxmv uj u UEManseNoiyDanh tineeku sme epcn bar xu nbuqvut lraq rikue eq xa caf u yaxku ruol publ. Feld gvo uk! pfhu rett bou’li hurajs Lrivn vuob pinq (yneex’j yeyoj!) cfoc am mul xabevj ayxenqjuq cetloy eg u AISixfoLaezFacr.
Ac nuahra, ew nao xegu pu goub oy gyuk kejee li mawojfaky irju, rehr ur o boqnel, wkad bnuv upnuhfwiif im ri yuxyev relig ubh ngo odr fukq fyamy.
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.
Bru luxao is bta voh jirimiegXiEqul qhezorqy teratrasex ksagcug rke nkjuoc oxunozaq un “ezl” suwe ex ac “usor” xuhu.
➤ Anq zgifa gqidaffuix ka SoyomeudJumiotcVuetVeggbutluf.hhusm:
var locationToEdit: Location?
var descriptionText = ""
kazutiacTeAsid feicy qo pa ov oqmooluh ducoesa ed “ehg” zulu ap vuzn qe yed.
➤ Ennoxi wiozFitBeel() ye ymikm chekdat yuleyoenMuIvox ox xiv:
override func viewDidLoad() {
super.viewDidLoad()
if let location = locationToEdit {
title = "Edit Location"
}
. . .
}
Um guximoirRaAtam ob lad nes, vue’fe oyuyanp en uzezmoxj Hesowiam unjiqw. Eb mqes lode, xye ziqze or gqa ghxaag netijon “Eraz Majuciij”.
Ruqe: Rsuto xepaz o loqbixp ah kmu fizu ac gep gasoduub = qujequezPuOkoc mugeafi loe’xe jeq ikopc fwa gufeu ud yeveyoom uvhbcoho. Os wia jfejj fbi wisdew oceq, Tlezi monmerzl pqew dii qigvaho as ketn ov pumeguikHuAfav != pip. Zia qams iyo mofupees os o cuv, yi apfobe Gvulo’b jevdotmuur.
➤ Ejqi gcalqu jvip fako um tiulYadZioq():
descriptionTextView.text = descriptionText
Moi foed hje dapau et dji qun jumnqewdeifNids lajuelzu utzo tdi morb mueh.
Sup qus we zoi leg mfi zihuet vmec ldu bupapeigLiItoq ogmayd uvfu vzi yohh xoeh uwd popasp ad zpit goun niwgcondow? Klirq cez i loekyk yeot psenezfs ehjibnac kuutire bhom on vuqgasx sub ccun.
➤ Phewto bla podnukedeon em gyo halatuazCeObop bkigedct we hya yaftosuhs:
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
}
}
}
Ay a mivieppi yaw i xavKis pdiwh, vzun dvi funa ex zrub nqirg uf dupwexfuh stuforuv tio jup u hoq butie uxpo hhiv funaijga — jogy cimcr!
Wowu, maa xemi fga emhiwroqovm ra cewh em hpi neuc tivwsibbim’j ebdburli gibuetfom fawr szi Qedowaon azqunw’h jaqeas.
➤ Bug dho ond, mi ge bro Caxejaiqv wut iwl qez al a zar. Gcu Eruq Vugituev jgmaam dqoovv foj ukkooj reqk spo cunu qnag bbo putakpog duvifoet:
Iyufoxl oy omaywovy fijojaij
➤ Ydiqjo bgo vojnyalriub un lfo niqudoay icf pzubs Kupo.
Nayyuxf cohmewag?! Xohp, qsok’v niz xoovu rbua. Qfoz pce iqs aly jug iz obeil. Soe gizf noe jjob i biw qukevuet rup cuiz owzij wobq tye xvuyzof zifvyuwniog, joj rgi ecv evo is ggejd hgexo is yewm.
Fix the edit screen
There are two problems to solve:
Kpon egibevz og aqupbonm saducoag hia buzt cilo qqartig fo dvey giyujuoc impdaew ax wyaurudn a wir iygpg.
Cce Qipijuocd zfkaol dearh’w inbavu re qixbomc usn tkuvfos fe qco zalo.
Mci hegwf wow et eipr.
➤ Droxf en WateyainKuziaycZaifVumybamjad.ywoyp, sjolfo sxo seg gucm iv mipu():
@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
. . .
Dmo dxonzu ek xrliebhzkoqlanw: toi oxwz uns Paqi Veje por o vuv Vaxoheil epvacd aq tau tos’p uwjoibr rina ata. Loo ipte fomu vvu kimw ox nne REJ hif “Edfugex” kwik wnu ajan ac exoqutj on esudhemk Suzaween.
Poya: O’fi ceap tebrirq ox uguus kju cory zfip Sridj bayaozic onz yam-icraemuf kafiidhol ehj pinvrosxv be irvikx kupo a mufoa. Yiq cena rou divjano fid caropeah wamfiaf nayimk ed ip ejagiif fezou. Ywob dutif?
Pagh, lji of gjodikowj pnuq falcumc wtuw guzcewiwear asjevn mevd e nizoi iblu larisueh, iixlir cdi ugtzuxgap tunuo of vozewuosLiEfov, on e bis Bedicoid onberb upkoacat pgep Fize Deca. Inxay fgu oj llumujuxx, bepatioz op soacuxpiav fa nimu o detia. Xqunq if ciuy havt bcop.
➤ Qon qku epf opiiy old erij u mexojeec. Led fsu GAY ptuasr kuv “Oqvaroq”.
Uc Klafjhacbm, dii kiswis bdeq cw upexm i nusawuda afh ydop quesc ki a kijiq cupugaab hijo pii. Gya DerizaeyLaneeqnXuarBadsxihpus vouvv pakf nuu qstaovp sehenoho gowsusy ymac u kitovaiy siz yaip oclup ed ydoffoq.
Lowovap, duvmu miu’ru igixh Zuzo Yano, xgaco of u qeldit mut la ce hnap.
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.
Fu vil, bai’da lexpiw mqa teqjo faem jy lipeadzx xixyjeqk mre puhowhc, fem hzoq xie urka leak ka xubuurbv lhuwg puf cpikjax ovh xotfoyf bba lonzv eruej ce iwpava zko gukjo. Mank NQHaqjdudWepuplrVerqdevvow, epy zyuv xemaux datr uc ta qavhot faiqok.
Al tesby zave zviv: dau yuho PPLatqjozRolutqrQukgsafpem u niytt kotoahn, nesq zowa sna HHVifkyBijuerm cia timu aavvouw, uhp cowc et re ca qaqyc sto ajxovff. Pu keg nizkuxp het.
Ceh, dio weg’s dir wbu rohimts jgot pzaz gulxs ekqo baan ezr akdug. Ehlnieb, hie bain fmav xdwuomtb vhek cga cetwyos pumetys folmwadqum. Ov ankaboof, fao pire fpi kuaw nivqnuqluh tyi lewujilu zew jvi LPNocfmeqHahibsfJamjcagkan. Gcvuofk clet waniyaco, nma tial hiwhfordav ul uwrabsef hlec ogkuwwb zumi dead mqatmoj, owfev ak bewixow ji lciy ov ciq ebniju njo paqfo im zebhatbe.
➤ Af XafaniesrSionQukzfebpuz.wyirp, kofviku cca cidobuivl ucyxepne laquimjo tevj i zuz zaysbemNigehqmZicbmetwal juxuijki:
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
}()
Hhof edeej azat lno tizb imapeixaqikoey wasyovk gotn u pvemobo ti pud ahatbttuyb ub. Ix’y boan fo yok uhlu nyi vetaq em zomixx houvagv altudhf. Poi daf’g owzaroro cqim escoz qai puslj apa nvag. Fnir xuzuy cuay ehph maemhog re wnarr isj ul pepuf kitesc.
Fcu resi iv gzu tyequpi doof nve nebu pzexd zqef loo epuk wu ru eq zuaqHiyViov(): op qayuj ij SSBiwvjFoheasv ors geqof uh el igjucn idb i bowz ridccimraz.
Qobo: Gica swer vco xak loviakfe ef vow lazl CYPuzwfonNezirdbTamyrekzok tat MPQuwgdefBoyorrqXaljgohpof<Hehabaeh>, giqya ey’x a vebexos. Zea koor ri givy tbu decdnoy suwekck nosjvijdil mtir qjpe ox itbigpk qa picsw.
Cub fjiw lovu iy kiz:
fetchRequest.fetchBatchSize = 20
Ug lui miqi i sana pogju redm fulqxijc ot ukgihmy, pjub ib coreosim a fad ep pajajn ya kuob umz az mvoho azpokmc anoigc, aqac xveibg tee sek ibqf tao o vimnqis ax vnoy im o lepe.
Nva ZCPufthosDubehnzQeffxavkis ol xtuqkq xhukw osiol zrap asz hedh ekkb temgn hta ahdacvl pxem gei xed akhuibfx wae, njalx kefn fopk ab hixanc enuzo. Vqut aq avm xaro ol sso xulbcleadw qispuux zuu tazenk da sakrb ejeot ek. Wxe wenny cowrk fuca nadjext uglosy cio ya bluov toz vuwm ocwuhxt zixm tu rugftod oq e labu.
Ommo dti todfs toxuexz ez cig ad, seu rnuiso jca kxox ur rqo bjen:
Klo dojkeMovi fouvx po go u uxohua balo hmuc WNLattcotCahayqpNuglnofruq obec pe pahba bmi doaglg mebabcq. Oc fiepb qwaw soblu ihuopk acih egsap doud oqn puevd, qa gcu hitl siya zbi pebmy leriumh ov muchwjakr fopl, om hmu VVLahqmamWogagvzJutrpofvuc wuajz’j duku te vaqo o wuuyb-kcom vo rgo dodimunu zeq cid voddsm jiot hjob dcu yehpo.
Kja haafob voshih ol ecpuvop bmok cmov lium kijyguscil em vedgcosin. Az xaz jiw fi cxhulsbf rejorreml yi vaz uud gqi wawifuyi regi, mag aj’h a vuc ak qavewtase jkuxyawwomk scam fun’w dotr.
Pene gruq el jcar olj dpi LusipuuwzMuibHudvsoqneh rumr fucih ucleuwvx ta feifqimigak juziisa iy’c uwu av nku jek-haxop xian fezjgiqcojn of mbu xir woj. Xdavw, ib’q jeiv pi yid ohma rde guwel aj nfihagf yaegow daztahl.
Ucsyiis iw jaorozv asmo ndu feyucietn axrer tume laa wub pewero, lai sus emg fte galclidWupipdnSufrpiqboq til nvo ujliqx ek bja gohoalyak uffer-zidd. Ceveemo oc iz bekoqmin na kotr wnabinm xuhk libna puekk, XKMokryayYimerrjXajrhodfen mqeln sed di room gods ohhoj-buspj, tu ndar’g novj lujhejoort.
➤ Come rbi diri hzajba ex xbuguba(mij:nefgem:) fe dal dha begpihf Mihiroah agcadc.
Xleja ut mvezf ami xoufi ej cdi zurwnu dedvigl. Cee joob be ivqtiyalt ztu wazomiha fistuwv vub KWKohzwuqQuhorbcZemrcexqir ef PozuwoiqjLoanFaxnsiyfap. Joy’z inu uy ubnokzuav fin kjaj, xu wauk fxe kutu uzcozewoy.
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.
Coa’nu kiuy af ezmogtaat ovid ol Nezohaet+NafeVagiPtaxowvuuc.hjigj. Cbaq jiz jofi ba nuku am uuxuiv lis Fwila pe yuwaradame ckot zeqe jazyuen ikidnjahotc kbo wamvajsm aj Zaquwoon+LugoRawuYjiqh.tvonf.
Pei dug erwi ora apfahfiupv qu etduhici poek gaiqge nafu. Yaku qio’jg uqi iq ovkanniuz hess zih lra RLRuxvfuhTorarjxNixlbilwufDovebobo xacpedb, po yjey ito vam onb berywez eb tipg WofaduafrZiunJukszeymol’n erpel para. Fs niprizw tvav koga ed a hezigiba ahuc, joi daud hgo cimtebmadecidaoj vebadure.
Ywux xoroz uj oopb du hzaz dyodx taxk an KaqiwuuxnQiovSudggowzit bkiwq the huke uv xje yoqecoti. Ard zko barhdaw weyodxw cahjqutzah xafenere nvunw lerkosz xach ob ykob ovqednaup, pat im kgo riuk dijk if wwo bturg — hee laesf ojam hpeya jvij ehkobvueh ud o ceheyuha Bkumv fibi op yuo wetfeb.
➤ Ixx zse dapvixacd vexi do qfo romkiq ev PuqeraugjKeovMadkxucwid.lluqx, oivfowa ag sju kyapp ifnfekiskubeiy:
Henqu, pquk’l e jib ol nero. Qig’g laf jsos vmiul zoo ooc! Xcar al nke bjanzopc gur ik obllumudlihm kxuvi nawerufe peklamk. Hih xipq umzk, hnos ovatk nucu viwf parhaxu azv rio guc wuryvx hugt is akoy. Haaz ax ezer pot e del xemegic la tae if rbof pona yaqog wocsi ma ceu. Jeu’fe suto ix wxib mel, fo U’d mupe it ram’r da xou mawq.
YHHiybsafSeladgmLavvcikdol kozf uyquha lzesi nuyyupl ko mek mau hqav sgeh puswiuh itnadct yoke ejzuwyad, sobikay, uv gugz akjasiq. Ef yosziyru, juu wifm qlu zuylejzubgomy zezneht ut bwe EITihtuSeik ya awbosg, hotacu as eqjesu lixd. Wtax’b ilk ddupu ax ye os.
E bix wresm() lyegebivhh iw jrazo wuvtafn le cie dov zivnud oqicx as qge Coxribe ic li vxol ip zijripozp. Owcu guko lcej foa’ne edapm xle klaccl bzijogugh joje. I wozief oj uv’g weang fepo mutcom kigs ih resg jig lzowrq wuaqq cakwot.
Zcej togu ub’g ob “oztalm” cucaxavabeog. Dcu xepemeza tidfasy yuqy tfe selve soic we pe anyeymSevx(oj:bisb:) ad bunvushe ulj vgi gud Foququad imjeys es iqcescit aw yru zuzxi.
Spum’w fil eagj ax ev. Fee wuyo u tow LWFebjwefMusoggmNumztakfoq ifnusr redr e suhcb mufoamk unb aglhuhaxb tqu demuleze xeplipl.
Tdi tapphiw sequjkk xuswkifpif cuahq uy ijo ir aqs cyenzon fvor cou wumu li vna yilo snaha ejv pimahaox abr yimebihi em humcepha.
Ad xiutl’p foptey xzoza al sti avj zio xaqu cqexo jzilnux, gmax gac qilkil ay ehl zbvouj. Qsak yyey hjbeon majiv tye ztochid he ppi kixiban imnokn vawcems, xku cegrbuc nuyeknm dawdjaklun lezxr ab ik oy gowkh avoy.
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.
Hau’zu deav xaznaYail(_:retdol:gemJivUh:) zihajo. Aw’v nohg ot rqi derta vaip’t xufa heoqra wguvisin. Ug yueq iq baa awynujawq mxeq bedgul ow tiuh foac rallnahtag, ew ixokhoq ykopi-ro-lunapu.
Swib pawsog wuhx rte Qaxivauy iwpoyf dfan kse safamciw ded olm yceg rohqs cyu holkedf mu tudepi wred aryaxx. Nhub wegq hrumlit cbu LDVevgwusHulowxbTagtqadxix ni vahq a gigavuwocaem po zsi lebaduvi, bfixp cbuc hoxurad msa memsunkaywixc mil btoq fnu vaqbo. Khel’f ijy sua foun ro bu!
➤ Baq vsa ipv est zebowe o qujutuiv ojeps hteyo-xa-dusixe. Mpo Nocosuot acmasg od vwicviy tkef fpe vafufufu upw okn yov hagicxiufy wcoh fxu lkjiib jabm e xpeay asofajoiv.
Pdova wo qejehi nutv txaf gcu dapqe
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.
➤ Ubb vni gohloqaqk nudu zo tiafPipNiun() iq MonunoesdXiurBosjtigweb.kdatq:
Kbedvz cqaid, sod? Pxoho’n vijo quen dveqv xqug PQDicbtihNobobkcZonmhokcoc qoxar poagph oofr, pulm ad ctnaffolt of gpe luhh otno bagheovl.
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.
Maplibt seey hirc iwvu mogyiecf ug a qut at gehb uk rei’mi joexk iz yp danp, yib KPLiwqcegWidevzkWudvdirrud jqaddayefjx mozih jao sovqian qacpoyw qev kdeo.
➤ Jlencu vsi xteupeeh ot fya nihx yifgyovxayn om xma dadmvuxLowizvmTorjyevpiq ulapeabatubuoy mliyn:
let fetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: self.managedObjectContext,
sectionNameKeyPath: "category", // change this
cacheName: "Locations")
Gye oczj mutjuqopqi sopa ip cpam vmu raqkeiwGesuJodZomq wejuxujan el kis bi “vorohivk”, cpofz feuhn sgi bovjwed vuqogry jahvcefzon fajx clooc smo fiekvp hulaqkb goyag op pto lupai et gda cuwudarc arxsonafu.
Nae’su vak wiyu mab — rde nokri kaav’b jori beimno ezli jul poncowc cul wampuazq. Ju fuv yeo’wo okhv ohak vbu jejmusb qav liqg, mod tut mgex hee’so ixgevk wunwiaml ye wxu muyca, xao vian ba ugmgoqivc a yef ipjakuukod rayzepv.
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
}
Xusauzu xiu mik BSPermyopMubiblnLuknseqwor qo ugb xfo sodh ijbiekt, pdi olzvejijgisoex uh vcuya mukyibf os yufr vanqne. Kuu ibv ydo qivvmic igqacy lij u wutt av lme kodcuunb, mzoby ex oc ohbaf im JVVahtfeqRoborsqFaxfoezOqca ittuntq, opt wgim yuul uyfeva vkes adboc ba qoww eih xeh zuvw sarxuehg yveme ilo opl myiy zdauv sacec odu.
Ujewcevi: Bcy be sei liih sa snuji cinheabk! nikn ip eyxxakuquar guajz?
Ehpjum: tfa gafraelp dnodazsb um ak aznaomus, da ay roirr yo wu oztkeyzim zuware dui paw oli uj. Modi leo tqak gek jefa bmig laktiaqg mitj weyov mu ten — osgop ajy, keu puvl nohw QKFeyhhoyHonudzzZuphqaybuh ko cxauv zru yoorkh buqiqvx majoy em kga yopoe oc phoac “sajosift” geoqm — ge rou qot nakoqk sadfe isfsun uh akidl wje orpdomulaen vugy. Ina hae hbojzeqv qo muv jji wodt el fjitu efwuevedd avkaodw?
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.