Bygge en handleliste Application Med CloudKit: Legge Records

Building en handleliste Application Med CloudKit: Legge Records

23
Del
10
Del

Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av
Dette innlegget er en del av en serie kalt Bygge en handleliste Application Med CloudKit.Building en handleliste Application Med CloudKit. Innledning

I den første opplæringen av denne serien, utforsket vi den CloudKit rammeverket og infrastruktur. Vi la også grunnlaget for prøveprogrammet som vi skal bygge, en handleliste søknad. I denne opplæringen fokuserer vi på å legge til, redigere og fjerne handlelister.

Forutsetninger

Som jeg nevnte i forrige tutorial, jeg skal bruke Xcode 7 Hotell og Swift 2
. Hvis du bruker en eldre versjon av Xcode, så husk at du bruker en annen versjon av Swift programmeringsspråk.

I denne opplæringen, vil vi fortsette å jobbe med prosjektet vi opprettet i den første opplæringen. Du kan laste det ned fra GitHub.

1. Sette opp CocoaPods

handleliste søknad vil gjøre bruk av SVProgressHUD bibliotek, en populær bibliotek skapt av Sam Vermette som gjør det enkelt å vise en fremdriftsindikator. Du kan legge til biblioteket manuelt til prosjektet, men jeg anbefaler på det sterkeste å bruke CocoaPods for å administrere avhengigheter. Er du ny på CocoaPods? Jeg har skrevet en innledende opplæringen for å CocoaPods som vil hjelpe deg å få fart

Trinn 1:. Opprette en Podfile

Åpne Finder og naviger til roten av Xcode prosjekt. . Opprette en ny fil, navn det Podfile, og legge til følgende linjer av Ruby til det
plattform: iOS, '! Target 8.0'use_frameworks' Lister "gjøre pod 'SVProgressHUD', '~ > 1.1'end

Den første linjen angir plattform, iOS, og prosjektets utplassering mål, iOS 8.0. Den andre linjen er viktig hvis du bruker Swift. Swift støtter ikke statiske biblioteker, men CocoaPods gjør gir muligheten siden versjon 0.36 å bruke rammer. Vi angi deretter avhengig for Lister målet for prosjektet. Bytt lister med målets navn hvis målet ditt er et annet navn

Trinn 2:. Installere Avhengig

Åpne Terminal, navigere til roten av Xcode prosjekt, og kjøre pod installere. Dette vil gjøre en rekke ting for deg, som å installere avhengig spesifisert i Podfile og skape en Xcode arbeidsområde.

Etter fullført CocoaPods oppsett, lukke prosjektet og åpne arbeidsområdet CocoaPods opprettet for deg. Det sistnevnte er meget viktig. Åpne arbeidsområdet, ikke prosjektet
. Arbeidsområdet omfatter to prosjekter, Lister prosjekt og et prosjekt kalt Pods.

2. Notering Shopping Lists

Trinn 1: Housekeeping

Vi er klar til å refokusere på CloudKit rammeverket. Men først må vi gjøre noen rengjøring ved å gi den ViewController klasse til ListsViewController klassen.

Start med å døpe ViewController.swift til ListsViewController.swift. Åpne ListsViewController.swift og endre navnet på ViewController klasse til ListsViewController klassen.

Deretter åpner Main.storyboard, utvide View Controller Scene i dokument Outline til venstre, og velg Vis Controller. Åpne Identity Inspektør på høyre og endre klasse til ListsViewController

Trinn 2:. Legge til en tabell Vis

Når brukeren åpner programmet, det er presentert med sine handlelister. Vi vil vise handlelister i en tabellvisning. La oss begynne med å sette opp brukergrensesnittet. Velg Lister Vis Controller i Lister Vis Controller Scene og velge Embed In > Navigation Controller fra Xcode Redigerings menyen.

Legg til en tabellvisning til visningen kontrolleren syn og skape de nødvendige layout begrensninger for det. Med tabellvisningen valgt, åpner attributter Inspector og satt Prototype Cells til 1. Velg prototype cellen og satt stil til Basic og Identifier å ListCell.

Med tabellvisningen valgt, åpner Connections Inspector. Koble bordet vise sin datakilden og delegere uttak til Lister Vis Controller

Trinn 3:. Tomme Statlige

Selv om vi bare opprette en eksempel program for å illustrere hvordan CloudKit fungerer, vil jeg liker å vise en melding hvis noe går galt, eller hvis ingen handlelister ble funnet på iCloud. Legg en etikett til visningen kontrolleren, gjøre det så stort som utsikten controller syn skape de nødvendige layout begrensninger for det, og sentrere etiketten tekst.

Siden vi arbeider med nettverksforespørsler, jeg ønsker også for å vise en aktivitet indikator utsikt så lenge søknaden venter på svar fra iCloud. Legg en aktivitetsindikator utsikt til visningen kontrolleren syn og sentrer den i den overordnede syn. I attributter Inspector, krysser du merket Hides Når stoppet

Trinn 4:. Koble Outlets

Åpne ListsViewController.swift og erklære et utløp for etiketten, utsikten bordet, og den aktivitetsindikator utsikt. Dette er også et godt tidspunkt å gjøre det ListsViewController klasse i samsvar med UITableViewDataSource og UITableViewDelegate protokoller.

Legg merke til at jeg har også lagt til en import regnskapet for SVProgressHUD rammeverk og at jeg har erklært en statisk konstant for gjenbruk identifikator av prototypen cellen vi skapt i dreieboken
importere UIKitimport CloudKitimport SVProgressHUDclass ListsViewController. UIViewController, UITableViewDataSource, UITableViewDelegate {statiske la ListCell = "ListCell"IBOutlet svak Var messageLabel: UILabel! IBOutlet Svak Var Tableview: UITableView! IBOutlet Svak Var activityIndicatorView: UIActivityIndicatorView! ...}

Leder tilbake til dreieboken og koble uttakene med de tilsvarende utsikt i Lister Vis Controller Scene

Trinn 5:. Klartabell

Før vi hente data fra iCloud, må vi sørge for at visningen tabellen er klar til å vise dataene. Vi må først opprette en eiendom, lister, for å holde postene vi er i ferd med å hente. Husk at postene er forekomster av CKRecord klassen. Dette betyr at eiendommen som vil holde dataene fra iCloud er av typen [CKRecord], en rekke CKRecord tilfeller
klasse ListsViewController. UIViewController, UITableViewDataSource, UITableViewDelegate, AddListViewControllerDelegate {statiske la ListCell = "ListCell"IBOutlet svak Var messageLabel : UILabel! IBOutlet Svak Var Tableview: UITableView! IBOutlet Svak Var activityIndicatorView: UIActivityIndicatorView! Var lister = [CKRecord] () ...}

For å komme i gang, må vi iverksette tre metoder for UITableViewDataSource protocol:


numberOfSectionsInTableView(_:)

numberOfRowsInSection(_:)

cellForRowAtIndexPath(_:)

If du har noen erfaring med bord visninger, da gjennomføringen av hver av disse metodene er grei. Men cellForRowAtIndexPath (_ :) kan kreve noen forklaring. Husk at en CKRecord eksempel er en supercharged ordbok av nøkkelverdipar. For å få tilgang verdien av en bestemt nøkkel, påberope deg objectForKey (_ :) på CKRecord objektet. Det er det vi gjør i cellForRowAtIndexPath (_ :). Vi henter posten som korresponderer med tabellvisningen rad og be det for verdien for nøkkelen "navn". Hvis nøkkelverdi-par ikke finnes, vi viser en strek for å indikere listen har ikke et navn ennå //MARK: -. //MARK: Tabell Data Source Methodsfunc numberOfSectionsInTableView (Tableview: UITableView) - > Int {return 1;} func Tableview (Tableview: UITableView, numberOfRowsInSection seksjon: Int) - > Int {return lists.count} func Tableview (Tableview: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) - > UITableViewCell {//dequeue Gjenbruk Cell la celle = tableView.dequeueReusableCellWithIdentifier (ListsViewController.ListCell, forIndexPath: indexPath) //Konfigurer Cell cell.accessoryType = .DetailDisclosureButton //Fetch Record la list = lister [indexPath.row] hvis la listenavn = liste .objectForKey ("navn") som? String {//Konfigurer Cell cell.textLabel .text = listenavn?} Else {cell.textLabel .text = "-"} retur celle}
Trinn 6: Klar brukergrensesnitt

Det er én mer trinn for oss å ta, forberede brukergrensesnittet. I visningen kontrolleren viewDidLoad metode, fjerne fetchUserRecordID metodekallet og påberope setupView, en hjelper metode.
Styre func viewDidLoad () {super.viewDidLoad () setupView ()}

setupView metoden forbereder brukergrensesnittet for å hente listen over oppføringer. Vi skjule etiketten og utsikten bordet, og fortelle at aktivitetsindikatoren sikte på å begynne å animere
//MARK: -. //MARK: Vis Methodsprivate func setupView () {tableView.hidden = true messageLabel.hidden = true activityIndicatorView. startAnimating ()}

Bygg og kjøre programmet på en enhet eller i iOS Simulator. Hvis du har fulgt trinnene ovenfor, bør du se en tom visning med en spinnende aktivitet indikator visning i sentrum

Trinn 7:. Opprette en Record Type

Før vi hente noen poster, vi trenger for å lage en posttype for en handleliste i CloudKit dashbordet. Den CloudKit dashbordet er en webapplikasjon som lar utviklere administrere data som er lagret på Apples iCloud-servere.

Velg prosjektet i Prosjekt Navigatør og velg Lister målrette fra listen over mål. Åpne fanen Capabilities på toppen og utvide iCloud delen. Nedenfor listen over iCloud containere, klikker du på knappen merket CloudKit Dashboard.

Logg deg på med utviklerkonto og sørg Lister programmet er valgt i venstre. På venstre, velg oppføringstyper fra Schema delen. Hvert program har som standard en Brukere oppføringstype. For å opprette en ny oppføringstype, klikker du på pluss-knappen på toppen av den tredje kolonnen. Vi vil følge Apples navnekonvensjon og navngi posttypen Lister, ikke liste.

Legg merke til at det første feltet blir automatisk opprettet for deg. Still Feltnavn for å nevne og bekrefte at Felttype er satt til String. Ikke glem å klikke på Lagre-knappen nederst for å lage lister posttypen. Vi vil revidere CloudKit Dashboard senere i denne serien

Trinn 8:. Utføre en spør

Med Lister posttypen opprettet, er det endelig tid for å hente noen poster fra iCloud. Den CloudKit Rammeverket gir to APIer for å samhandle med iCloud, en praktisk API og en API basert på NSOperation klasse. Vi vil bruke både APIer i denne serien, men vi kommer til å holde det enkelt for nå og bruke det praktiske API.

I Xcode, åpen ListsViewController.swift og påkalle fetchLists metoden i viewDidLoad. Den fetchLists metoden er en annen hjelper metode. La oss ta en titt på metodens gjennomføringen.
Styre func viewDidLoad () {super.viewDidLoad () setupView () fetchLists ()}

Fordi en handleliste posten er lagret i brukerens private database, må vi først få en henvisning til standard container private database. For å hente brukerens handlelister, må vi utføre en spørring på den private database, bruker CKQuery klassen
//MARK: -. //MARK: Helper Methodsprivate funk fetchLists () {//Fetch Private Database la privateDatabase = CKContainer.defaultContainer () privateCloudDatabase //Initial Query la query = CKQuery. (registreringstype: RecordTypeLists, predikat: NSPredicate (format: "TRUEPREDICATE")) //Konfigurer Query query.sortDescriptors = [NSSortDescriptor (key: "navn" , stigende: true)] //Utfør Query privateDatabase.performQuery (spørring, inZoneWithID: null) {(records, feil) - > Ugyldig i dispatch_async (dispatch_get_main_queue () {() - > ugyldig i //Process Response on Main Thread self.processResponseForQuery (poster, error: error)})}}

Vi initial en CKQuery eksempel ved å påberope seg init ( registreringstype: predikat :) utpekt initializer, passerer i posten type og en NSPredicate objekt. For å unngå skrivefeil, har jeg laget en konstant for posttypen. Den konstante, RecordTypeLists, er erklært øverst ListsViewController.swift
import UIKitimport CloudKitimport SVProgressHUDlet RecordTypeLists = "Lister" class ListsViewController. UIViewController, UITableViewDataSource, UITableViewDelegate {...

Før vi utføre spørringen setter vi spørringen er sortDescriptors eiendom. Vi skaper en matrise som inneholder en NSSortDescriptor objekt med nøkkel "navn" og stigende satt til true

Utføre spørringen er så enkelt som å kalle performQuery (_:. InZoneWithID: completionHandler :) på privateDatabase, passerer i søket som første argumentet. Den andre parameteren angir identifikatoren posten sonen der søket vil bli utført. Ved bestått i null, er spørringen utføres på standardsonen av databasen.

Det tredje argumentet er en ferdigstillelse handler. Nedleggelsen godtar en valgfri rekke CKRecord gjenstander og en valgfri NSError eksempel. Dokumentasjonen CloudKit eksplisitt nevner at ferdigstillelse behandleren kan påberopes fra hvilken som helst tråd. Vi sender derfor behandlingen av responsen på hovedtråden ved å pakke processResponseForQuery (_: error :) metodekallet i en dispatch_async nedleggelse. Det er hvor enkelt det er å utføre en spørring. La oss se hvordan vi håndterer respons spørringen er

Trinn 9:. Behandler Response

Gjennomføringen av processResponseForQuery (_: error :) er ikke vanskelig hvis du er kjent med Swift språk . Vi inspiserer innholdet i postene og feil parametre, og oppdatere meldingen variable tilsvar
privat func processResponseForQuery (poster: [CKRecord] ?, feil:? NSError). {Var message = "" hvis la error = error {print (feil) melding = "Feil Henter Records"} else if lar poster = poster {lister = poster hvis lists.count == 0 {message = "Ingen registreringer funnet"}} else {message = "Ingen registreringer funnet"} hvis melding .isEmpty {tableView.reloadData ()} else {messageLabel.text = melding} updateView ()}

På slutten av metoden, påberope vi updateView. . I denne hjelperen metoden, vi oppdaterer brukergrensesnittet basert på innholdet i listene eiendommen
privat func updateView () {la hasRecords = lists.count > 0 tableView.hidden =! HasRecords messageLabel.hidden = hasRecords activityIndicatorView.stopAnimating ()}

Bygg og kjøre programmet for å teste det vi har fått så langt. Vi har for øyeblikket ikke har noen poster, men vi vil fikse det i neste del av denne opplæringen.

3. Legge til en handleliste

Trinn 1: Opprette AddListViewController Class

Fordi legge til og redigere en handleliste er svært like, vi kommer til å gjennomføre både på samme tid. Opprett en ny fil og navngi den AddListViewController.swift. Åpne den nyopprettede filen og opprette en UIViewController underklasse heter AddListViewController. På toppen, legge import uttalelser for UIKit, CloudKit, og SVProgressHUD rammer. Erklærer to uttak, en av typen UITextField! og en av typen UIBarButtonItem !. Sist men ikke minst, lage to handlinger, kansellere (_ :) og lagre (_ :)
import UIKitimport CloudKitimport SVProgressHUDclass AddListViewController. UIViewController {IBOutlet svak Var nameTextField: UITextField! IBOutlet Svak Var saveButton: UIBarButtonItem! IBAction Func avbryte (avsender: AnyObject) {}IBAction func redning (avsender: AnyObject) {}}
Trinn 2: Opprette brukergrensesnittet

Åpne Main.storyboard og legge til en visning styringen til storyboard. Med utsikt kontrolleren valgt, åpner Identity Inspektør på høyre og sette klasse til AddListViewController.

Brukeren vil kunne navigere til add listevisning kontrolleren ved å trykke på en knapp i listene vise kontrolleren. Dra en bar knapp element fra objektbiblioteket til navigasjonslinjen av listene vise kontrolleren. Med bar knappen elementet valgt, åpner attributter Inspector og satt System element for å legge. Trykk Kontroll og dra fra baren knappen elementet til add listevisning controller og velg Trykk fra menyen som vises.

Det er viktig at du velger presse fra Handling Segue delen. Det bør være det første elementet i menyen. Velg segue du jus opprettet og Set Identifier å ListDetail i attributter Inspector til høyre.

Legg to bar knapp elementer til navigasjonslinjen i add listevisning kontrolleren, en på venstre og en på høyre . Set System Element av venstre bar knappen element for å Avbryt og som av retten bar knappen element for å spare. Til slutt legger du et tekstfelt til add listevisning kontrolleren. Sentrere tekstfeltet og sette sitt Alignment til sentrum i Attributter Inspector.

Det er mulig at etter å skape naturlig overgang fra listene vise styringen til add listevisning controller, ble ingen navigasjons elementet opprettet for Add List View Controller Scene. Jeg tror dette er en feil i Xcode 7.

For å løse dette problemet, velger naturlig overgang, og i attributter Inspector, setter naturlig overgang til frarådet segues > Trykk. Dette vil legge et navigasjonselement til scenen. Deretter satt naturlig overgang tilbake til Adaptive segues > Vis

Til slutt kobler uttak og handlinger du opprettet i AddListViewController.swift til de tilsvarende elementene i brukergrensesnittet i scenen

Trinn 3:..
AddListViewControllerDelegate Protocol

Før vi implementere AddListViewController klasse, må vi erklære en protokoll som vi skal bruke til å kommunisere fra tillegget listevisning kontrolleren til listene vise kontrolleren. Protokollen definerer to metoder, en for å legge til og en for å oppdatere en handleliste. Dette er hva protokollen ser ut
protokollen AddListViewControllerDelegate {func kontrolleren (controller: AddListViewController, didAddList listen: CKRecord) func kontrolleren (controller: AddListViewController, didUpdateList listen: CKRecord)}.

Vi trenger også å erklære tre eiendommer, en for delegat, en for handleliste som er opprettet eller oppdatert, og en hjelper variabel som indikerer om vi skaper en ny handleliste eller redigere en eksisterende oppføring.
importere UIKitimport CloudKitimport SVProgressHUDprotocol AddListViewControllerDelegate {func kontrolleren (controller : AddListViewController, didAddList listen: CKRecord) func kontrolleren (controller: AddListViewController, didUpdateList listen: CKRecord)} class AddListViewController: UIViewController {IBOutlet svak Var nameTextField: UITextField! IBOutlet Svak Var saveButton: UIBarButtonItem! Var delegat: AddListViewControllerDelegate? Var newList: Bool = sant Var liste: CKRecord? IBAction Func avbryte (avsender: AnyObject) {}IBAction func redning (avsender: AnyObject) {}}

Gjennomføringen av AddListViewController klassen er ingen rakett vitenskap. Metodene knyttet til visningen livssyklus er kort og lett å forstå. I viewDidLoad, vi først påberope setupView helper metoden. Vi vil implementere denne metoden i et øyeblikk. Deretter oppdaterer verdien av newList hjelpevariabel basert på verdien av listen egenskapen. Hvis listen er lik null, så vet vi at vi skaper en ny rekord. I viewDidLoad, vi også legge til visningen kontrolleren som observatør for UITextFieldTextDidChangeNotification varslinger
//MARK: -. //MARK: Vis Livet Cycleoverride func viewDidLoad () {super.viewDidLoad () setupView () //Update Hjelper newList = liste == null //Legg Observer la notificationCenter = NSNotificationCenter.defaultCenter () notificationCenter.addObserver (selv, velger: "textFieldTextDidChange:", navn: UITextFieldTextDidChangeNotification, objekt: nameTextField)} overstyring func viewDidAppear (animert: Bool) { nameTextField.becomeFirstResponder ()}

I viewDidAppear (_ :), kaller vi becomeFirstResponder på tekstfeltet for å presentere tastaturet for brukeren.

I setupView, påberope vi to hjelpemetoder, updateNameTextField og updateSaveButton. I updateNameTextField, befolke vi tekstfeltet hvis listen er ikke null. Med andre ord, hvis vi redigerer en eksisterende post, så vi fylle ut tekstfelt med navnet på den rekorden.

updateSaveButton metoden er ansvarlig for å aktivere og deaktivere baren knappen elementet i høyre . Vi bare gjør det mulig å spare knappen hvis navnet på handlelisten er ikke en tom streng
//MARK: -. //MARK: Vis Methodsprivate func setupView () {updateNameTextField () updateSaveButton ()} //MARK: - private func updateNameTextField () {if la name = listen? .objectForKey ("navn") som? String {nameTextField.text = navn}} //MARK: -Private func updateSaveButton () {! La text = nameTextField.text hvis la name = text {saveButton.enabled name.isEmpty =} else {saveButton.enabled = false}}
Trinn 4: Implementering Handlinger

avbryte (_ :) handlingen er så enkelt som det blir. Vi pop top view controller fra navigasjons stabelen. Lagringen (_ :) handlingen er mer interessant. I denne metoden, trekke vi brukerens input fra tekstfeltet, og få en henvisning til standard container private database.

Hvis vi legger til en ny handleliste, så skaper vi en ny CKRecord forekomst ved å påberope init (registreringstype :), passerer i RecordTypeLists som posttypen. Vi deretter oppdatere navnet på handleliste ved å sette verdien av posten for nøkkelen "navn".

Fordi lagre en rekord involverer et nettverk forespørsel og kan ta en ikke-triviell mengde tid, vi viser en forløpsindikator. Hvis du vil lagre en ny rekord eller eventuelle endringer i en eksisterende post, kaller vi saveRecord (_: completionHandler :) på privateDatabase, passerer i posten som første argument. Det andre argumentet er et annet ferdigstillelse handler som startes når du lagrer posten ferdig, hell eller uten hell.

Gjennomføringen handler godtar to argumenter, et valgfritt CKRecord og en valgfri NSError. Som jeg nevnte tidligere, kan ferdigstillelse handler påberopes på enhver tråd, noe som betyr at vi trenger å kode mot det. Vi gjør dette ved eksplisitt å påberope seg processResponse (_: error :) metoden på hovedtråden
//MARK: -. //MARK: Handlinger @ IBAction func avbryte (avsender: AnyObject) {navigationController .popViewControllerAnimated? (sann)} @ IBAction func spare (avsender: AnyObject) {//Hjelpere la name = nameTextField.text //Fetch Private Database la privateDatabase = CKContainer.defaultContainer () privateCloudDatabase hvis liste == null {list = CKRecord (registreringstype.: ? RecordTypeLists)} //Konfigurer Record liste .setObject (navn, Forkey: "navn") //Show Progress HUD SVProgressHUD.show () //Lagre post privateDatabase.saveRecord (liste) {(record, feil) - >! Void i dispatch_async (dispatch_get_main_queue () {() - > Void i //Avvis Progress HUD SVProgressHUD.dismiss () //Process Response self.processResponse (rekord, error: error)})}}

I processResponse ( _: error :), vi kontrollere om en feil ble kastet. Hvis vi får problemer, vi viser et varsel til brukeren. Hvis alt gikk greit, varsle vi representanten og pop utsikten kontrolleren fra navigasjons stabelen
//MARK: -. //MARK: Helper Methodsprivate func processResponse (? Rekord: CKRecord ?, feil: NSError) {var message = "" hvis la error = error {print (feil) melding = "Vi var ikke i stand til å lagre listen din." } Else if rekord == null {message = "Vi var ikke i stand til å lagre listen din." } If message.isEmpty {//Initial Alert Controller la alertController = UIAlertController! (Tittel: "Feil", melding: melding, preferredStyle: .Alert) //Present Alert Controller presentViewController (alertController, animert: true, ferdigstillelse: null)} else {//Varsle delegat hvis newList {delegere .controller? (selv, didAddList: liste)} else {delegere .controller (selv, didUpdateList: liste)?} //Pop View Controller navigationController .popViewControllerAnimated (true)} .}

Sist men ikke minst, når utsikten kontrolleren mottar en UITextFieldTextDidChangeNotification varsling, påkaller det updateSaveButton å oppdatere lagre knappen
//MARK: - //MARK: Melding Handlingfunc textFieldTextDidChange (varsling: NSNotification) {updateSaveButton ( )}
Trinn 5: Binde Alt Sammen

I ListsViewController klasse, likevel må vi ta vare på noen få ting. La oss begynne med konform klassen til AddListViewControllerDelegate protokollen
klasse ListsViewController. UIViewController, UITableViewDataSource, UITableViewDelegate, AddListViewControllerDelegate {...

Dette betyr også at vi må implementere metoder for AddListViewControllerDelegate protokollen. I kontrolleren (_: didAddList :) metode, legger vi den nye plata til rekken av CKRecord stedene. Vi deretter sortere rekke poster, oppdater bordvisningen og påberope updateView på visningen kontrolleren
//MARK: -. //MARK: Legg List View Controller Deleger Methodsfunc kontrolleren (controller: AddListViewController, didAddList listen: CKRecord) {//Legg Liste til Lister lists.append (liste) //Sorter Lister sortLists () //Update Tabell tableView.reloadData () //Oppdater visning updateView ()}

sortLists metoden er ganske grunnleggende. Vi kaller sortInPlace på rekke poster, sortering array basert på plata navn.
Private funk sortLists () {lists.sortInPlace {var resultat = false la name0 = $ 0.objectForKey ("navn") som ? String la navn1 = $ 1.objectForKey ("navn") som? String hvis la listName0 = name0, listname1 = navn1 {resultat = listName0.localizedCaseInsensitiveCompare (listname1) == .OrderedAscending} retur resultat}}

Gjennomføringen av den andre metoden av AddListViewControllerDelegate protokollen, controller (_: didUpdateList :), ser nesten identiske. Fordi vi ikke legger til en post, vi trenger bare å sortere rekke poster og laste tabellvisningen. Det er ikke nødvendig å ringe updateView på visningen kontrolleren siden rekke poster er, per definisjon, ikke tom
func kontrolleren. (Controller: AddListViewController, didUpdateList listen: CKRecord) {//Sorter Lister sortLists () //oppdater Table View tableView.reloadData ()}

Hvis du vil redigere en post, må brukeren å trykke på tilbehøret knappen på rad tabellvisning. Dette betyr at vi må implementere Tableview (_: accessoryButtonTappedForRowWithIndexPath :) metoden i UITableViewDelegate protokollen. Før vi implementere denne metoden, erklærer en hjelper eiendom, valg, til å lagre brukerens utvalg
klasse ListsViewController. UIViewController, UITableViewDataSource, UITableViewDelegate, AddListViewControllerDelegate {statiske la ListCell = "ListCell"IBOutlet svak Var messageLabel: UILabel! IBOutlet Svak Var Tableview: UITableView! IBOutlet Svak Var activityIndicatorView: UIActivityIndicatorView! Var lister = [CKRecord] () Var valg: Int? ...}

I Tableview (_: accessoryButtonTappedForRowWithIndexPath :) Vi lagrer brukerens valg i utvalg og fortelle visningen kontrolleren til å utføre naturlig overgang som fører til add listevisning kontrolleren. Hvis du er nysgjerrig, har jeg laget en konstant i ListsViewController.swift for naturlig overgang identifikator, SegueListDetail
//MARK: -. //MARK: Tabell delegat Methodsfunc Tableview (Tableview: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath) {tableView.deselectRowAtIndexPath (indexPath, animert: true) //Lagre Selection selection = indexPath.row //Utfør Overgang performSegueWithIdentifier (SegueListDetail, avsender: selv)}

Vi er nesten der. Når naturlig overgang med identifikatoren ListDetail er utført, må vi konfigurere AddListViewController forekomsten som skyves på navigasjons stabelen. Vi gjør dette i prepareForSegue (_:. Avsender :)

segue hender oss en referanse til målet visning kontrolleren, AddListViewController eksempel. Vi setter representanten eiendom, og hvis en handleliste er oppdatert, setter vi utsikten kontrollerens liste eiendom til den valgte posten
//MARK: -. //MARK: Overgang Livet Cycleoverride func prepareForSegue (naturlig overgang: UIStoryboardSegue, avsender:? AnyObject) {vakt la identifikator = segue.identifier else {retur} bryter identifikatoren {case SegueListDetail: //Fetch Destination View Controller la addListViewController = segue.destinationViewController som! AddListViewController //Konfigurer View Controller addListViewController.delegate = selv hvis la selection = utvalget {//Fetch List la list = lister [utvalg] //Konfigurer View Controller addListViewController.list = liste} standard: break}}

Bygg og løp programmet for å se resultatet. Du skal nå være i stand til å legge til en ny handleliste og redigere navnet på eksisterende handlelister.

4. Slette Shopping Lists

Legge muligheten til å slette handlelister er ikke mye ekstra arbeid. Brukeren skal kunne slette en handleliste ved å dra en tabellvisning rad fra høyre til venstre og trykke på sletteknappen som er avdekket. For å gjøre dette mulig, trenger vi å implementere to metoder for UITableViewDataSource protocol:


tableView(_:canEditRowAtIndexPath:)

tableView(_:commitEditingStyle:forRowAtIndexPath:)

The implementering av Tableview (_: canEditRowAtIndexPath :) er trivielt som du kan se nedenfor
func Tableview (Tableview: UITableView, canEditRowAtIndexPath indexPath. NSIndexPath) - > Bool {return true}

I Tableview (_: commitEditingStyle: forRowAtIndexPath :), vi hente den riktige posten fra tabellen med poster og påberope deleteRecord (_ :) på visningen kontrolleren, passerer i posten som må slettes .
func Tableview (Tableview: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {vokte editingStyle == .Delete else {retur} //Fetch Record la list = lister [indexPath.row] //Slett Record deleteRecord (liste)}

deleteRecord (_ :) metoden bør se kjent nå. Vi viser en fremdriftsindikator og ringe deleteRecordWithID (_: completionHandler :) på standard container private database. Legg merke til at vi kjører i posten identifikator, ikke posten selv. Gjennomføringen handler godtar to argumenter, et valgfritt CKRecordID og en valgfri NSError
privat func deleteRecord (liste: CKRecord). {//Fetch Private Database la privateDatabase = CKContainer.defaultContainer () privateCloudDatabase //Show Progress HUD SVProgressHUD.show.