Compatibile con Xcode 8

Tutorial Core Data, creare e gestire relazioni tra Entity

ENTRA NEL NOSTRO GRUPPO FACEBOOK

Questa è un tutorial estrapolato dal corso di sviluppo app per iOS con Swift. Buona lettura!

Nel precedente tutorial ti ho lasciato con le funzioni principali del Core Data: inserimento, cancellazione e ricerca dei vari NSManagedObject all’interno del tuo NSManagedObjectContext (cioè lo spazio dove i dati persistenti risiedono).

Tutte le operazioni viste fin ora, però, riguardano esclusivamente una tipologia d’oggetto che nasce e muore da solo. Cioè un oggetto che non ha nessuna relazione con gli altri oggetti del context.

Questa ovviamente è una grossa limitazione. Infatti, pur potendo creare diverse Entity e quindi salvare diversi NSManagedObject non conosci ancora il sistema per rendere due Entity A e B, di conseguenza anche i ManagedObject, a conoscenza l’uno dell’altro.

Ma cosa significa che due oggetti si conoscono? Come si creano le dipendenze tra oggetti?

Facciamo un piccolo passo indietro e torniamo alla programmazione ad oggetti del linguaggio Swift.

Immagina di voler creare un’applicazione per la memorizzazione dei voti di uno studente. Uno studente segue diverse materie e, di conseguenza, bisogna diversificare i voti per ognuna di esse. Presumibilmente, quindi, dovrai creare due classi. Una classe Materia ed una Voto. La classe Materia conterrà al suo interno un array di Voto che l’applicazione riempirà in base alle interazioni dell’utente con l’app:

Quindi, istanziando un oggetto Materia con nome “Matematica” gli potrai aggiungere diversi oggetti Voto in base al rendimento scolastico dell’utente. Un esempio potrebbe essere il seguente:

A questo punto potremmo dire che, una relazione tra classi, avviene quando una Classe A ha un riferimento ad una classe B.

Dato che una Materia può conservare più oggetti Voto, l’array ci conferma proprio questo, questo tipo di relazione viene chiamata Uno a Molti CoreData e relationship app finale(One-To-Many). Cioè un oggetto ha un riferimento a più oggetti. Come è facile immaginare esistono anche le relazioni One-To-One e Many-To-Many.

Come esercizio, prova a creare delle classi che rispondono a questi due altri modelli di relazione.

Questo stesso identico principio è riportato all’interno del Core Data e ti permetterà di salvare NSManagedObject che sono in relazione con altri NSManagedObject. L’unica differenza, dato che utilizzerai un sistema visuale, sta nella creazione di questi tipi di relazione.

Per andare verso una direzione pratica, creerai un’applicazione che rispecchia l’esempio che ti ho fatto poc’anzi. Quindi realizzerai un’app che salverà i voti di uno studente associandoli ad una materia.

 

Setting del progetto

Crea un nuovo progetto, iOS, Single View Application. Chiamalo DiarioScolastico, seleziona Swift come linguaggio di programmazione e assicurati di aver spuntato la casella per attivare il Core Data.

L’applicazione è composta da un ViewController per l’inserimento dei voti in una materia, una TableViewController per la visualizzazione delle materie e un’altra TableViewController per la visione dei voti relativi ad una materia:

Schermata 2016-03-16 alle 18.37.13

Il progetto di partenza, che puoi scaricare da qui:

[wpdm_package id=’1606′]

É composto da tre Controller principali (oltre al Navigation Controller):

  • InserViewController: Da qui l’utente potrà inserire un nuovo voto e memorizzarlo. Gli basterà riempire tutti i campi e premere aggiungi. Infine potrà andare alla lista delle Materie per visualizzare i voti associati ad ogni materia (premendo il tasto Visualizza Materie verrà invocato il segueToMaterie che porterà alla tabella).
  • MaterieTableViewController: Qui verrà visualizzata la lista delle Materie. Selezionandone una l’utente verrà portato nella seconda tabella, cioè quella con i voti di quella materia.
  • VotiTableViewController: Qui verrà mostrata la lista dei voti associati alla materia selezionata nella precedente tabella.

Come già spiegato nella precedente lezione, utilizzeremo il Core Data grazie ad una classe d’appoggio chiamata CoreDataController. Nel progetto di partenza ho già aggiunto questa classe e più avanti la riempiremo.

Un’altra cosa importante da notare è che ho diviso i file in Group, cioè in sotto cartelle. É importante suddividere i file in quanto più avanti andrai e più complesse si faranno le strutture dei tuoi progetti. Una buona suddivisione in cartelle può aiutarti a mantenere pulito e comprensibile il tuo lavoro.

Le Entity

Spostati nel tuo xcatdatamodeld e aggiungi due Entity. Una chiamata Materia ed una Voto. Nella Entity Materia aggiungi un attributo “nome” di tipo String.

Schermata 2016-03-16 alle 19.00.08

Nell’Entity Voto, aggiungi due attributi: uno chiamato “tipo” con type String ed un altro chiamato “risultato” con tipo Double.

In progetti più sofisticati si potrebbe dividere l’Entity Voto in Entity Voto Orale e Scritto dato che potrebbero avere diverse caratteristiche. Per semplicità assumiamo che possono essere descritti dalla stessa Entity. Quindi, l’utente, si limiterà a cambiare il Segmented Control che provvederà a inserire una stringa in questa proprietà.

Schermata 2016-03-16 alle 19.00.41

one to many relationship core dataCreare relationship tra Entity

Come faccio ad attaccare un Voto ad una Materia?

Ti sarai sicuramente accorto di come tra i tipi di dato degli attributi delle Entity non compare nessun riferimento a: Classi, Array o addirittura altre Entity! Questo è un bel dramma se pensi che la classe Materia, che ti ho mostrato all’inizio del tutorial, aveva come attributo un array di oggetti Voto.

L’unico modo per poter collegare due Entity è, come ti dicevo, di creare delle relazioni. Fortunatamente l’xcatdatamodeld presenta una sezione chiamata Relationships che ti permette di risolvere questo problema.

Per creare una relazione clicca sul tasto “+” del menu Relationships. Rinomina la relazione in “voti” e come Destination setta l’entity Voto:

relationship tra entity materia core data

Inverse Relationship

In questo momento, l’entity Materia ha una relazione con l’entity Voto. Tuttavia, l’entity Voto non conosce chi è il suo partner perché il tipo di relazione è uni direzionale. Un po’ come se io dicessi di essere fidanzato con una ragazza che non sa di essere fidanzata con me!

Fortunatamente le relazioni tra Entity, come quelle reali, possono essere bi direzionale.

Per creare una relazione bi direzionale o Inversa devi creare una relazione dall’entity di destinazione all’entity genitore. Quindi, spostati nell’Entity Voto e crea una relazione con l’Entity Materia.

Xcode in questo momento ti starà mostrando due avvisi! Quale relazione è l’inversa di chi?

Il Core Data non è abbastanza furbo da capire quale relazione è stata creata con il compito di gestire l’entity di destinazione. Cioè, tu vuoi che dall’Entity Materia si raggiunga l’Entity Voto e viceversa. Dato che hai creato due relazioni che fanno in modo che le due Entity si puntino a vicenda, è necessario specificare che le due relazioni siano collegate. Quindi, clicca sulla scritta “No Inverse” e seleziona la relationship a cui collegarti:

Schermata 2016-03-16 alle 19.09.24

Con la relazione inversa, una volta che accederai al Voto dalla Materia e viceversa, sarai in grado di ritornare alla destinazione (quando vedrai il codice te ne renderai conto).

Il grafico dei Modelli

Uno dei punti di forza dell’xcatdatamodeld è quello della visualizzazione delle Entity in grafico. In basso a destra seleziona il secondo bottone nel campo Editor Style.

Grazie a questa visualizzazione riesci a capire al volo come due o più Entity si relazionano tra loro. Se osservi bene, le tue due entity sono collegate da una freccia con doppia testa proprio per indicarti che formano una relazione inversa e bi direzionale. Cioè dall’attributo “voti” raggiungi l’entity Voto e dall’attributo “materia” raggiungi l’entity Materia:

visualizzazione grafica delle Entity

To-Many relationship

La relazione che hai creato poco fa si chiama One-To-One Relationship, cioè una Materia può avere un Voto e viceversa. Tuttavia tu vuoi che ad una Materia corrispondano più voti.

Seleziona la relazione voti e dal Data Model Inspector cambia il Type da To-One a To-Many (se non riesci a selezionarla, fai doppio click su “voti”):

relazione one-to-many entity

In questa maniera una Materia potrà avere più Voti e tutti quei Voti potranno avere una sola Materia di riferimento. Attenzione perché questo non vuol dire che la relazione One-To-Many non consiste nella creazione di un solo oggetto Materia. Bensì date X materie, ognuna di queste potrà avere Y voti associati.

Esiste anche la relazione Many-To-Many. Un esempio può essere quando una Persona vive in più Indirizzi e quando più Indirizzi ospitano più Persone (Persone e Indirizzi sono due Entity).

Core Data e relationship tra Entity

NSManagedObject subclass e relationship

Come spiegato nel tutorial introduttivo la classe NSManagedObject permette di gestire e rappresentare tramite codice i modelli del Core Data. Dato che viene più semplice lavorare con le classi è possibile associare una classe reale ad un modello del Core Data, per farlo bisogna creare una sotto classe della NSManagedObject.

Quindi crea, alla stessa maniera di quanto fatto nel primo tutorial su Core Data, le classi di riferimento per le due Entity. Segui tutti i passaggi di creazione dei file. A fine sequenza dovrebbero comparire i due file per ogni Entity. Quindi in totale dovresti avere quattro file (due classi e due extension):

Schermata 2016-03-18 alle 20.04.31

Le relationship One-To-Many o più in generale le X-To-Many tra NSManagedObject vengono rappresentante come array o NSSet (come dovresti aspettarti dalle introduzioni della lezione). Un NSSet puoi considerarlo come un array costante di oggetti qualsiasi. Nella simbologia di Swift, un NSSet è l’equivalente di un “let array: [AnyObject]”.

Nel caso del CoreData, gli oggetti salvati in memoria sono NSManagedObject, quindi l’array o NSSet conterrà oggetti di questo tipo. Nel nostro progetto la “var voti: NSSet” conterrà gli oggetti Voto che verranno associati a questo oggetto Materia.

Nel caso opposto, cioè nel caso della relazione tra Voto verso Materia (One-To-One), la proprietà “materia” è di tipo Materia. Cioè conterrà l’istanza dell’oggetto NSManagedObject Materia associato a quel Voto.

Per facilitare l’inserimento degli oggetti Voto nell’array/NSSet aggiungi le seguenti funzioni all’extension Materia. Questi due metodi ti faciliteranno l’operazione d’aggiunta ed eliminazione di un Voto dall’array dei voti di una Materia:

Il metodo addVoto(value: Voto) serve ad aggiungere un nuovo Voto all’NSSet voti. Un NSSet è un tipo immutabile, più o meno come una costante. Per potervi inserire un elemento, bisogna utilizzare un metodo della classe NSManagedObject che permette di estrapolare l’NSSet in versione mutabile. Questo compito è affidato alla funzione mutableSetValueForKey(:String) che come parametro vuole passato il nome dell’NSSet da utilizzare.

Alla riga successiva, cioè dopo aver preso il Set mutabile, viene aggiunto il nuovo Voto con il metodo addObject.

Il metodo remomeVoto(value: Voto) esegue lo stesso procedimento di recupero del set e, invece d’aggiungervi un oggetto, lo elimina. Nel dettaglio, verrà eliminato l’oggetto Voto passato come parametro della funzione.

Il CoreDataController

Come già spiegato nella precedente lezione, uno dei sistemi più semplici per interagire con il Core Data è quello di creare una classe ad hoc dove inserire tutti i metodi per il controllo della memoria.

Nel progetto di partenza che avrai già scaricato troverai già il file CoreDataController.swift. Nel caso in cui stessi seguendo il tutorial per conto tuo, provvedi a creare il seguente file:

Dato che qui le cose cominciano a complicarsi un po’. Se sei un nuovo sviluppatore ti consiglio di dare un’occhiata ai miei due corsi:

Salvare e recuperare dati dal Core Data

Ricordati che dividere un problema in tanti sotto problemi è la chiave per risolvere qualsiasi ostacolo. Alla nostra applicazione servono essenzialmente tre funzioni principali. Una funzione per l’aggiunta di una Materia in memoria. Un’altra per il recupero di suddetta materia e l’ultima per l’aggiunta di un Voto all’array dei voti di una Materia.

Adesso vedremo come creare tutte queste funzioni più altre che ti aiuteranno nella gestione efficiente del codice ricorsivo (cioè del codice che si ripete in più funzioni).

addNuovaMateria

Comincia aggiungente la seguente funzioni:

Il funzionamento è abbastanza semplice. Il metodo crea un nuovo oggetto NSManagedObject con lo stesse caratteristiche dell’entityMateria. Infine, setta il nome della materia uguale al parametro passato e chiama la funzione salvaContext() (vedi sotto).

Credo che fin qui non dovrebbe esserci nulla di nuovo. I passaggi scritti sono gli stessi che ho spiegato nel precedente tutorial dove ti ho fatto vedere come aggiungere un oggetto NSManagedObject nella memoria (ovvero nel tuo NSManagedObjectContext che è definito nell’AppDelegate).

  • Perché la funzione è private e ritorna un oggetto Materia?
    Perché questa funzione verrà utilizzata da un gestore delle materie dell’applicazione. Cioè l’utente non sarà in grado di creare materia con questa funzione bensì con l’utilizzo di un altro metodo che vedrai tra poco.

salvaContext

Dato che il metodo di salvataggio del Managed Object Context verrà utilizatto in molte funzioni, estrapoliamolo ed aggiungiamolo in una funzione ad hoc che verrà richiamata dalle altre. Questa funzione oltre a salvare, gestirà i casi d’errore del salvataggio:

Ogni modifica, inserimento o cancellazione di un NSManagedObject all’interno del tuo NSManagedObjectContext va reso persistente con l’invocazione del metodo .save(), pena la perdita delle informazioni. In più, dato che questa funzione è di tipo throws va gestita utilizzando un blocco do try catch. In questa maniera, se il context non riuscisse a salvare, modificare o cancellare l’oggetto verrà sollevata una eccezione che verrà gestita dal blocco catch.

cercaMateria

Dato che il layout d’inserimento di un voto associato ad una materia prevede la scrittura sia del nome della materia che del voto, è probabile che non sempre la materia inserita sia nuova. Ovvero, se al primo avvio l’utente inserisce Matematica come nome della materia ed al secondo avvio inserisce nuovamente la stessa, dobbiamo prevedere un sistema che eviti la duplicazione degli oggetti importanti.

Cioè, per un utente, materie che si chiamano “Matematica” ne esisterà solamente una e, automaticamente, tutti i voti che l’utente gli aggiungerà dovranno essere collegati sempre allo stesso oggetto.

Questo è il motivo che mi ha spinto a creare una funzione che permette di cercare e contemporaneamente aggiungere una Materia. Il metodo crea una nuova materia nel caso in cui non esistesse e se dovesse essere già stata creata la restituisce.

La funzione ha due scopi:

  • Il primo è quello di cercare e ritornare, quando esiste, il riferimento ad una Materia (case dello switch con valore 0).
  • Il secondo è quello di creare una Materia quando non esiste (switch case 1).

La ricerca all’interno del context avviene mediante l’invocazione del metodo executeFetchRequest che fa richiesta, al context, di restituire un NSArray contenenti tutti i dati simili all’entity Materia. L’oggetto NSFetchRequest vuole come parametro il nome dell’Entity da cercare.

La funzione da utilizzare per cercare un’informazione all’interno del CoreData è la executeFetchRequest che come parametro ha un predicate ovvero un oggetto che permette di scartare e selezionare solo una tipologia di oggetti (ho spiegato nel dettaglio come funziona nella precedente lezione). Nel tuo caso, il predicate, farà in modo che verrà sempre ritornato un Array contenente le materie con lo stesso nome inserito nel parametro della funzione cercaMateria.

Se l’array ritornato ha 0 elementi inserisce nel context la materia cercata invocando la funzione addNuovaMateria (ecco dove viene utilizzata quella funzione privata). Se invece l’array ha 1 solo elemento, quindi la materia esiste nel context, restituisce il suo riferimento.

Con questo sistema sarà impossibile inserire più di una Materia con lo stesso nome.

Le funzioni per il salvataggio e la gestione delle relazioni

Grazie alla funzione cercaMateria(nome: String) sei in grado di recuperare un NSManagedObject Materia univoco per ogni materia che l’utente inserirà. Adesso, creerai la funzione per l’aggiunta di un Voto alla materia.

Ti ricordo che alla classe Materia ti ho fatto aggiungere una funzione chiamata addVoto(:Voto) che serviva ad inserire un nuovo Voto all’interno dell’array o NSSet dei voti della materia.

Aggiungi la seguente funzione:

La funzione ha come parametri:

  • materia: Una String per il nome della Materia nella quale inserire il voto.
  • voto: Un Double per il valore del voto.
  • tipo: E una stringa che indicherà il tipo di voto: Orale o Scritto.

Il metodo comincia creando un NSManagedObject Voto. Successivamente cerca la materia a cui assegnare tale voto con il metodo cercaMateria a cui viene passato il parametro “materia” della funzione.

Dato che il Voto ha una relazione One-To-One con la Materia passiamo il riferimento della Materia cercata all’attributo materia dell’oggetto nuovoVoto. Grazie a questo passaggio, sarai in grado di accedere alla materia a cui è associato tale voto.

Successivamente vengono passati i valori dei parametri “voto” e “tipo” ai rispettivi attributi dell’oggetto nuovoVoto. Infine, il nuovoVoto viene agganciato all’NSSet della materia corrente con il metodo addVoto.

La ciliegina sulla torta è sempre il famosissimo salvaContext() per rendere effettive le modifiche al tuo NSManagedObjectContext.

La funzione per il recupero dei voti di una Materia

L’ultima funzione che manca è quella per il recupero dei voti, quindi aggiungi:

La funzione stampaVotiMateria() recupera e stampa gli oggetti dell’NSSet di una Materia. Gli oggetti di un NSSet possono essere qualsiasi, quindi per essere recuperati vanno estrapolati tutti con la funzione allObjects, la quale restituisce un Array di AnyObject che opportunamente viene trattato e convertito come array di Voto (as [Voto]).

Poi, come per un array normale, la funzione itera tutti gli elementi presenti nell’array e li stampa.

Il test del CoreDataController

Adesso, dato che c’è tantissima carne sul fuoco, è arrivato il momento di provare tutte le funzioni. Spostati nel file InsertViewController.swift che contiene la classe associata al primo VC dell’applicazione e, all’IBAction del bottone per l’inserimento del nuovo Voto, aggiungi il seguente codice:

Il metodo nella prima parte esegue dei normalissimi controlli guard sulla presenza del testo nei due text field. Il terzo guard converte e controlla il testo della seconda text field in Double dato che verrà salvato come numero e non come testo.

Se uno dei guard dovesse fallire si uscirebbe dalla funzione prima dell’interazione con il Core Data. Questo è uno dei vantaggi dell’utilizzo dell’istruzione guard e della suddivisione dei codici in classi e funzioni. Nel nostro caso, il Core Data viene richiamato solo dopo che tutti i guard sono stati verificati con successo.

Infine viene richiamato il metodo addVotoInMateria accedendo al Singleton della classe CoreDataController. Ai tre parametri vengono passati rispettivamente:

  • Il nome della materia a cui inserire il voto. Ti ricordo che grazie alla funzione cercaMateria(:String) sarai in grado di accedere sempre allo stesso voto e contemporaneamente di creare una Materia qualora non esistesse.
  • Il voto convertito in Double.
  • Il testo selezionato nel segment controller. Il metoto titleForSegmentAtIndex ti permette di accedere al titolo che hai scritto nei due bottoni del segment (“Orale” e “Scritto”). Sei in grado di ottenere il titolo per il segment corretto grazie alla proprietà selectedSegmentIndex che restituisce l’indice del bottone selezionato.

CoreData e relationship primo test

Et voilà! Hai appena creato la tua prima applicazione per la gestione e la creazione di relazioni tra modelli del Core Data!!

Tabelle e Core Data

Adesso che la pagina d’inserimento dei dati in memoria funziona correttamente è arrivato il momento di recuperare e mostrare queste informazioni all’interno della tabella successiva.

La tabella successiva, ovvero la MaterieTableViewController, come ho spiegato all’inizio della lezione serve per la visualizzazione dei soli nomi delle Materie inserite. Mentre, la tabella successiva, visualizzerà i voti associati ad un elemento selezionato dalla tabelle delle materie.

Comincia aggiungendo una nuova funzione al tuo CoreDataController. Questa funzione servirà a recuperare tutte le materie dal context:

Adesso nel tuo MaterieTableViewController aggiungi una proprietà chiamata array_materie dell’omonimo tipo e, nel metodo viewDidLoad, passagli il valore restituito dal metodo recuperaMaterie:

L’array delle materie verrà utilizzato dai metodi della tabella per poter visualizzare le varie materie dell’utente.

In questo momento però, il nostro array ha un enorme problema. Se l’utente non aggiunge alcune materie, questo, potrebbe essere nil e di conseguenza non potrai utilizzarlo per riempire la tabella. 

Come risolviamo questo problema? Potresti optare per tre possibili soluzioni:

  • Bloccare nel ViewController precedente lo spostamento al VC delle tabelle fin quando l’utente non inserisci un Voto. Cioè nel bottone che invoca il segue metti un if che controlla il numero di materie presenti nel context. Se questo numero è maggiore di 0 allora l’utente può andare alla tabella.
  • Aggiungere delle Materie di default in modo da non doverle creare perché già assegnate dall’applicazione. Questo è uno dei sistemi che utilizzano parecchie applicazioni di questo tipo. Questa soluzione comporta però la conoscenza a priori delle materie di uno studente. Se sei stato studente sai che ogni scuola ha diverse materie, quindi, io scarterei questa implementazione barbara.
    Al massimo creerei un numero predefinito di indirizzi scolastici/universitari che l’utente potrà scegliere all’inizio e quando configura l’applicazione. Ma anche qui, cosa succede quando lo studente cambia scuola? tutti gli indirizzi hanno le stesse materie?
  • Il terzo e ultimo sistema potrebbe essere quello di visualizzare una tabella senza elementi. Semplice, facile e veloce. Al massimo un alert view potrebbe consigliare all’utente di inserire dei voti o delle materie.

Ci sono altre soluzioni? Of course. A te la scelta di scegliere quella più opportuna. In questa lezione passeremo per la terza via, ovvero quella più veloce e semplice.

A questo punto il gioco è abbastanza semplice. Dimentica che stai lavorando con il Core Data. L’array delle materie è già stato riempito (oppure no). Essendo un array di oggetti, dovresti già sapere come riempire la tua tabella.

Ricordati che nel mio progetto ho già impostato un Cell Identifier per la cella che si chiama “cellMateria”. Se stai utilizzando un tuo progetto, ricordati di mettere l’identifier alla cella della tua tabella. In più, assicurati di aver inserito il performSegueWithIdentifier nel bottone del VC precedente. 

Fai un test dell’applicazione. Dato che già avevamo inserito delle materie e dei voti, la tabella dovrebbe riempirsi con quelle materie:

CoreData e relationship secondo test

Qui entra veramente in gioco il pattern Model View Controller. Il Model della nostra applicazione è contenuto tutto all’interno del CoreDataController. Il Controller della tabella, cioè la MateriaTableViewController, non si preoccupa minimamente di come i dati vengano conservati in memoria. Bensì si limita a richiamare un metodo del Model (il CoreDataController) che gli restituirà le informazioni.

Nota anche come la classe MaterieTableViewController è semplice ed intuitiva da leggere ed interpretare. Pensa a come sarebbe senza la presenza del CoreDataController. Te lo dico io, un vero e proprio caos!

Al di là di tutto. Se dovessero esserci problemi di comprensione, lascia pure un commento. Mi rendo conto che in questi ultimi passaggi sia andato decisamente più veloce.

La tabella dei Voti

L’ultimo step è quello di riempire la tabella dei voti di una materia. Al solito, come per la funzione stampaVoti, basterà recuperare la materia e di conseguenza si conoscerà anche l’array dei voti.

Anche qui una domanda. É necessario aggiungere una nuova funzione al CoreDataController solo per il recupero dell’array dei voti? Non possiamo utilizzare l’array delle materie calcolato nella tabella delle materie?

Stesse domande, stesse risposte. Tutto dipende dal progetto in questione. In questo caso non creeremo una nuova funzione, bensì utilizzeremo il l’array già calcolato dalla prima tabella per poi passare la materia, o meglio l’array dei voti contenuto nell’NSSet, alla seconda tabella.

Per prima cosa implementa il metotodo didSelectRowAtIndexPath nella MaterieTableViewController. Qui recupera la materia corrente e passala al sender del segue che collega alla tabella dei voti:

La proprietà voti è un NSSet. Per poter leggere tutti i suoi valori come un array del linguaggio Swift devi utilizzare l’attributo allObjects che restituisce gli elementi del set in un array di AnyObject. Questo array viene successivamente downcastato in un array di voti. Dopo aver recuperato l’array dei voti, verrà invocato il segueToVoti che trasporterà l’array al VC di destinazione.

Nel metodo prepareForSegue accedi al VC di destinazione e passa alla proprietà array_voti, che creerai appositamente, l’array dei voti:

Infine, modifica la classe VotiTableViewController. Aggiungi la proprietà array_voti: [Voto] perché a questa verranno inviati i dati dal VC precedente e modifica tutti i metodi della tabella di conseguenza:

CoreData e relationship terzo test

Considerazioni e Download

Uno dei problemi che affligge un nuovo sviluppatore, anche se ormai tanto nuovo non dovresti essere, è quello di non intravedere velocemente la risoluzione di un problema complesso come magari potrebbe essere quello di mettere insieme Core Data e tabelle.

Per esempio, invece di domandarti “come posso caricare i dati presenti nel Core Data in una tabella?” prova a dividere la domanda in domande più semplici: “come recupero i dati dal core data?”, “che dati vuole una tabella per essere riempita?”. Se sai riempire una tabella dato un array, che sia di stringhe o di oggetti marziani non deve assolutamente trarti in inganno.

La capacità di intravedere una soluzione semplice ad un problema complesso dovrebbe essere la reale caratteristica di uno sviluppatore. Il non focalizzarsi sull’utilizzo di un framework, su una classe ecc è solamente il risultato finale e la concretizzazione del percorso. Saper, invece, trovare una soluzione generale e astratta “ci vorrà sicuramente un array, una classe o un database” è ciò che ti permetterà di arrivare alla parte pratica in maniera automatica.

Ad ogni modo, quello che ti consiglio adesso è di provare a creare applicazioni simili a questa provando ad ampliare il data model con nuove Entity e Relazioni.

[sociallocker][wpdm_package id=’1607′][/sociallocker]

Buona Programmazione!

Start typing and press Enter to search

Come creare un gioco per iOS con SpriteKit e SwiftIntroduzione alle notifiche Push Locali in iOS con Swift