Ditt första WatchKit-program Användarinteraktion

I den tidigare handledningen undersökte vi grunden för WatchKit-utvecklingen. Vi skapade ett projekt i Xcode, lade till ett WatchKit-program och skapade ett grundläggande användargränssnitt.

Användargränssnittet för vår WatchKit-applikation visar för närvarande statisk data. Om du inte bor i öknen är det inte särskilt användbart för en väderapplikation. I denna handledning kommer vi att fylla användargränssnittet med data och skapa några åtgärder.

1. Uppdatering av användargränssnittet

Steg 1: Byta ut WKInterfaceDate

Innan vi fyller användargränssnittet med data måste vi göra en liten förändring. I den tidigare handledningen lade vi till en WKInterfaceDate instans till den nedre gruppen för att visa aktuell tid och datum. Det är dock mer användbart att visa tid och datum för de data som vi visar. Anledningen till denna förändring kommer att bli tydlig om några ögonblick.

Öppna Interface.storyboard, ta bort WKInterfaceDate instans i den nedre gruppen och ersätt den med a WKInterfaceLabel exempel. Ange etikettens Bredd tillskriva Relativt till behållaren och etiketten Inriktning till högerinriktad.

Steg 2: Lägga till försäljningsställen

För att uppdatera användargränssnittet med dynamiska data behöver vi skapa några uttag i InterfaceController klass. Öppna storyboardet i huvudredigeraren och InterfaceController.swift i Assistent Editor till höger. Välj den övre etiketten i den första gruppen och Ctrl-dra från etiketten till InterfaceController klass för att skapa ett uttag. Namn utloppet locationLabel.

Upprepa dessa steg för de andra etiketterna, namngivna dem temperatureLabel och dateLabel respektive. Det här är vad InterfaceController klassen ska se ut när du är klar.

importera WatchKit import Foundation class InterfaceController: WKInterfaceController @IBOutlet weak var dateLabel: WKInterfaceLabel! @IBOutlet svag var locationLabel: WKInterfaceLabel! @IBOutlet svag var temperatureLabel: WKInterfaceLabel! åsidosätta func awakeWithContext (context: AnyObject?) super.awakeWithContext (context) åsidosätta func willActivate () // Denna metod kallas när watch view controller är på väg att vara synlig för användaren super.willActivate () åsidosätta func didDeactivate ) // Den här metoden heter när Watch View Controller inte längre är synlig super.didDeactivate ()

Nu kan det vara en bra tid att ta en närmare titt på genomförandet av InterfaceController klass. I den tidigare handledningen nämnde jag det InterfaceController ärver från WKInterfaceController. Vid första anblicken kan det verka som om a WKInterfaceController Exempel beter sig som a UIViewController exempel, men vi lärde oss också i den tidigare handledningen att det finns ett antal viktiga skillnader.

För att hjälpa oss har Xcode befolket InterfaceController klass med tre överdrivna metoder. Det är viktigt att förstå när varje metod åberopas och vad den kan eller ska användas till.

awakeWithContect (_ :)

I awakeWithContext (_ :) Metod, du ställer in och initierar gränssnittskontrollen. Du kanske undrar hur det skiljer sig från i det metod. De awakeWithContext (_ :) Metoden åberopas efter att gränssnittsregulatorn initialiserats. Metoden accepterar en parameter, ett kontextobjekt som tillåter gränssnittsstyrare att skicka information till varandra. Detta är det rekommenderade tillvägagångssättet för att skicka information över scener, det vill säga gränssnittsregulatorer.

willActivate

De willActivate Metoden liknar viewWillAppear (_ :) metod för UIViewController klass. De willActivate Metoden åberopas innan användargränssnittet för gränssnittsstyrenheten presenteras för användaren. Det är perfekt för tweaking av användargränssnittet innan det presenteras för användaren.

didDeactivate

De didDeactivate Metod är motstycke till willActivate metod och åberopas när gränssnittskontrollens scen har tagits bort. En eventuell uppringningskod går in i denna metod. Denna metod liknar viewDidDisappear (_ :) metod som hittades i UIViewController klass.

Med ovanstående kan vi börja ladda data och uppdatera användargränssnittet för vår WatchKit-applikation. Låt oss börja med att ladda väderdata.

2. Laddar väderdata

Bästa praxis

Du kanske tror att nästa steg innebär ett API-samtal till en väderstjänst, men det är inte så. Om vi ​​byggde ett iOS-program skulle du ha rätt. Vi skapar dock ett WatchKit-program.

Det rekommenderas inte att göra komplexa API-samtal för att hämta data för att fylla i användargränssnittet för en WatchKit-applikation. Även om Apple inte uttryckligen nämner detta i dokumentationen, nämnde en Apple-ingenjör denna oskrivna bästa praxis i Apples utvecklarforum.

WatchKit-programmet är en del av ett iOS-program och det är iOS-programmet som ansvarar för att hämta data från en fjärrbackend. Det finns flera tillvägagångssätt som vi kan vidta för att göra detta, att hämta bakgrund är ett bra val. I denna handledning kommer vi dock inte att fokusera på den aspekten.

Istället lägger vi till dummy-data i buntet i WatchKit-tillägget och laddar det i awakeWithContext (_ :) metod vi diskuterade tidigare.

Skapa en tom fil genom att välja Ny> Fil ...  från Fil meny. Välja Tömma från iOS> Annat avsnitt och namnge filen weather.json. Dubbelkontrollera att du lägger till filen i filen RainDrop WatchKit Extension. Utse inte denna lilla men viktiga detalj. Bifoga filen med följande data.

"platser": ["plats": "Cupertino", "temperatur": 24, "tidsstämpel": 1427429751, "plats": "London", "temperatur": 11, "tidsstämpel": 1427429751 "Plats": "Paris", "Temperatur": 9, "Tidstämpel": 1427429751, "Plats": "Bryssel", "Temperatur": 11, "Tidstämpel": 1427429751]

Dela data

Att dela data mellan iOS-programmet och WatchKit-programmet är ett viktigt ämne. Men denna handledning fokuserar på att få ditt första WatchKit-program igång. I en framtida handledning kommer jag att fokusera på att dela data mellan en iOS och ett WatchKit-program.

Även om vi inte kommer att täcka delning av data i den här handledningen är det viktigt att veta att iOS-programmet och WatchKit-tillägget inte delar en sandlåda. Båda målen har sin egen sandlåda och det gör det att dela data mindre trivial än det verkar.

För att dela data mellan iOS och WatchKit-programmet måste du utnyttja appgrupper. Men det är ett ämne för en framtida handledning.

Steg 1: Lägga till SwiftyJSON

Swift är ett bra språk, men vissa uppgifter är enklare i mål-C än de är i Swift. Hantering av JSON är till exempel en sådan uppgift. För att göra denna uppgift enklare har jag valt att utnyttja det populära SwiftyJSON-biblioteket.

Ladda ner förvaret från GitHub, pakka ut arkivet och lägg till SwiftyJSON.swift till RainDrop WatchKit Extension grupp. Den här filen finns i Källa Arkivets mapp. Dubbelkontrollera det SwiftyJSON.swift läggs till RainDrop WatchKit Extension mål.

Steg 2: Implementering WeatherData

För att göra det enklare att arbeta med de väderdata som lagras i weather.json, Vi ska skapa en struktur som heter WeatherData. Välj Ny> Fil ... från de Fil meny, välj Swift File från iOS> Källa avsnitt och namnge filen WeatherData. Kontrollera att filen har lagts till i RainDrop WatchKit Extension mål.

Genomförandet av WeatherData strukturen är kort och enkel. Strukturen definierar tre konstanta egenskaper, datum, plats, och temperatur.

import Foundation struktur WeatherData låt datum: NSDate låt plats: String låt temperatur: Double

Eftersom temperaturvärdet på weather.json är i Celcius implementerar vi också en beräknad egendom fahrenheit för enkel konvertering mellan Celcius och Fahrenheit.

var fahrentheit: Dubbel returtemperatur * (9/5) + 32

Vi definierar också två hjälpar metoder toCelciusString och toFahrenheitString för att göra formateringstemperaturerna enklare. Älskar du inte Swifts stränginterpolation?

func toCelciusString () -> String return "\ (temperatur) ° C" func toFahrenheitString () -> String return "\ (fahrentheit) ° F"

Som jag sa, genomförandet av WeatherData strukturen är kort och enkel. Så här ska genomförandet se ut.

importera Foundation Struct WeatherData låt datum: NSDate låt plats: String Låt temperatur: Dubbel var fahrentheit: Dubbel Returtemperatur * (9/5) + 32 Func toCelciusString () -> String Retur "\ (Temperatur) ° C"  func toFahrenheitString () -> String return "\ (fahrentheit) ° F"

Steg 3: Laddar data

Innan vi laddar data från weather.json, Vi måste förklara en egendom för lagring av väderdata. Egendomen, weatherData, är av typ [WeatherData] och kommer att innehålla innehållet i weather.json som fall av WeatherData strukturera.

var weatherData: [WeatherData] = []

För enkel användning, förklarar vi också en beräknad egendom, väder, som ger oss tillgång till första objektet i weatherData array. Det är uppgifterna om detta WeatherData exempel som vi kommer att visa i gränssnittskontrollen. Kan du gissa varför vi måste förklara väder egendom som tillval?

var väder: WeatherData? return weatherData.first

Vi laddar data från weather.jsonawakeWithContext (_ :) metod. För att hålla implementeringen ren, anropar vi en hjälparmetod som heter loadWeatherData.

åsidosätta func awakeWithContext (context: AnyObject?) super.awakeWithContext (context) // Ladda väderdata loadWeatherData ()

Genomförandet av loadWeatherData är förmodligen det mest skrämmande kodbiten vi ser i den här handledningen. Som jag sa är parsing JSON inte trivial i Swift. Lyckligtvis gör SwiftyJSON det mesta av det tunga för oss.

func loadWeatherData () let path = NSBundle.mainBundle (). pathForResource ("weather", ofType: "json") om släpp path = path let data = NSData (contentOfFile: path) om låt data = data let weatherData = JSON (data: data) låt platser = weatherData ["locations"]. Array om låt platser = platser för plats på platser let timestamp = location ["timestamp"]. Dubbel! låt datum = NSDate (timeIntervalSinceReferenceDate: timestamp) låt modell = WeatherData (datum: datum, plats: plats ["plats"]. sträng !, temperatur: plats ["temperatur"]. dubbel!) self.weatherData.append (modell) 

Vi får vägen till weather.json och ladda dess innehåll som en NSData objekt. Vi använder SwiftyJSON för att analysera JSON, som passerar in i NSData objekt. Vi får en hänvisning till matrisen för nyckeln platser och slinga över varje plats.

Vi normaliserar väderdata genom att konvertera tidstämpeln till en NSDate instans och initiera a WeatherData objekt. Slutligen lägger vi till WeatherData protestera mot weatherData array.

Jag hoppas att du håller med om att genomförandet inte är så svårt. Eftersom Swift tvingar oss att göra ett antal kontroller, ser genomförandet ut mer komplicerat än det faktiskt är.

3. Populera användargränssnittet

Med väderinformationen redo att användas är det dags att uppdatera användargränssnittet. Som jag förklarade tidigare måste uppdatering av användargränssnittet hända i willActivate metod. Låt oss ta en titt på genomförandet av denna metod.

åsidosätta func willActivate () // Den här metoden kallas när vaktvisningskontrollen är synlig för användaren super.willActivate () om låt väder = self.weather locationLabel.setText (weather.location) // Uppdateringstemperaturetikett själv .updateTemperatureLabel () // Uppdateringsdatum Etikett self.updateDateLabel ()

Efter att ha åberopat willActivate Metoden för superklassen, vi paketerar det värde som lagrats i väder fast egendom. För att uppdatera platsetiketten åberopar vi setText, passerar i det värde som lagrats i plats egenskapen hos väder objekt. För att uppdatera temperatur- och datumetiketterna åberopar vi två hjälpar metoder. Jag föredrar att hålla willActivate metod kortfattad och kortfattad, och viktigare, jag gillar inte att upprepa mig själv.

Innan vi tittar på dessa hjälpmetoder måste vi veta om temperaturen måste visas i Celcius eller Fahrenheit. För att lösa detta problem, förklara en egendom, celcius, av typ Bool och ställa in dess ursprungliga värde till Sann.

var celcius: Bool = true

Genomförandet av updateTemperatureLabel är lätt att förstå. Vi paketerar säkert det värde som lagrats i väder och uppdatera temperaturmärket baserat på värdet på celcius. Som du kan se, två hjälpar metoder av WeatherData struktur vi skapade tidigare kommer till nytta.

func updateTemperatureLabel () om låt väder = self.weather if self.celcius temperatureLabel.setText (weather.toCelciusString ()) annars temperatureLabel.setText (weather.toFahrenheitString ())

Genomförandet av updateDateLabel är inte heller svårt. Vi initierar en NSDateFormatter Exempel, sätt dess datumformat egendom och konvertera datumet för väder objekt genom att ringa stringFromDate (_ :)dateFormatter objekt. Detta värde används för att uppdatera datumetiketten.

func updateDateLabel () var datum: NSDate = NSDate () // Initialize Date Formatter låt dateFormattter = NSDateFormatter () // Konfigurera datum Formatera dateFormattter.dateFormat = "d / MM HH: mm" om låt väder = self.weather date = weather.date // Uppdateringsdatum Etikett dateLabel.setText (datumFormattter.stringFromDate (datum))

Bygg och kör programmet för att se resultatet. Användargränssnittet bör nu fyllas med data från weather.json.

4. Växla till Fahrenheit

Det ser bra ut. Men skulle det inte vara bra om vi lagt till stöd för både Celcius och Fahrenheit? Det här är lätt att göra eftersom vi redan har lagt det mesta av grunden.

Om användarkraften berör användargränssnittet för en användargränssnittskontroll, visas en meny. Självklart fungerar det bara om en meny är tillgänglig. Låt oss se hur det här fungerar.

Öppna Interface.storyboard och lägg till en meny till GränssnittskontrollerDokumentbeskrivning till vänster. Som standard har en meny ett menyalternativ. Vi behöver två menyalternativ så lägg till ett annat menyalternativ på menyn.

Observera att menyn och menyalternativen inte är synliga i användargränssnittet. Detta är inte ett problem eftersom vi inte kan konfigurera menyns layout. Vad vi kan ändra är texten på ett menyobjekt och dess bild. Du förstår bättre vad det innebär när vi presenterar menyn.

Välj det översta menyalternativet, öppna Attribut Inspector, uppsättning Titel till Celcius, och Bild till Acceptera. Välj det nedre menyalternativet och ställ in Titel till fahrenheit och Bild till Acceptera.

Nästa, öppna InterfaceController.swift Assistent Editor till höger. Ctrl-dra från översta menyalternativet till InterfaceController.swift och skapa en åtgärd som heter toCelcius. Upprepa det här steget för det nedre menyobjektet, skapa en åtgärd som heter toFahrenheit.

Genomförandet av dessa åtgärder är kort. I toCelcius, vi kontrollerar om celcius fastigheten är inställd på falsk, och om det är så ställer vi fastigheten till Sann. I toFahrenheit, vi kontrollerar om celcius fastigheten är inställd på Sann, och om det är så ställer vi fastigheten till falsk.

@IBAction func toCelcius () if! Self.celcius self.celcius = true @IBAction func toFahrenheit () om self.celcius self.celcius = false

Om värdet av celcius ändringar måste vi uppdatera användargränssnittet. Vilket bättre sätt att uppnå detta genom att genomföra en fastighetsobservatör på celcius fast egendom. Vi behöver bara genomföra en didSet fastighetsobservatör.

var celcius: Bool = true didSet om celcius! = oldValue updateTemperatureLabel ()

Den enda detalj som är värt att nämna är att användargränssnittet bara uppdateras om värdet av celcius förändrade sig. Uppdatering av användargränssnittet är lika enkelt som att ringa updateTemperatureLabel. Bygg och kör WatchKit-programmet i iOS-simulatorn för att testa menyn.

Det är värt att nämna att iOS-simulatorn efterliknar en fysisk enhetens lyhördhet. Vad betyder det? Kom ihåg att WatchKit-tillägget körs på en iPhone medan WatchKit-programmet körs på en Apple Watch. När användaren knackar på ett menyalternativ skickas kontakthändelsen via en Bluetooth-anslutning till iPhone. WatchKit-förlängningen behandlar händelsen och skickar uppdateringar tillbaka till Apple Watch. Kommunikationen är ganska snabb, men det är inte så snabbt som om både tillägg och applikation skulle köras på samma enhet. Den korta fördröjningen efterliknas av IOS Simulator för att hjälpa utvecklare att få en uppfattning om prestanda.

Slutsats

När du har förstört ditt huvud kring arkitekturen i ett WatchKit-program blir det mycket lättare att förstå möjligheterna och begränsningarna i den första generationen WatchKit-applikationer. I den här handledningen har vi bara täckt de viktigaste aspekterna av WatchKit-utvecklingen. Det finns mycket mer att upptäcka och utforska. Håll dig igång.