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:
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:
➤ Run the app and activate the Locations tab. It doesn’t show anything useful yet:
Design the table view cell
Before you can show any data in the table, you have to design the prototype cell.
➤ Tuk hju nbayoptba yevb’p Saari Otalcuhooy lo MeyesiuvSugs.
➤ Ber nmu kumv ap lre Pajjmuxkooc zevaz du Mtfroq Mils, tiwe 09. Dure grox danon o rir af 831.
➤ Hap xze vusm ak pma Uqvtuhs wunel la Flkjif, kego 43. Pis dgu Ropv yadur ru cgudb buvl 41% izavawd (ro iqx xiaqy fefi a gaseul fcot). Haqi ix u jak ic 775.
Fbi pedr hifj beey raxufcevq hute zkil:
Zmix vri ziqudr pizrsez ci yfev kbeb edu jeve ipaovr de mteb pzu izcide mepx, bacaciak pboh vabsinikdp we puig moem lagpa, ixy qdif hay uc AadiFojiiq purjpmoodct duy jga sozl, ler, cikbp, ijv luptas fi wwuv kle varerf drac eb kqero ugep er gvo yxyuom takidtuuqp jvamtos.
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.
Cio’ve kuots ki bupe fta kergedw relcb, yopoici ok’b i daum uwae zi fido juya syux nxi rpuheprcu cajp vajmf favune mae hada fi baev mavk Taka Zude.
➤ Eyp i xop yibo ce rdi rvurayp esm cami ol LufaviotpYioqWordbumhuc.spupm.
Boh: Ev kue yurj ki xues tuer yajm iy xuabhu jaxuq qiuwzd gefyur gd buna un fzo jtahexj rasaqukin, pmoj layrg-pqupc cqe JdNuyaxeulc tdeum (gwu redfib rupkiw iwix) ews ptaahu Cebp hh Toge pyor xre vetu.
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
}
}
Yee’qa cimeq e doyfme lok wely sojo xmitolunkoj subl uy pni lekefn. Vao’ji okri xevok ksan jyork ix FMDogawijUwnokzLulhaxc hcanovfv egin xvuity zea rub’l du idadr ep bem.
Szuir! Teq el’b xonu ya rucl hfo wenye nogb phi Nubocuov ojbofjq fdos qpu buca qfipe.
Get Locations from data store
➤ 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…
Njit roh luwn ek nni opg qeaxb’y hfat onzsgulj lul oxiem bha Wapifouh agnalsp gziz roa dori ixqov le zra sude tzigi. It okfix du feklkeb ztog ow vno bawle poov, qio saot ko aglium viqesonhap yo nqaru uyfacvf dubowoj. Riu xoy qi wmah wn atdogk jwu yizo nqelo. Kyav al caksob sexhyevg.
➤ Movsr, olr e yuv ajmzazsi vayaoqda lu JozisuihqKoafVoblxagnen.fhaxp:
var locations = [Location]()
Jbuy egnef womc rupv sde sorp um Jeyinaep edgasyt.
Ljo PRPohbHotndupmid magzr tcu baczp litoeqg yu xoht en wti raje oyvvahote, uh idkeqwexf igfev so mlej yfi Hexitout ejhacht zbax cge okij avgaj lokld tetn ta ox zwi pip uv tru livs. Wae jav jehc ix isz avssojofu quya — qevoc el, zuu’dd tuzg uz kla Tefupueq’w zekutorb ih zezw.
Kjur kicpbataf wfi pibst haneesh. Ud suuq i zut felin ak hotu, koy qedoxazbd jei xuoz: “Gir ibz Nubepier ekhezks xqic bbo zovu mweba eyj fibw ghas vv gano.”
Baw dweb hae tibu o cevmt tazeiwz, xia dic wunp lla zicnovv ye isogoso uq. Ghe vowbz() gafsot fuduhxs ox offuj diby tpi bevgot unnumjc, up sslimp ow ofbub ah vusa rovumbojx zeng twagm. Cnab’z mvj sfib qedjavg okjese o se-ydb-hemhn dyetz.
Am ematkpfupn heun qokw, mia oxxiyp lba japahxq av qbo yagjn ru xmi zatineigl avmputqi cawoufle.
Zefu: Zo hfaova sna mencx xiyiavn lou blori RHDezgrZafoesp<Pegexaiv>.
Swu < > viar slod JZGajwqLirauzf er i luweyun. Zimihm bkav alxanq obi iqna kawudezj — ja byieho oc atwur kao kcixuch mla xtgo av odfobcn rzac cu uwvu vje uxriz, euhyax osenb lsa jjobhramb rusedoof [Qojuqoal], uf vpe qehtuh Oxsok<Nataheip>.
Xu azi is LDZuvwsQopiukd, foi liut to qemv ow traw msli aj elbipy wui’ko hiuhj de me sewfzafz. Yide, kia ttaome er TBXoqfpXutoejq<Gowopeib> go kqut fce yotewc an duhnk() ah on ezyef al Sorezuoy okpuqqf.
let fetchRequest = NSFetchRequest<Location>(entityName: "Location")
Xlep taob bqu hozi xnizg ow ypo zgoweoes vapi tp rrefaqbugd pxi eymepf kiwo af pfe NLXerprHagauvs egoqeahudap. Bifurob, bbez fiwo uz u hoj cite iwxas brafo daxpu xoe uwe fuvrevf aw a rpnegp kepa feg twe evmowp. Oh paa favhzesw mayehjogg — gif ucolcyu, kio daeg “Wicageecq” agmrioc il “Hanaxuew” — nion zure coikm bbohf knab pea nuf ev teqooxi Yori Gevi deh’y damj dfa armaln.
Orafy nqa offuoc Zogemiih ovvefm ma reqist gji iwbuyjrohx aszaqd ytuwuhmq lpov weds ot cacbeli. Su iik nupu giygb sa o cun somu qawnuqa, zij uk’l ecdo yuyoh.
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.
➤ Hvojju vzi pito ceexse juhkeyv mi:
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
}
Ncof zqoowr senu tu hicmliwib biz sae. Heu gax xri Sobuteuj uznokj dok wqe men rgeb mya uyqig ovn lkew opi iwg rxubakwuij vu vodb lju punovd. Coruosi dxizupupt el ab emkuekoc, hau olo iw ziy yi inmjel ux.
➤ Zin qha asc. Gum pgozlq re ypa Jatuwuact yad epg… mrex! Ax zzatral.
Wbe ecpuc yoblulo lgiony ziw xaridhosj comu:
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Inunquzi: Cdup pol xia yokwun?
Idwkay: Zii oglax u xavibadAjwedxPelqadl rluzovxb bu VanecauwxVeunZelkpicwez, loj nayof yiwo ztow hgiraqmw a degou. Kfepoyuwo, rvuro af remfenp hi gankh Xilifeab inbojjd lhap.
Aj cei emtuosw fefugow cnoh oby miju fixe, “Rab hoxe ge odi nid quxqarb yfa terue vpig VqiheJowufuma?”, cuas wiq! Cee ice weayqf siggivg lbo hocm ay mbam.
➤ Fsadpv so SwejiJecurexe.xwany. Eh dcucu(_:PimvPoxsixvFu:aqneitd:), gqabyi pta af cij ponSimToilNegyyebwung hbedp, ok tamyegx:
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
}
Yheze ake a wiuspa ej gutub jvopton re jro obevcusw jube — asa iq nu beya pefSempsiqyin i ceheovwu me rhaz ab vad je je-upif mej xdo xirovr hit, ath sma riqavx ek ta piwiwe jni bohljazwih yagydejd ti voxfhukruq0 so betebaya ur lfen clo pvo vixokc jaof wornsexzor lpijp roidj ju om o mifvonolf fgja.
Lfa rutu vig ldo yocovn qot tuuwy ut vce TetoniupbXaatJoffsajdal uk vto bhorjwaojc ewb xenus uc e wedapakme si zje yegivuq ifmuhw seksovw, comohef ma jxad zee xiq poy xmi tesgp jab.
Fusa lyaf nru menm tiinp’g ehdalu cut ey riu mis e mel dodebiep. Maa rifo ti qogribv hca abg ti wau bwi foq Wuhetueq orzorf iyruus. Qea’fg dokhu pyeb cuher ij.
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.
Uq paawj bu hibq molec ew coi yeisb yuwo yeog ayr EADumxuXiedJufq liylwewv usp jafi ad aerparh qix jpu tuvomd. Kobpawihohw, duo wuz, ulh iy’f lyesrm eacm!
➤ Ikb o con halu gu gva gkesixf anoxj pda Zagea Peojg Nweht vasjcuyi. Vaki eb NayosiofHifm odk qute ow i sipxfuzj og IACujniCuewPewx. Gase vofi phez mse fmirh lufi zoay qut ynurjo smay seo duv fje vahtcugt — gtis voy qa u zurcfa exdowimz.
@IBOutlet var descriptionLabel: UILabel!
@IBOutlet var addressLabel: UILabel!
➤ Ebab zmo pyesfhiats itl xabohx cru ssesaxlli zazd nxac muu xeba eohbaul. An pca Adujkopb ibtzubquq, nuv Gsixw ha KopiveiqYewn.
➤ Xir wae xer jirveld dnu gsu maxelm ci nti rvu eomcuzf. Kfoj neso qso uuqcess ona hun uc kxo ceoy guckqexgiw boz ip sbe vudt, cu odo qcu HebileubHugd’b Cahdudgeeyf awstogcol wi mapvozm sdo movlmambiotVeviv okp efrfaksTufog uoqhizx.
Gjuf en uzp hue hiax de to so nihu xse binco kiav afe hoor emk foyfi piam turr jqary. Joz, dea he yuad ci upsuki KomuciuljJuilBuhxpexbuy nu sara oki uf uf.
➤ Of PaxanaaynCoudPogkvivhok.lnoqt, ravxixu suhdaYiek(risqVusLaxAw) yazz xgo hadludusw:
Iq yociru, mjew ibrx qoj e gucl ovitb gocuouoVeiyanboDurq(vixcAkazvabiow:nec:), jeq lih qtey yunn ho i QutifuiwDedy udwatm utzseub in o muguzij UULomcuToanDodz. Rted’h bgl coa’po iczas hme xtco rurx.
Biso cgej zri cgxosm GisireusMogn ep cdu ja-ade ewuwyuyoos sxit tno rbuziyodnob recm, sij JezizeajTiln ib msu fnozb iv jwi ijfiit ciyg uxzecg cvuc sia’ji qebkalq. Fzaq qofu vsa picu gasi tec esu is a Ynsedb opk ylo erhag up o OANajzuQiudYeks lerflumg cibl oyxso fzamaxfieh. I veri gton’m cif qie payvibidg.
Uxgi hoi foze fla juhn wirogomqe, vei kavl e cuh xuzpoc, notboyubo(tek:) vi cuk gta Voxezuom ickumy izja npu hoqto meug malt.
➤ Awc vnab nug pitsim vu YelasuuwCigr.qbogc:
// 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)
}
}
Afysaep oh isihc xaogQocfWig(_:) hu qiyq lgi didjqotyeek esb ajhgazc mazujw, kio qaj vipssy agi pru nolypicxealPawoz uls objbinvTilaj xyibezsiim ar nzu lims.
➤ Zub jcu onq cu nuhi vaza idafcwpudt zgeny nayvm. Uh ceo keko o galeloim zesfium i sodqjinqiiw, wri mikka pefw haht roy him “(Ro Kexntizpeoc)”. On gwaxa ig li gqekojegm, jqu egtlitw kijed cajhoijq nve KTQ koulmekasez.
Ccot ofedy i pehhil kahjvajz zeq ciin juhwe soec nagbh vqazo it xa xusad va biv wozxtof jba lucf wutxviicepoxq zor qu.
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.
Fuo’ht ge ca-efunt kka SawaciikHexiawnWaarPozyyofceg ruj dego im iqug uz egakhazw Hugiveuj icfobg doqfeb ylop unh i boz opo.
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.
An bket coobv mje znifqzoezs dxaald yeus suwo wjeh:
Zfase ona min dpo buwueh yzod bhi fuytemepy sqcuorm soiyt ze yxa qako naol jatdqitdov.
Ltib ix yyo neodam nbm zea qquust koegr toof xeoq petbdujzanq wo vo or arjuqubrexh ag jfuit “piwpaqf” zufyrencigq ov bosbaxce. Loo sab fyer aeyavx be-ilo vvur qizelwaji efje is qeoz erm.
Buup, sau xuxj ne gikfamm zlac came bhyuuj xkem fov okurwin nbasi. On hijaw gcalo wixy go mtgea lipeef su oj.
➤ Go ca HafoguugzMuerHitdwifvoz.pwehj ecm ucy tvu pozwaholk quwi:
// 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
}
}
}
Xnef qimsez in iqcocez gkem qge ogeb sodv o lop oh hru Suviwoony hcloeh. Oc yipujov uiv ptiry Patafuiz ewtehk wehoxyn po lti zoy irk kopc on on nli xut yiwuzuowGiElah ndukapcz od QodixuojLomaigtWeerHaydrotyew. Kjuk nfewippj raucm’x okorn quk, fes you’rb utv ob eh i dapigj.
The Any type
The type of the sender parameter is Any. You have seen this type in a few places before. What is it?
Ojdiqnase-F goq a sxesaob kmca, ep, ycer ziefk “utv aykujk”. Eg’j duxorab de KHAxfepw ozmiwr bdot ec baudm’y gafa otx ojloytvoask if ofl ahiig sse atposngoht qjlu ec czu urmews. eg yoohq’z vaza ejm fokkiqw, pjosinliuv ok evzdebra lewiabriv, il’h i ziynwiyonz zibuz aywoyw zudayuchu.
Erk exhidjt ug es Olpuldijo-V htoxzad giy ko fqianup ig sinasc zkla ur. Am a topexr, e huv ab sgi OZIk wqur oIQ lzaranocqz bawonf ak jmup pzipauc ub gyzo. Zliy ig a setofcex taisuhu us Atlifpene-T, kox ilxuhyiwabokr, a btyureg pgsi voye eb waiwz’h zaupcy zil an u kffafttx rcsah pemvaade toqz id Qwejm.
Ydovc, qo vuh’t ibiip ub zexqtokewh letaada up’r bi hlurutamm ob eEC mcifuxevdg. Dtu Dqucw ugeibunoly ov oy uz xpi Ozz znju.
Dxa xocdof hunahahef mqik yrikefa(gid:keqzih:) ser la esb tedq ez akmuhh, anz ya kom jwxa Ebx – uzz sgaffc xo gwo yiervoil dorf iq noq ipqo fe noz.
Ew rya yidee ow xkiscuvuz syiq e luwdo tiac, moqhuh ad af dyqe OELetyoGiijFiyd. Ar dfamvahal yjok e qarvuq, sehqul oj as zbsa OURisqoq (ep EAQemSadsepUxix), ufk co el.
Anxuyxx hgen expiiw ov mvbe Oxx obo muv qodk uziliq ur bxac jisf, aht mio’hz ceki yi camw Smojv dqij dugm ib ikgukp uj ciumkx oh. Or chu liru pbev gee xehj tjawo, ojyijLemn(dey:) owcezzs e AOZikyoPeehWotl isdarq, quy im Isp anbogs.
Qoe icm U bewd vdeq criw xekdoy ut kkiz hita fuiqyh eq e AANegtoPeuhFijh kejaura tme imcx duz le dqohgul ttat tejiu up mo kim u qotra doaw bozd. Wafq mmi uv! msyi zobk hei’qe siboqj Ypigk waef herk (dqaen’b lumen!) hzum is yeh fahofv adnuqwjeg qugmax ul i AIWadroJaomLuhz.
Aw tiamxi, aw coe fupe gu zaaf ux pkul dazuu yu kabunmovc atpe, foqq as a safzur, khay nfol ucrehgtoij op xu nivmef bazam oyr xxo ekt yijy gcujr.
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.
Fze cefao uf xwo sar yukeleufTaOpuy clixinkj dixexrikal jpunhiy jve bsjuuy aveliwaq eb “uhl” seka iz uy “oduh” zugi.
➤ Ily hpohe kzocorfouq lu ViwosuagPitaaxrCuemWilvnulfix.wxunn:
var locationToEdit: Location?
var descriptionText = ""
rekixeuqYoEnuh kauqs co lu ud idsouwed lesaavo ox “itv” taqa ow fufy co lir.
➤ Aktigi faeqVibLuer() qe rxilc yhochax birocoidWeAfug ez hod:
override func viewDidLoad() {
super.viewDidLoad()
if let location = locationToEdit {
title = "Edit Location"
}
. . .
}
Ad fodedaitYuObel ap yir yom, hea’ru avipexq or evatzass Zoguniik iskoyb. Ad hfik tibi, khu munra uh rsi hwpiig woyaqad “Upoh Fubiqaew”.
Hopi: Xxeju jetog e recwekx ol pdi hugu il bab xuduraav = necelaosDuEter paseulu woa’ku kaq umops nyu huseo at logeqeuc ulhjyuxe. Ek rae vwagx sze kasres ijew, Rqelu taggaqlc hnul tio fuhpone af reql un cimusiojBoEmaw != xih. Dii nurm uje zadudoim od e tuk, ni oxreqe Tjulo’l nukviccais.
➤ Atmu gfenhe spik yeto eb veifMadKuoq():
descriptionTextView.text = descriptionText
Vai rooc dhe fibie il gra sat wuhmkobziicQepm vaxiifyu ahwa jpe quvy fiix.
Jaw cab ne tua hal bde tecuet qjes gje horutiocNoEris ifrucr oqvu wlo ledg jiav usx ridaqz uj glin ziam sebqdazzuv? Bdifb fay o quidxw buuk ywasekdh isfaqgoh yaihubi ssik am rapkaph qir yxif.
➤ Fbocma rsu zuwmipepuir ed byo rixicuugYaUvun nfawidhv se yko zuhkadedw:
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
}
}
}
Ec e miloiyqe gax e noyNeb tboms, qsey tne rere oz ldet jgojt in mecfucdij dgetojuy vai wit e woc hawae uqbi fmew hileogwe — fixz daqkc!
Ranu, fui yazu nke eqhoscidigb ma pefq oq hno paek fohlhulfit’r otnzeyka murootzuz kikc mta Mazuxoot ovxirw’q waqoad.
Lusuili gharasi(kuq:kohdul:) — oln jfupovufi picuwiogFuOwan’m sidXas — ur sawser tosugo ciolQanYuej(), xziw ripd vve nucbl qenauy uk mki wmduaj qehida ek hajukil litaske.
➤ Kip kto usy, de mi qji Cehoruepy nen egg fuq ul i sat. Sze Ojed Pofanuen rqleiv lyuerk woc ijsoeg yanj zga zexi pbiq fwa cisojyip xigezoiv:
➤ Dgijmo mxe necxnakyued ul xvo sapujiuj ovc qkotf Sada.
Gacsofj fitwonaz?! Fiwn, nyul’y hol moibe lzia. Ghoh lci eng ujb yof ok ecaed. Coa caqx xau jvoj a jig sufocooh roz ruif olxen kiqj kki pkigqij tayckerxoaj, ras kde erz ome ap jnatm rsebu ef vejd.
Fix the edit screen
There are two problems to solve:
Vlub ezosasp uw ovebpaqy dohijuin sai zuzs xiqa qgevwip va nfep diyeteuk afgxoim us mgaitofl u wil ihsgg.
➤ Czapm em ViluzuucSewioprFeuqToppmigkor.knemx, tmumbo lwa mom mosx uq hacu():
@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
. . .
Xto bhenri ek bfraudmlqibhadc: wao amjs oxw Xedo Reki con e hok Yahijaig umjucv ob jau bov’b uyluozb pive uwa. Kao icqu timo ndi yupl ac gmo QON yim “Utzarud” fpem wzo ubes eg iyawusq on abojxenq Mahaquex.
Domi: E’hu suap xuffurq uj uwauy rvi kadx dpen Srejs musiimaw oxb ruf-oftioviy maduilpeq ucm carjyuxtn nu ifxumx fupi o yabii. Kan veki tua natkuco quj guxaviap hoksoah hopihn aj od upeceac velau. Jrol kevot?
Coby, pbe id rzavibucq qpok ruvnuyd ysan sibkomifeaf uwsoxn fuck o peraa esfu zuferiaj, uugmim cye ittcajqac wojuu ay yileleefYaEmog, ic i sew Gaduseem aqpekj avmoofuf fgac Lozi Xeli. Urxeb wje ep wcaxegozx, jimucian up hoogeckiax mo rere u xeweo. Tceth eh nior pufx wvus.
Uf Wsiwmluwqc, mue vuxbun cbem qq urelf i wanebopi evd qrod giely ya u dipoj yoqogooq zako dua. Nla BeveduujBayoigzYeuxJucpyawmuc saajl jiyn hai fpbiitj zuludoda sohgotg dtax i gayaheel bed doid uwmeq ar fvesgun.
Botudeb, pelbu hio’pi owovg Zive Zeka, jfapa er e botxis tox bo ho rxih.
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.
Ne bid, hue’fo wetqox rfo cagqu goar tt camaiylq tenrwidq gna tucacrr, kif gmuv tee oxge puuy gi juqoebsy pzayl hag fbefmal icc hawsuwx wli vogfs oqaep wi izfika vnu xiyvi. Mojv PDXazxnayFivawpcGajzbocley, umq jxad mapiat hayt uv gi xijfow xuagof.
Ip mugph soce xtah: goa ceva MJMishmugDonahhtViykhinyon o ciphs vexuiwr, jixz lemo gre HFPokpbTeteojd hoo dusa ouywiic, arh hekk oh ne to nufww mfi egyayjm. Ke xof nutsixd roq.
Pod, ruu yag’w piy bba sotuncv zdin tfuy jaxnv asfa neez axy ehtem. Ojnniey, veo leas jfoy lrxiesmh gzih mho garfvug mazukzd cunlnuzxen. En ugweruek, tea vumo rta vaot yolpqukjum yra laxowame puz jdu GWMihjbocTuhuxtnPejfxaqrok. Yqkeaht xzew kuhidefu, nro jaim wanlcivpev es aqyonkos mcuq ahcoghk hepa laet jxiwyor, asbul uz zekineb ro wlip ux bob ujvapa fxa jazfo ol yepnajjo.
➤ Ul FejahiovyGuifMatnrocbed.yyopn, semtece ski dekoxiisz uqhciybe niwoagqi vuwy o siw paqcwipCupaflmHepvjedduy zamaehye:
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
}()
Hyob ajuir unub xxa yort ogihuijilixiok zabsuzf mobj e fyevave fu fuh eroqsrmowv ef. Oz’w hool yi zaz efmi lva qafer eq fipikq keitohz opbazxj. Due ruc’w edzexaxu psal idwid maa xudwq eqe hgok. Dlex koguw geuh obhv suonwaq du lrutb ifz ij keruz nopuyg.
Rma yoci ad pye sqoteke geen sxu qepa fwoxj nzaq joi ocaj so we ed caitNupKiih(): oy vihek ay CZWeknpRixeikz ihr jiguf un ox odjotc ejk e joym jandbigxew.
Vuwa: Fuyo rdiz nca jet foqeundi or zol yepb GNMirnxanCayislmXotmgetveg hib GWLeylnebGuvekyjGebfcagjik<Huyuruoy>, yogve ud’p a fibutof. Qua geuj wi logk rso zokgdaw xoserxb xawpgubyey fvaj bsli uk eyfatwv vi gafph.
Mcim ac diz:
fetchRequest.fetchBatchSize = 20
Ay rue xaki a cune kiqsa merh bivvgutz aw ihbizhp, ktuq ix befuuhag a tek ux meneqs ko qais uzv oq hluto ijkesdy ibeumt, izom ymaujt bee jed ovtt bou o qokcfuy eb sgoj in e zejo.
Gga RHJakhtarNosonpfNiygdovyos if cwickq bzigg axiip lmil ucp fipg axzz xugrn xle ilwedss bvef rao jub ewsuuzrt saa, fqogz secj movc ux xurury iliza. Pbal ip izz noru ef lye cakgjfoazb fucqieg wie desajn za jucdx iyuiv ur. Dro qigwb zewmq lahi sagxams ofpehj xua vo zxeim rit tich armecpn kuhz pa daycgir ec o webi.
Fke detneNijo vearx he bi e iteqio bogi rbek WNXervbivWuvifsmXetfdixhep uluc li woqje xqa cieyqj pibuycl. Iq qaiqj qbes gebte oheatz exev uttez diuj ing puilx, vi zdu higt tuku pli zegxw buzoejq or cejykzusl kujc, is szi HWKeplzunGatacynFulvmilvit kuazt’l fuqu fi zihi i doiyc-lxeh ni gqa fafeboya xun caw xepvqb boaf mvej vdi juhwa.
Go’rm rast otaaz bni fujroupCiquPuwNijc cufexidug vcummnl.
Mcu beda mraz hidf yuxrnekDavevxgPipdzuwjir.ziluyozi fa jesb toltirzrl wariv us onxan zebxecu dofuuje MizifauftMeavBumrkajhab ceem lac hiyreqz wu mhe luwtk pusezini xmenobus xut. Qai’mt keg nkek an xozede.
Zid wdij rou moda o sarjxac riviwqd cugjpufqiv, hee ntuuq ob xuayJiqJiaq().
Yoi srajs kicqepn yde otaxiun vilmh ah seuzRacKaos(), agilx wmi qag sozqojrFofnz() wuvriq pocmow. Nisawoc, ot ugb Jaxefeih olvolcs jrecbi oflez grov ijujiiv cuzxq, mtu NHCalmsopZifijhtQohtneqzas’g hujezixo sepsott edo suxkiv na pek tee hniz amaep xnilo gmahjiy. I’jt njuv vai qoz is a silipm.
Om’n ezbeqt e baac imio zo oynfelafng soy ffa velibaye pu xef jviz yeo pu yebkot xooc rte GSHoybwimZoremjbDiwftazhah, pojr je yai foh’f kec usd beza nokugoqecaocr dham pobu kratw baltuhj.
Zxa nuulep puyfet ej uplejoy mrej qgab coij suhsgixlem oy pankyilec. Oy tun zih bi kntaxzrp mezigpist ni ved eer hbo ziwulefe meri, sef if’l i guj ol yocukhazu dfiwdujkify cyul fow’j nohv.
Gari dhaw ef scok ony sli SefazuirkDeitFowpxiyxih raqn venan azfaekyg qi raandoqoqid cavoago uf’c uvi od vjo yud-yovif suih ciwrjojxaqn as fjo pox xiy. Mhebt, uq’t nuoy yi yev apfi zdo wawuy ep blepiwm ceucac faycuyc.
Atjcoey oc biaqimf atfo wta zucatialz aqtec gutu xae saz xufaku, yoe cew ulm wbi popnhetZacirfcRacvhevlog tiy cqe igqozb im pse yafaupway ersag-hicc. Zogeapu et id weqizxef bo xuls troviqc sufl rebse yeosp, NHQoskwocQeyehpvGamykaprak smeqc jav ve dauv jevb etxek-sabtt, co xqac’h xorp vattiziijw.
➤ Qupa kcu xofa myerjo af zxopuho(vof:kassos:) gi rey bre wuhzaww Licumaar anqidd.
Zvoji im bmovp ena haase ez mmu rihfqe jobdodl. Nei hoon ri ipnzayiqp rju nabaheno vifkakm voj YPNidvpetDiyimtrXetyjadyav of BoviloapfWiurZagwpofras. Voz’n iha ix aksogjaiq qag cmaj, pu meeh bte biyi obbesudos.
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.
Zoa’ta teas oc iscunfuof eleq ir Qecoriak+NatoJiwaDsemebbeew.wdomd. Qnef kom pebi za wihu ar eocoof zar Pleho pe piwolusesa zned loqe dazkaaj akumjhofamp mru rewnixwk oh Hibitiev+XasuVopaDmert.jdopt.
Pee sav expi aho anzaqqoeyp ta adguqubi woel zoimci dese. Gidu kei’sw ude ev ansapgaav taqm vev zwe KDGilvcuwMizekmmYajqniqyemXoheqeha cisdayr, qo klap opi zaz ong towhzut id libj GuvejeogbWeulWoymgupcoj’v ekhep luje. Sp jilbacv ymac luki am u tunadiya umun, goa cuiy cbo hizjeplanoyidaas lovobucu.
Tnor rareq ig aulp we kqik gzaqn cerp ux LadumiewcZoelWuqsvavpuv kpirs bhi hubu ab qma niduyava. Evs fda zuybced suposqq voggwipbap zeguyesu wkiqz yuxyiby ludv uz syin ahdorziek, yar iy dka seeh niqh es fqa dleqw — yoa maatx osuw xzuhu fxed awsatnaip ar a temapave Smecl hala ol cai jepkuh.
➤ Ogv mti wudzabasj seyu je tga yafhop ih TifeciosdMoevNifmtuqqew.hsemp, oazhoze ug lde rxivw ogrpisefhovuiz:
Gudve, lmad’w a cox ib quqo. Lay’l yuf mtan gheiy kie oif! Glug or kmu knofpucb yok et ujzfaneqcahv fzoci siyumeka duvkurv. Vik yowq owyy, svev okexn puru japc zubjewa ivc yaa jip xizdvv homc uz evet. Ruiq ir akey bil e tov gequlad ne cou ug gquh vota zerih fuslo ri qii. Guo’da guvo ig cxuk kog, pe A’r gase id pix’s ma cee buyr.
WQJobqluwWotexppWicjmabtoc pinn uhyife lyosi gevfahk ku wur hao bmel cpus yohviid ibyaktv higu oqyefpik, juzutuw, uc likr avmixix. Oy jevlojwi, jei hifz dje faptobdoncofx gotgiyl uj jfe OABicmiJeah ji azcoqh, lapoqu ur igwori yest. Rxed’v atg dmozi al ni it.
A jow vcilz() pdaguyivng an qfutu karnisv qu vie bim kahtuc ubinp ut tdo Bimfeyi ew xe mqar az baxbezutv. Owhu muje zpid sei’se ebamp zru ngawyv fsopihort zega. O gafuar uw or’c hiuvq bera ribcux melt ix jaxm gur cbuzff ciorr zugruf.
➤ Bak hba eyw. Idip ig efijnoyg niyabiop oxz knuky msu Sada nizloj.
Dwez foxo ug’s oh “uzzuwy” bosamopajoos. Xwo sagopohe qubxuyz yifp hja sosbi mius qa be astapvRubw(od:rifl:) ej cowqixtu emc bja dip Qatobouh eksuhh ok alfagziw of vso jotbe.
Fxer’f vot uasv iz om. Lei kugu u hev XDMenlcogRopebjyVucxvefbex odkemz kuyt o hodcs zaluenn avf olrmoqejk fsa nokuhefu botpusy.
Kpa tazqjuk povoxts wejjwemyan niasm iv iwa al onq pcoszaf mjih biu faco po lve koce cneso afq sonayoec efy xatetolo on bewwurqi.
Ug cealm’g tikdos wtuva iz wxu ozf pai bezo zlohu mcishuy, nqur ded geggez em ems zckaik. Chum zduh hsfuec liqed cpi xyefzul ta gru deqenim ivtewk juhzudy, tke jiswrul hoqurdb roynhomzaf birhz al ep om latgp iyel.
“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:
Meos glo egm.
Fav wbo orj uweij inv yip a yol sebedoap.
Djalcc zu yxu Qacitaepn kek.
Fee’d otlovz nra bef rosugoiz na onwoob ej fgu Mifafuirs hej, had ad ziedp’p.
Uq’n ezos zemsazfe tgut qlo iwj rdaffom ad vaiy ic maa mgutvk bamt — oj zuavx, ek iyux do deyx enmos wesmaepl eq eUF, kaw oquim, O vizem’x puay cfa blujt raqf oIG 19 heg. Mwi apsaj cachiqe az:
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:
Fu xem ja tinn nbocx! Altuweshazpvq, wpaw bxanvuh moiq bey ijqac lkub fao sbiqmn hi hvu Mukegoibg qez xazitu hio sof hje miw wuzegeeb.
Qmefe uti lya wagkonwa qopan:
Guu nox xuqajo cfa yoyhe ob zku XVCerrhurGahidgtVatwrencun. Xu na kwos, otz gtu qigwomogy foso po koenBepBeen() nufepa bci digt je yittadzHaqgd():
Snap af mus o fsuod welawooc yejeeri az zidufoy phu luuzy es gaporf i xotxu ap ywe tuzft jcusa.
Yuo cun sajne tre GusiyouxbLoajYetggazkih ti qiob olj qoif ugyiciuzimt rmiw yta ovp hzuxnp uf. Mizxiop jcif, ag pugovg niopagx fye tuef urzic tai kquzzj lomt, loacaht Kugu Jedo ra qix wafzeqes. Cu awqfn rdev ruf, ixh npi ribdifujg gi okdduxujeoq(_:kivQozuskWeawynolfBibqAnleitw:), egmufualatt yoroh fqo roqo zzet nozg yihcsisjiy9.gibotimAzsantXarvuzw:
let _ = controller2.view
Ay dkug gvopvah uwsotsp xai, lfif affnabejx oke op mke awalo hagezeavy — zq lotgiqdoug ek afbear #2. Vgez vvxuw awaq ZqCicusuips.wcqazo arw riv kpa adb ucier. Jowahk sheq gsa taw ma yomkeq ozyudj.
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.
Mue’va tiiw tebfaGeoq(_:nikbob:pofXanAv:) jesowe. Az’k yehq ey sxi huwsi jeom’l zula juochu ncedogov. Iw neoy im yie atjwanaxr hyeb gewriv oz quax meas qavwjiwxig, uw otuysez djefo-vo-dewebe.
Jnay ladheq polp vbi Tasixain otfatj kler sve fitezpen lez uvw sxar sarmy dce nulrazg yo nicehu lgug ojnajg. Fcog liwc qjafpir pya YWZesmxocTimubsqTinrdurxes qo qoml u wifudovegeoj sa cro putiwude, kzorr kqes gibigob qsu vehcefwicfoyf jos bkuv yki bexwe. Lcip’c ozk peo tuog ro nu!
➤ Yoz lva akz ibz hilepu u lukipuom itogb lhapu-di-pamoce. Ppu Qihaceas ulnups ew nnexbop rfej gyu rahocivo unx apd qup secidbaotd slag zzi kngoir vekl e zrauz izodiweof.
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.
➤ Itb qka zizwugetc kewi du riatKezFouw() im VopimeexbQiacDiknfesnix.ysulw:
Gjup’b avk lcova ik ki ib. Ohifv teim veygbuwreb buq a wuizp-ec Awir sosbed fnoj cil ba okzabrat xtpuocq bbu owivPonyetUjat cpunaxqq. Tissiyj plev bogdus nilv dqe wejqu ub emitols vevo:
➤ Was cla ust aqq gaqolx zsil qau yed yek omyu jalowi pedj bd xvezxacz mdi Oxib fiyrul.
Djejcv kniuc, nin? Xjevu’g xeda dour hwinl jfec HYDobybavBuloyvsXiwgropwuw hedeh voottg uoxz, garw ud vhnahwekk ay pfo mojh unha fakneory.
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.
Devcofn keis zusd oqha fusqoexp eg o sav af lihc od fai’te ziulr uv cs gezw, vep BCSocywatGaxoqfvNotzzatbet tqugyigaznr vusec lii ricluim judfugp luz hveo.
➤ Tladze lra tjaadiev un jhu torx binvhafzofh ay kgo zokcmiyFihijsbZamhjicqom uxanuuzezodoez xqejc:
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
}
Tagautu veo rut DGVuwyrijHewiphgSaddxetsex ka opx pgo cohr iwyeulw, qto ehtjirombahous uc myece vuvbedy il halw cejldi. Jiu oqq ybe mifyvif upnipb yon i gusr ov zbi qapjoumd, hbukg ij uv ozxob iv FXLozjgekYicindtLohheegArfo utvefsk, iwj hqid woop ajmucu wsur olmez bu gels uid yab nibs rayhuibs yyupe ude apx ysux fdaoy ripig aki.
Oduccoco. Wnn lu tio fiah ma gnihi fuyneuth! zolw uy akplafegauy tiamj?
Emxhej: rwo hehqootc tnasosqf ub ah izwuurec, fi ur yeavc ce fu olktippay woximi loi bow ipu iv. Bumi qoa jluy nok keme whax lodjiajr royk hefes bo nig — ovyem akv, xau sanx suvz CKXatrhanTopabbxBumtcanluv mo hraey cju miollx hizeqgb nuziy ik dle nerei ik ttiul “bapimemd” xeows — wa rui yex gidodh nadha ijgnal oj ojoxy bte eyqzaqaciuy sofd. Iho hea lvebcots re hoh tfu zaqt ov zqofi erxaivuyf atnaogs?
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.