Swift From Scratch Ereditarietà e protocolli

Se hai letto le lezioni precedenti di questa serie, dovresti avere una buona conoscenza dei fondamenti del linguaggio di programmazione Swift ormai. Abbiamo parlato di variabili, costanti e funzioni, e nella lezione precedente abbiamo trattato le basi della programmazione orientata agli oggetti in Swift.

Mentre i parchi giochi sono un ottimo strumento per giocare con Swift e imparare la lingua, è il momento di andare avanti e creare il nostro primo progetto Swift in Xcode. In questa lezione, creeremo le basi di un'applicazione semplice da fare usando Xcode e Swift. Lungo la strada, impareremo di più sulla programmazione orientata agli oggetti e daremo un'occhiata più da vicino all'integrazione di Swift e Objective-C.

Prerequisiti

Se desideri seguirmi, assicurati di aver installato Xcode 8.3.2 o successivo sulla tua macchina. Xcode 8.3.2 è disponibile dall'App Store di Apple.

1. Impostazione del progetto

Passo 1: Scegli un modello

Avvia Xcode 8.3.2 o versioni successive e seleziona Nuovo> Progetto ... dal File menu. Dal iOS sezione, scegliere il Applicazione vista singola modello e clicca Il prossimo.

Passaggio 2: configura il progetto

Assegna un nome al progetto Fare e impostare linguaggio veloce. Assicurarsi dispositivi è impostato per i phone e le caselle di controllo in basso sono deselezionate. Clic Il prossimo continuare.

Dillo a Xcode dove desideri archiviare il tuo progetto e fai clic Creare in basso a destra per creare il tuo primo progetto Swift.

2. Anatomia del progetto

Prima di continuare il nostro viaggio in Swift, prendiamoci un momento per vedere cosa Xcode ha creato per noi. Se sei nuovo nello sviluppo di Xcode e iOS, allora la maggior parte di questo sarà nuovo per te. Lavorando con un progetto Swift, tuttavia, otterrai una migliore sensazione di come appaiono le classi e le strutture e come si comportano in Swift.

Il modello di progetto non differisce molto da un progetto creato con Objective-C come linguaggio di programmazione. Le differenze più importanti sono legate al AppDelegate e ViewController classi.

Se in passato hai lavorato con Objective-C, noterai che il modello di progetto contiene meno file. Non ci sono intestazione (.h) o attuazione (.m) file da trovare nel nostro progetto. In Swift, le classi non hanno un file di intestazione separato in cui viene dichiarata l'interfaccia. Invece, una classe è dichiarata e implementata in un singolo .veloce file.

Il nostro progetto contiene attualmente due file Swift, uno per il AppDelegate classe, AppDelegate.swift, e un altro per il ViewController classe, ViewController.swift. Il progetto include anche due storyboard, Main.storyboard e LaunchScreen.storyboard. Lavoreremo con lo storyboard principale un po 'più avanti in questa lezione. Attualmente contiene solo la scena per il ViewController classe.

Ci sono alcuni altri file e cartelle inclusi nel progetto, ma per il momento ignoreremo quelli. Non svolgono alcun ruolo importante nell'ambito di questa lezione.

3. Ereditarietà

La prima cosa che tratteremo in questa lezione è l'ereditarietà, un paradigma comune nella programmazione orientata agli oggetti. In Swift, solo le classi possono ereditare da un'altra classe. In altre parole, le strutture e le enumerazioni non supportano l'ereditarietà. Questa è una delle principali differenze tra classi e strutture.

Aperto ViewController.swift per vedere l'eredità in azione. L'interfaccia e l'implementazione del ViewController la classe è piuttosto scheletrica, il che rende più facile concentrarsi sull'essenziale.

UIKit

In cima a ViewController.swift, dovresti vedere una dichiarazione di importazione per il framework UIKit. Ricorda che il framework UIKit fornisce l'infrastruttura per la creazione di un'applicazione iOS funzionale. La dichiarazione di importazione in alto rende disponibile questa infrastruttura ViewController.swift.

importa UIKit

superclasse

Sotto la dichiarazione di importazione, definiamo una nuova classe chiamata ViewController. I due punti dopo che il nome della classe non si è tradotto è di tipo come abbiamo visto in precedenza in questa serie. Invece, la classe dopo i due punti è la superclasse del ViewController classe. In altre parole, il seguente snippet potrebbe essere letto come definiamo una classe chiamata ViewController che eredita da UIViewController.

class ViewController: UIViewController 

Questo spiega anche la presenza della dichiarazione di importazione nella parte superiore di ViewController.swift dal momento che UIViewController la classe è definita nel framework UIKit.

Sostituzioni

Il ViewController la classe include attualmente due metodi, ma si noti che ciascun metodo è preceduto dal prefisso oltrepassare parola chiave. Ciò indica che i metodi sono definiti nella superclasse della classe o più in alto nell'albero di ereditarietà e sono sovrascritti dal ViewController classe.

class ViewController: UIViewController override func viewDidLoad () super.viewDidLoad () override func didReceiveMemoryWarning () super.didReceiveMemoryWarning ()

Il oltrepassare il costrutto non esiste in Objective-C. In Objective-C, si implementa un metodo sottoposto a override in una sottoclasse senza indicare esplicitamente che sostituisce un metodo più in alto nella struttura di ereditarietà. Il runtime Objective-C si occupa del resto.

Mentre lo stesso è vero in Swift, il oltrepassare le parole chiave aggiungono sicurezza al metodo prioritario. Perché abbiamo prefisso il viewDidLoad () metodo con il oltrepassare parola chiave, Swift aspetta questo metodo nella superclasse della classe o più in alto nell'albero dell'eredità. In poche parole, se si esegue l'override di un metodo che non esiste nell'albero di ereditarietà, il compilatore genererà un errore. Puoi testare questo errore ortografando il viewDidLoad () metodo come mostrato di seguito.

4. Interfaccia utente

Dichiarando gli sbocchi

Aggiungiamo una vista tabella al controller della vista per visualizzare un elenco di cose da fare. Prima di farlo, dobbiamo creare uno sbocco per la vista tabella. Uno sbocco non è altro che una proprietà visibile e impostabile in Interface Builder. Dichiarare uno sbocco nel ViewController classe, abbiamo il prefisso della proprietà, una variabile, con il @IBOutlet attributo.

class ViewController: UIViewController @IBOutlet var tableView: UITableView! override func viewDidLoad () super.viewDidLoad () override func didReceiveMemoryWarning () super.didReceiveMemoryWarning ()

Si noti che la presa è facoltativamente non imballata. A cosa? Lasciatemi dire che uno sbocco deve sempre essere un tipo facoltativo. La ragione è semplice. Ogni proprietà del ViewController la classe deve avere un valore dopo l'inizializzazione. Una presa, tuttavia, è collegata solo all'interfaccia utente in runtime dopo il ViewController l'istanza è stata inizializzata quindi il tipo facoltativo.

Apetta un minuto. Il tableView outlet è dichiarato come facoltativo da scartare facoltativo, non facoltativo. Nessun problema. Possiamo dichiarare il tableView presa facoltativa sostituendo il punto esclamativo nello snippet precedente con un punto interrogativo. Questo si compilerebbe bene. Tuttavia, ciò significherebbe anche che avremmo bisogno di scartare esplicitamente la proprietà ogni volta che vogliamo accedere al valore memorizzato nell'opzionale. Ciò diventerebbe rapidamente macchinoso e prolisso.

Invece, dichiariamo il tableView outlet come opzione facoltativa da scartare, il che significa che non è necessario scartare esplicitamente l'opzione se è necessario accedere al suo valore. In breve, un facoltativo facoltativo da scartare è un optional, ma possiamo accedere al valore memorizzato nell'opzionale come una variabile regolare. La cosa importante da tenere a mente è che l'applicazione si bloccherà se si tenta di accedere al suo valore se non è stato impostato alcun valore. Questo è il trucco. Se la presa è collegata correttamente, tuttavia, possiamo essere sicuri che la presa sia impostata quando proviamo ad accedervi per la prima volta.

Collegamento di prese

Con la presa dichiarata, è ora di collegarlo in Interface Builder. Aperto Main.storyboard, e selezionare il controller della vista. Scegliere Incorporare in> Controller di navigazione dal editore menu. Questo imposta il controller della vista come controller della vista radice di un controller di navigazione. Non preoccuparti di questo per ora.

Trascina a UITableView istanza dal Libreria di oggetti per visualizzare la vista del controller e aggiungere i vincoli di layout necessari. Con la vista tabella selezionata, apri il Connections Inspector e imposta la vista della tabella fonte di dati e delegare punti vendita al controller della vista.

Con il Connections Inspector ancora aperto, selezionare il controller della vista e connettere il tableView sbocco alla vista del tavolo che abbiamo appena aggiunto. Questo collega il tableView sbocco del ViewController classe alla vista tabella.

5. Protocolli

Prima di poter creare ed eseguire l'applicazione, è necessario implementare il UITableViewDataSource e UITableViewDelegate protocolli nel ViewController classe. Ciò comporta diverse cose.

Passaggio 1: conformità ai protocolli

Dobbiamo dire al compilatore che il ViewController classe conforme al UITableViewDataSourceUITableViewDelegate protocolli. La sintassi è simile a quella in Objective-C.

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate ...

I protocolli a cui la classe si conforma sono elencati dopo la superclasse, UIViewController nell'esempio sopra. Se una classe non ha una superclasse, cosa non rara in Swift, i protocolli sono elencati immediatamente dopo il nome della classe e il colon.

Passaggio 2: implementazione di UITableViewDataSource Protocollo

Perché il UITableViewDelegate il protocollo non definisce i metodi richiesti, stiamo solo implementando il UITableViewDataSource protocollo per ora. Prima di farlo, creiamo una proprietà variabile per archiviare gli elementi delle cose da fare che andremo a elencare nella vista tabella.

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate @IBOutlet var tableView: UITableView! var items: [String] = [] ...

Dichiariamo una proprietà variabile elementi di tipo [Stringa] e imposta un array vuoto, [], come il valore iniziale. Questo dovrebbe sembrare familiare ora. Quindi, implementiamo i due metodi richiesti di UITableViewDataSource protocollo.

Il primo metodo richiesto, numberOfRows (inSection :), è facile. Restituiamo semplicemente il numero di elementi memorizzati nel file elementi proprietà.

func tableView (_ tableView: UITableView, sezione numberOfRowsInSection: Int) -> Int return items.count

Il secondo metodo richiesto, cellForRow (a :), ha bisogno di una spiegazione Usando la sintassi del pedice, chiediamo elementi per l'articolo che corrisponde alla riga corrente.

func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell // Fetch Item let item = items [indexPath.row] // Dequeue Cell let cella = tableView.dequeueReusableCell (withIdentifier: "TableViewCell", per: indexPath // Configure Cell cell.textLabel? .Text = item return cell

Quindi chiediamo la vista tabella per una cella con identificatore "TableViewCell", passando il percorso dell'indice per la riga corrente. Si noti che memorizziamo la cella in una costante, cellula. Non c'è bisogno di dichiarare cellula come variabile.

Nella prossima riga di codice, configuriamo la cella di visualizzazione tabella, impostando il testo dell'etichetta di testo con il valore di articolo. Si noti che in Swift il textLabel proprietà di UITableViewCell è dichiarato come un tipo opzionale quindi il punto interrogativo. Questa riga di codice potrebbe essere letta come imposta l'etichetta del testo testo proprietà a articolo Se textLabel non è uguale a zero. In altre parole, l'etichetta del testo testo la proprietà è impostata solo se textLabel non è zero. Si tratta di un costrutto di sicurezza molto conveniente in Swift noto come concatenamento opzionale.

Passaggio 3: riutilizzo delle celle

Ci sono due cose che dobbiamo risolvere prima di costruire l'applicazione. Per prima cosa, dobbiamo dire alla tabella che ha bisogno di usare il UITableViewCell classe per creare nuove celle di visualizzazione tabella. Lo facciamo invocando registerClass (_: forCellReuseIdentifier :), passando nel UITableViewCell classe e l'identificatore di riutilizzo che abbiamo usato in precedenza, "TableViewCell". Aggiorna il viewDidLoad () metodo come mostrato di seguito.

override func viewDidLoad () super.viewDidLoad () // Registra classe per cella Reuse tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")

Passaggio 4: aggiunta di elementi

Al momento non abbiamo elementi da mostrare nella visualizzazione tabella. Questo è facilmente risolto popolando il elementi proprietà con alcuni elementi da fare. Ci sono diversi modi per farlo. Ho scelto di popolare il elementi proprietà nel viewDidLoad () metodo come mostrato di seguito.

override func viewDidLoad () super.viewDidLoad () // Popola Articoli items = ["Acquista latte", "Termina tutorial", "Riproduci Minecraft"] // Registra classe per cella Riutilizza tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")

6. Costruisci ed esegui

È tempo di prendere la nostra domanda per un giro. Selezionare Correre da Xcode's Prodotto menu o hit Comando-R. Se hai seguito, dovresti ottenere il seguente risultato.

Nota che ho aggiunto un titolo, Fare, nella parte superiore della vista nella barra di navigazione. Puoi fare lo stesso impostando il titolo proprietà del ViewController istanza nel viewDidLoad () metodo.

override func viewDidLoad () super.viewDidLoad () // Imposta titolo titolo = "Da fare" // Popola articoli Articoli = ["Acquista latte", "Termina tutorial", "Riproduci Minecraft"] // Registra classe per riutilizzo cella tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")

Conclusione

Anche se abbiamo appena creato una semplice applicazione, hai imparato un bel po 'di cose nuove. Abbiamo esplorato metodi di ereditarietà e sovrascrittura. Abbiamo anche trattato i protocolli e come adottare il UITableViewDataSource protocollo nel ViewController classe. La cosa più importante che hai imparato, tuttavia, è come interagire con le API di Objective-C.

È importante capire che le API dell'SDK di iOS sono scritte in Objective-C. Swift è stato progettato per essere compatibile con queste API. Sulla base dei precedenti fallimenti, Apple ha capito che Swift doveva essere in grado di connettersi all'SDK iOS senza dover riscrivere ogni singola API in Swift.

La combinazione di Objective-C e Swift è possibile, ma ci sono alcune avvertenze che esploreremo più in dettaglio mentre andiamo avanti. A causa dell'attenzione incessante di Swift sulla sicurezza, abbiamo bisogno di prendere qualche ostacolo di tanto in tanto. Tuttavia, nessuno di questi ostacoli è troppo grande come lo scopriremo nella prossima lezione in cui continuiamo a lavorare sulla nostra applicazione da fare.

Nel frattempo, dai uno sguardo ad alcuni dei nostri altri corsi e tutorial sullo sviluppo di iOS in lingua Swift!