Swift From Scratch Arv och protokoll

Om du har läst de tidigare lektionerna i denna serie borde du ha en bra förståelse av grunden för Swift-programmeringsspråket nu. Vi pratade om variabler, konstanter och funktioner, och i den tidigare lektionen omfattade vi grunderna för objektorienterad programmering i Swift.

Medan lekplatser är ett bra verktyg för att leka med Swift och lära sig språket är det dags att gå vidare och skapa vårt första Swift-projekt i Xcode. I den här lektionen ska vi skapa grunden för en enkel att göra-ansökan med hjälp av Xcode och Swift. Under tiden kommer vi att lära oss mer om objektorienterad programmering och vi kommer också att titta närmare på integrationen av Swift och Objective-C.

förutsättningar

Om du vill följa med mig, se till att du har Xcode 8.3.2 eller högre installerad på din maskin. Xcode 8.3.2 är tillgänglig från Apples App Store.

1. Projektinställningar

Steg 1: Välj en mall

Starta Xcode 8.3.2 eller högre och välj Nytt> Projekt ... från Fil meny. Från iOS avsnitt, välj Enkel visningsprogram mall och klicka Nästa.

Steg 2: Konfigurera projektet

Namn på projektet Att göra och ställa in Språk till Snabb. Se till enheter är satt till iPhone och kryssrutorna längst ner är avmarkerade. Klick Nästa att fortsätta.

Berätta Xcode där du vill spara ditt projekt och klicka Skapa längst ned till höger för att skapa ditt första Swift-projekt.

2. Projektanatomi

Innan vi fortsätter vår resa till Swift, låt oss ta en stund för att se vad Xcode har skapat för oss. Om du är ny för Xcode och iOS-utveckling, kommer det mesta av det nya för dig. Genom att arbeta med ett Swift-projekt får du en bättre känsla av vilka klasser och strukturer som ser ut och hur de beter sig i Swift.

Projektmallen skiljer sig inte mycket från ett projekt som skapats med Objective-C som programmeringsspråk. De viktigaste skillnaderna är relaterade till AppDelegate och ViewController klasser.

Om du har arbetat med Objective-C tidigare så märker du att projektmallen innehåller färre filer. Det finns ingen rubrik (.h) eller genomförande (.m) filer som finns i vårt projekt. I Swift har klasser ingen separat headerfil där gränssnittet är deklarerat. I stället förklaras en klass och implementeras i en enda .snabb fil.

Vårt projekt innehåller för närvarande två Swift-filer, en för AppDelegate klass, AppDelegate.swift, och en annan för ViewController klass, ViewController.swift. Projektet innehåller också två storyboards, Main.storyboard och LaunchScreen.storyboard. Vi arbetar med huvud storyboardet lite senare i den här lektionen. Det innehåller för närvarande bara scenen för ViewController klass.

Det finns några andra filer och mappar som ingår i projektet, men vi kommer att ignorera dem för nu. De spelar ingen viktig roll inom ramen för denna lektion.

3. Arv

Det första vi kommer att påverka i denna lektion är arv, ett gemensamt paradigm i objektorienterad programmering. I Swift kan endast klasser arva från en annan klass. Med andra ord stöder strukturer och uppräkningar inte arv. Detta är en av de viktigaste skillnaderna mellan klasser och strukturer.

Öppna ViewController.swift att se arv i handling. Gränssnittet och genomförandet av ViewController klassen är ganska nakna ben, vilket gör det lättare för oss att fokusera på de väsentliga.

UIKit

På toppen av ViewController.swift, Du bör se ett importdeklaration för UIKIT-ramverket. Kom ihåg att UIKit-ramen tillhandahåller infrastrukturen för att skapa en funktionell iOS-applikation. Importdeklarationen överst gör denna infrastruktur tillgänglig för oss ViewController.swift.

importera UIKit

super

Nedanför importdeklarationen definierar vi en ny klass som heter ViewController. Kolon efter klassnamnet översätter inte till är av typ som vi såg tidigare i denna serie. I stället är klassen efter tjocktarmen superklassen hos ViewController klass. Med andra ord kan följande stycke läsas som vi definierar en klass som heter ViewController som ärar från UIViewController.

klass ViewController: UIViewController 

Detta förklarar också närvaron av importdeklarationen högst upp på ViewController.swift sedan UIViewController klassen definieras i UIKit-ramen.

åsido~~POS=TRUNC

De ViewController klassen innehåller för närvarande två metoder, men märker att varje metod är prefixad med åsidosätta nyckelord. Detta indikerar att metoderna definieras i klassens superklass - eller högre upp i arvsträdet - och överstyrs av ViewController klass.

klass ViewController: UIViewController override func viewDidLoad () super.viewDidLoad () åsidosätta func didReceiveMemoryWarning () super.didReceiveMemoryWarning ()

De åsidosätta konstruktion existerar inte i mål-C. I Mål-C implementerar du en överdriven metod i en underklass utan att uttryckligen ange att det överstyrar en metod högre upp i arvsträdet. Objective-C runtime tar hand om resten.

Samtidigt är det samma i Swift, den åsidosätta nyckelord lägger till säkerhet för överordnad metod. Eftersom vi har prefixat viewDidLoad () metod med åsidosätta nyckelord, Swift förväntar den här metoden i klassens superklass eller högre upp på arvsträdet. Enkelt uttryckt, om du åsidosätter en metod som inte existerar i arvsträdet, kommer kompilatorn att kasta ett fel. Du kan testa detta genom att felstava viewDidLoad () metod som visas nedan.

4. Användargränssnitt

Deklarera försäljningsställen

Låt oss lägga till en tabellvy för vykontrollen för att visa en lista över aktiviteter. Innan vi gör det måste vi skapa ett uttag för tabellvyn. Ett uttag är inget annat än en egenskap som är synlig för och kan ställas in i Interface Builder. Att anmäla ett uttag i ViewController klass, vi prefix egendomen, en variabel, med @IBOutlet attribut.

klass ViewController: UIViewController @IBOutlet var tableView: UITableView! åsidosätta func viewDidLoad () super.viewDidLoad () åsidosätta func didReceiveMemoryWarning () super.didReceiveMemoryWarning ()

Observera att uttaget är en implicit oöppnad tillval. En Vad? Låt mig börja med att säga att ett uttag alltid måste vara en valfri typ. Anledningen är enkel. Varje fastighet hos ViewController klassen måste ha ett värde efter initialiseringen. Ett uttag är emellertid endast anslutet till användargränssnittet vid körning efter ViewController exemplet har initialiserats, följaktligen den valfria typen.

Vänta en minut. De Tableview utlopp förklaras som en implicit oöppnad valfri, inte en valfri. Inga problem. Vi kan deklarera Tableview uttag som tillval genom att ersätta utropstecken i ovanstående kod med ett frågetecken. Det skulle sammanställa bara bra. Detta skulle emellertid också innebära att vi skulle behöva explicit ta bort fastigheten varje gång vi vill komma åt det värde som lagrats i frivilligt. Detta skulle snabbt bli besvärligt och verbalt.

I stället förklara vi Tableview utlopp som en implicit oöppnad valfri, vilket innebär att vi inte behöver uttrycka bort valfri om vi behöver komma åt dess värde. Kort sagt, en imponerande oöppnad valfri är valfri, men vi kan komma åt det värde som lagrats i frivilligt som en vanlig variabel. Det viktiga att komma ihåg är att din ansökan kommer att krascha om du försöker komma åt dess värde om inget värde har ställts in. Det är gotchaen. Om uttaget är ordentligt anslutet kan vi dock vara säker på att uttaget är inställt när vi först försöker komma åt det.

Anslutning av uttag

Med utloppet deklarerat är det dags att ansluta det i Interface Builder. Öppna Main.storyboard, och välj vykontrollen. Välja Bädda in> Navigation Controller från Redaktör meny. Detta ställer visningsstyrenheten som root view-styrenhet för en navigationsstyrenhet. Oroa dig inte för det här för tillfället.

Dra a UITableView exempel från Objektbibliotek till visningskontrollerns vy och lägga till de nödvändiga layouten. Med tabellvyn vald, öppna Anslutningsinspektör och ställ in tabellvyn datakälla och delegera uttag till visningsstyrenheten.

Med Anslutningsinspektör fortfarande öppen, välj visningskontrollen och anslut den Tableview utlopp till bordet vi just lagt till. Detta ansluter Tableview utloppet av ViewController klass till tabellvyn.

5. Protokoll

Innan vi kan bygga och köra applikationen måste vi implementera UITableViewDataSource och UITableViewDelegate protokoll i ViewController klass. Det handlar om flera saker.

Steg 1: I enlighet med protokoll

Vi måste berätta för kompilatorn att ViewController klassen överensstämmer med UITableViewDataSource och UITableViewDelegate protokoll. Syntaxen ser ut som i mål-C.

klass ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate ...

De protokoll som klassen överensstämmer med är listade efter superklassen, UIViewController i ovanstående exempel. Om en klass inte har en superklass, som inte är ovanlig i Swift, listas protokollen direkt efter klassnamnet och kolon.

Steg 2: Implementera UITableViewDataSource Protokoll

Eftersom det UITableViewDelegate protokoll definierar inte nödvändiga metoder, vi ska bara genomföra UITableViewDataSource protokoll för nu. Innan vi gör, låt oss skapa en variabel egenskap för att lagra de åtgärdsposter vi ska lista i tabellvyn.

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

Vi förklarar en variabel egendom objekt av typ [Sträng] och ange en tom matris, [], som initialvärdet. Detta borde bli bekant nu. Låt oss sedan genomföra de två nödvändiga metoderna för UITableViewDataSource protokoll.

Den första nödvändiga metoden, numberOfRows (inSection :), är lätt. Vi returnerar helt enkelt antalet poster som lagrats i objekt fast egendom.

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

Den andra nödvändiga metoden, cellForRow (vid :), behöver en förklaring. Med hjälp av subscriptsyntax frågar vi objekt för objektet som motsvarar den aktuella raden.

func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell // Hämta Item let item = objekt [indexPath.row] // Dequeue Cell låt cell = tableView.dequeueReusableCell (withIdentifier: "TableViewCell", för: indexPath ) // Konfigurera Cell cell.textLabel? .Text = returnera cell

Vi frågar sedan tabellvyn för en cell med identifierare "TableViewCell", passerar i indexbanan för den aktuella raden. Observera att vi lagrar cellen i en konstant, cell. Det finns inget behov av att deklarera cell som en variabel.

I nästa kodlinje konfigurerar vi tabellvynscellen och ställer in textikettens text med värdet av Artikel. Observera att i Swift the textLabel egendom av UITableViewCell förklaras som en valfri typ och därmed frågetecken. Denna kodlinje kan läsas som Ange textetikettens text egendom till Artikel om textLabel är inte lika med noll. Med andra ord, textetiketten är text egendom är bara inställd om textLabel är inte noll. Detta är en mycket bekväm säkerhetskonstruktion i Swift kallad valfri kedja.

Steg 3: Återanvändning av celler

Det finns två saker vi måste sortera ut innan du bygger applikationen. Först måste vi berätta för tabellen att den behöver använda UITableViewCell klass för att skapa nya tabellvynceller. Vi gör detta genom att åberopa registerclass (_: forCellReuseIdentifier :), passerar i UITableViewCell klass och återanvändningsidentifieraren vi använde tidigare, "TableViewCell". Uppdatera viewDidLoad () metod som visas nedan.

åsidosätta func viewDidLoad () super.viewDidLoad () // Registrera klass för Cellåtervinning tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")

Steg 4: Lägga till objekt

Vi har för närvarande inga föremål att visa i tabellvyn. Detta löses enkelt genom att fylla i objekt egendom med några saker att göra. Det finns flera sätt att uppnå detta. Jag har valt att fylla i objekt egendom i viewDidLoad () metod som visas nedan.

överträffa func viewDidLoad () super.viewDidLoad () // Populera artiklar = = "Köp mjölk", "Slutför handledning", "Spela Minecraft"] // Registrera Klass för Cellåtervinning tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")

6. Bygg och kör

Det är dags att ta vår ansökan om en snurrning. Välj Springa från Xcode s Produkt meny eller träff Kommando-R. Om du har följt efter, borde du sluta med följande resultat.

Observera att jag har lagt till en titel, Att göra, längst upp i vyn i navigeringsfältet. Du kan göra detsamma genom att ställa in titel egenskapen hos ViewController exempel i viewDidLoad () metod.

åsidosätta func viewDidLoad () super.viewDidLoad () // Set Title title = "Att göra" // Populera artiklar objekt = ["Köp mjölk", "Slutför handledning", "Spela Minecraft"] // Registrera Klass för Cellåterställning tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")

Slutsats

Även om vi just har skapat en enkel applikation, har du lärt dig en hel del nya saker. Vi har undersökt arv och överordnade metoder. Vi omfattade också protokoll och hur man ansluter UITableViewDataSource protokoll i ViewController klass. Det viktigaste du har lärt dig är emellertid hur du interagerar med objektiv-C-API: er.

Det är viktigt att förstå att API: erna för iOS SDK skrivs i Objective-C. Swift utformades för att vara kompatibel med dessa API. Baserat på tidigare misslyckanden förstod Apple att Swift behövde kunna haka i iOS SDK utan att behöva skriva om varje enskilt API i Swift.

Kombinera mål-C och Swift är möjligt, men det finns några försiktighetsåtgärder som vi kommer att utforska närmare när vi går framåt. På grund av Swifts obevekliga fokus på säkerhet, måste vi ta några hinder ibland. Men ingen av dessa hinder är för stora som vi kommer att ta reda på i nästa lektion där vi fortsätter att arbeta med vår handlingsapplikation.

Under tiden, kolla in några av våra andra kurser och handledning om Swift-språk iOS-utveckling!