Let oss skrive en RubyMotion App: Part 1 
 49 
 Del 
 7 
 Del 
 Dette Cyber Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av. 
 Hva du skal lage 
 RubyMotion er et rammeverk som lar deg bygge iOS-applikasjoner i Ruby. Det gir deg alle fordelene av Ruby språket, men fordi koden er kompilert til maskinkode, får du all den rå ytelse for utvikling i Objective-C. RubyMotion lar deg bruke iOS SDK direkte, noe som betyr at du har tilgang til alle de nyeste funksjonene i plattformen. Du kan ta med Objective-C-kode inn i prosjektet og RubyMotion fungerer selv med CocoaPods. 
 
 I denne opplæringen, vil du bygge et maleri program fra bunnen av. Jeg skal vise deg hvordan du kan innlemme Interface Builder i arbeidsflyten, og hvordan du kan teste din søknad skal. Hvis du ikke har noen tidligere iOS eller Ruby erfaring, vil jeg anbefale deg å lære mer om dem først. Den Tuts + Ruby for Nybegynnere og læring iOS SDK Development fra Scratch guider er et flott sted å starte. 
 
 1. Prosjektet Setup 
 
 Før du kan begynne koding, må du ha RubyMotion installert og satt opp. For detaljer om hvordan du gjør dette, sjekk ut Forutsetninger delen av RubyMotion Komme i gang 
 
 Når du har gjort det, åpne opp terminal og opprette et nytt RubyMotion prosjekt ved å kjøre. 
 Bevegelse skape paintcd maling 
 Dette skaper en  male katalog og flere filer: 
 
  .gitignore: 
 Denne filen forteller Git hvilke filer som skal ignorere. Fordi RubyMotion genererer bygge filer når den kjører, er denne filen nyttig for å holde din generert bygge filer ut av kildekontroll 
 
  Gemfile 
 . 
 Denne filen inneholder programmets avhengig . 
 
  Rakefile: 
 RubyMotion bruker Rake for å bygge og drive din søknad.  Rakefile 
 konfigurerer din søknad og laster sine avhengigheter. Du kan se alle de oppgavene som er tilgjengelig for din søknad ved å kjøre rake -T fra kommandolinjen 
 
  app /app_delegate.rb. 
 Søknad delegat er inngangsporten til søknaden din. Når iOS ferdig lasting søknaden din inn i minnet, er programmet delegat varslet. 
 
 RubyMotion genererer også en  spec /main_spec.rb 
 fil. Jeg skal vise deg hvordan du kan teste din søknad litt senere i denne opplæringen. For nå kan du slette denne filen ved å kjøre rm spec /main_spec.rb fra kommandolinjen. 
 
 Installer programmets avhengigheter ved å kjøre bundle installere fulgt av bunt exec rake å starte applikasjonen. 
 
 Woohoo! En svart skjerm. Du vil gjøre det mer interessant i et minutt. 
 
 2. First Endre 
 
 Selv om det er fint å ha en løpende app, er en svart skjerm litt kjedelig. La oss legge til litt farge. 
 
 Som innfødt iOS SDK, RubyMotion ikke tvinge deg til å organisere filene på en bestemt måte. Men det er nyttig å lage noen mapper i  app katalog for å holde prosjektet organisert. Kjør følgende kommandoer fra kommandolinjen for å lage en katalog for dine modeller, synspunkter og kontrollere. 
 Mkdir app /modelsmkdir app /viewsmkdir app /kontrollere 
 Neste, ta en titt på innsiden av  app /app_delegate .rb 
 file: 
 klasse AppDelegate def program (søknad, didFinishLaunchingWithOptions: launchOptions) sant Sluttslutt 
 Hvis du er kjent med iOS utvikling, vil du legge merke til denne metoden tilhører UIApplicationDelegate protokollen, som gir flere kroker i søknaden livssyklus. Merk at AppDelegate klassen ikke erklære at den implementerer UIApplicationDelegate protokollen. Ruby er avhengig av duck typing som den ikke støtter protokoller. Dette betyr at det ikke bryr seg om din klasse sier det implementerer en protokoll, det bare bryr seg om det implementerer de riktige metodene 
 
Definisjonen av søknaden:. DidFinishLaunchingWithOptions: metode inne i AppDelegate klassen kan se litt rart . I Objective-C, vil denne metoden være skrevet slik: Anmeldelser - (BOOL) program: (UIApplication *) applikasjons didFinishLaunchingWithOptions: (NSDictionary *) launchOptions;
 Fordi Objective-C metodenavn kan deles inn i flere deler implementerer Ruby dem på en unik måte. Den første delen av programmet: didFinishLaunchingWithOptions: er hva som ville være den metoden navn i MR. Resten av fremgangsmåten signaturen skrives som søkeord argumenter. I RubyMotion, applikasjons: didFinishLaunchingWithOptions: er skrevet slik: 
 def program (søknad, didFinishLaunchingWithOptions: launchOptions). End 
 La oss gjennomføre denne metoden 
 klassen AppDelegate def program (søknad, didFinishLaunchingWithOptions: launchOptions)window = UIWindow.alloc.initWithFrame (UIScreen.mainScreen.bounds) @ window.makeKeyAndVisible @ window.rootViewController = UIViewController.alloc.initWithNibName (null, pakke: null) true Sluttslutt 
 De to første linjene i søknaden: didFinishLaunchingWithOptions: Metode opprette et nytt vindu objekt og gjør det nøkkelen vinduet av søknaden. Hvorfor erwindow en instansvariabel? RubyMotion vil sanering vinduet med mindre vi lagre den. Den siste linjen i metoden setter vinduet rot view controller til en ny, tom view controller. 
 
 Kjør programmet for å gjøre alt fortsatt fungerer. 
 
 Hmm. Programmet kjører, men skjermen er fortsatt svart. Hvordan vet du koden fungerer? Du kan gjøre en rask tilregnelighet sjekk ved å legge følgende til bunnen av søknaden: didFinishLaunchingWithOptions :, før sant. Sørg for å fjerne denne før du går videre. 
 @ Window.rootViewController.view.backgroundColor = UIColor.yellowColor 
 3. Testing 
 
 Ingen søknaden er komplett uten en solid pakke med tester. Testing kan du være trygg på koden din fungerer og det lar deg gjøre endringer uten å bekymre deg for å bryte eksisterende kode. 
 
 RubyMotion skip med en port av Bacon testing biblioteket. Hvis du er kjent med Rspec, vil Bacon føler veldig kjent. 
 
 For å komme i gang, speile  app katalog strukturen i  spec katalog ved å kjøre følgende kommandoer fra kommandolinjen. 
 mkdir spec /modelsmkdir spec /viewsmkdir spec /kontrollere 
 Deretter oppretter den AppDelegate spesifikasjon fil på  spec /app_delegate_spec.rb 
. Ved konvensjonen, kildefilene er speil i spec katalogen og har  _spec 
 lagt til på slutten av filnavnet. 
 
 Start denne klassen ved å definere et beskrive blokk som forteller leseren hva din fil er testing 
 beskrive AppDelegate doend 
 Deretter legge til en andre beskrive blokk i den første til å vise at du ønsker å teste programmet. didFinishLaunchingWithOptions. metode 
 beskrive AppDelegate vet beskrive "#application: didFinishLaunchingWithOptions:" gjøre Sluttslutt 
 La du merke til det # i begynnelsen av metoden signatur? Ved konvensjonen, instansmetoder begynne med hasj og klassemetoder begynne med en periode 
 
 Deretter legger du til en spec bruker en det blokk 
 beskrive AppDelegate gjør beskrive.. "#application: DidFinishLaunchingWithOptions:" gjør det " skaper vinduet "gjør UIApplication.sharedApplication.windows.size.should == en slutt Sluttslutt 
 En av de beste tingene med Bacon-og andre BDD test rammeverk-er at spesifikasjonene er veldig klar på hva de tester. I dette tilfellet, du gjør at programmet: didFinishLaunchingWithOptions: metoden skaper et vindu. 
 
 Din spec trenger ikke å kalle programmet: didFinishLaunchingWithOptions: metode direkte. Det kalles automatisk når Bacon lanserer søknaden din. 
 
 Kjør programmets specs ved å kjøre bunt exec rake spec fra kommandolinjen. Du vil nå se slik ut: 
 1 spesifikasjoner (1 krav), 0 fiaskoer, 0 feil 
 Dette forteller deg at Bacon kjørte en test og ikke fant noen feil. Hvis en av dine specs mislykkes, vil du se en fiasko og Bacon vil skrive ut en detaljert beskrivelse av problemet. 
 
 De ovennevnte fungerer, men du skal bruke UIApplication.sharedApplication for alle dine spesifikasjoner. Ville det ikke vært fint om du kunne ta dette objektet gang og bruke det i alle specs? . Du kan med en før blokk 
 beskrive AppDelegate vet beskrive "#application: didFinishLaunchingWithOptions:" gjøre før doapplication = UIApplication.sharedApplication avslutte det "skaper vinduet" gjør @ application.windows.size.should == en ende Sluttslutt 
 Nå kan du enkelt legge til resten av programmets specs 
 beskrive AppDelegate vet beskrive. "#application: didFinishLaunchingWithOptions:" do før doapplication = UIApplication.sharedApplication avslutte det "skaper vinduet" gjørapplication. windows.size.should == en slutt det "gjør vinduet nøkkelen" gjør @ application.windows.first.isKeyWindow.should.be.true avslutte det "setter root view controller" gjør @ application.windows.first.rootViewController. should.be.instance_of UIViewController slutten Sluttslutt 
 Kjør disse til å sørge for at alt fungerer før du går videre. 
 
 4. Legge til brukergrensesnitt 
 
 Det er flere måter å lage brukergrensesnittet ved hjelp RubyMotion. Min personlige favoritt er å bruke  Interface Builder 
 med IB perle. Åpne opp Gemfile og tilsett IB perle 
 kilde. 'Https: //rubygems.org'gem' rake'gem 'ib' 
 Kjør bunt installere fra kommandolinjen installerer perle. Hvis du bruker Git, legge ib.xcodeproj til  .gitignore 
 fil. 
 
 Interface Builder er en del av Xcode. Lansere Interface Builder ved å kjøre bunt exec rake ib: open. Dette skaper en Xcode prosjekt skreddersydd til søknaden din. Opprett en ny filer brukergrensesnitt ved å velge  New > Fil ... 
 fra Xcode  Fil 
 meny og velg  Storyboard 
 fra  User Interface 
 kategori til venstre. Klikk  Neste 
 to ganger for å fullføre dette trinnet. 
 
 Lagre dreieboken i  ressurser katalog som  main.storyboard 
. Åpne dreieboken i Xcode og drar en ny  View Controller 
 inn i den fra  Object Library 
 til høyre. Sett  Storyboard ID 
 felt av kontrolleren til PaintingController. 
 
 Dra en etikett til visningen kontrolleren syn fra objektbiblioteket på høyre og sette tekst til Hello. 
 
 Deretter åpner opp  app /app_delegate   Deretter kjører programmets tester igjen med bundle exec rake spec for å sørge for at de fortsatt passere. Legg merke til hvordan du ikke trenger å endre noen av dem? Gode spesifikasjoner teste oppførselen av koden, ikke gjennomføringen. Dette betyr at du bør være i stand til å endre  hvordan   Hva du har bygget så langt er flott, men ville det ikke være fint hvis din app faktisk gjorde noe? I denne seksjonen vil du legge kontrollene for å bytte farge på pensel. Opprette to nye filer, en controller og sin spec, ved å kjøre følgende kommandoer.   Implementere PaintingController skjelett sammen med sin spec. Anmeldelser klasse PaintingController < UIViewControllerenddescribe PaintingController gjøre tester PaintingController,: storyboard = > 'main',: id = > 'PaintingController'end   RubyMotion håndterer kontrolleren specs på en spesiell måte. Den tester PaintingController,: storyboard = > 'main',: id = > 'PaintingController' linje på spec filen forteller RubyMotion å bruke kontrolleren med en dreiebok ID PaintingController i  Hovedanmeldelser storyboard. Du kan bruke kontrolleren variabel for å teste den.   Deretter må du legge til uttak til kontrolleren. Disse lar deg koble objekter til kontrolleren i Interface Builder   forlenge IB legger flere metoder til kontrolleren, inkludert uttak. Du har lagt til fem utsalgssteder, en for hver knapp.   Bildene for knappene er inkludert i kildefilene for denne opplæringen. Last ned bildene og kopiere dem inn i  ressurser katalog. Du må regenerere Xcode prosjekt for å tillate Interface Builder for å plukke opp de endringene vi har gjort. Den enkleste måten å gjøre dette på er ved å lukke Xcode og kjører bunt exec rake ib: åpen, noe som vil gjenåpne prosjektet   Velg visningen kontrolleren og endre sin klasse PaintingController   Åpne <.. b> spec /app_delegate_spec.rb Hotell og modifisere den siste spec for å se etter den PaintingController klassen.   Disse knappene er litt kjedelig. Velg den første knappen, endre typen til Custom i  attributter Inspektør   Sett State Config rullegardinmenyen til Valgte og endre bakgrunnsbildet til button_black_selected.png.   I  Størrelse Inspector   Gjenta denne prosessen for de andre knappene.   Det neste trinnet er å koble knappene opp til visningen kontrollerens uttak vi erklært tidligere. Hold nede  Ctrl   Til slutt velger den første knappen og klikk på  Valgt   Nå er en god tid for å legge til et par nyttige specs til  spec /painting_controller_spec.rb   Disse specs sikre uttak er riktig tilkoblet i Interface Builder. Som alltid er det en god idé å kjøre dem før du fortsetter å sørge for at de alle pass.   Deretter vil du implementere select_color metoden i PaintingController. Når denne metoden kalles, er den knappen som ble tappet valgt og den tidligere valgte knappen er deaktivert   Legg specs til  spec /kontrollere /painting_controller_spec.rb   Kjør programmet og sørge for at knappen valg fungerer. Når du trykker på en knapp, bør det øke i størrelse. Selv om dette er kult, hva du egentlig ønsker er for en farge som velges når det bankes på knappen. Dette er lett å oppnå med noen få tillegg.   sugarcube er et sett med iOS utvidelser for RubyMotion som gjør flere oppgaver, som å lage farger, enklere. Legg perle 'sugarcube "til din Gemfile og kjøre bunt installere. Deretter legger du krever "sugarcube-farge" i  Rakefile   Perle gjør det enkelt å lage farger ved hjelp av sin hex-kode. I PaintingController klassen, legge inn følgende kode under utdeling av uttakene:   Deretter refactor rekken av knappene i select_color inn i et privat hjelpemetode:   Til slutt legger du en ny metode under select_color som returnerer den valgte farge .   Denne metoden griper indeksen for den valgte knappen og velger den fargen som tilsvarer det. Of course, denne metoden ville ikke være komplett uten tester   Kjør programmet igjen for å kontrollere at alt fungerer som forventet   Du har dekket mye bakken i denne opplæringen. Du har lært å sette opp og kjøre en RubyMotion program, har du jobbet med Interface Builder, og du har bygget et brukergrensesnitt.   I den andre delen av denne opplæringen, vil du dykke dypere inn i Model-View-Controller mønster på iOS og din søknad organisasjon. Du vil også legge et maleri utsikt og skrive kode som gjør det mulig for brukeren å tegne. Følg med.
  Hotell og erstatte den siste linjen av programmet: didFinishLaunchingWithOptions: med følgende: 
 dreiebok = UIStoryboard.storyboardWithName ("main", bunt: null ) @ window.rootViewController = storyboard.instantiateInitialViewController 
 koden er implementert og dine spesifikasjoner skal fortsatt fungere. Kjør din søknad til å prøvekjøre den nye brukergrensesnittet. 
 
 5. Knapper 
 
 Berøring app /kontrollere /painting_controller.rbtouch spec /kontrollere /painting_controller_spec.rb 
 
 klasse PaintingController <.; UIViewController forlenge IB utløp: black_button utløp: purple_button utløp: green_button utløp: blue_button utløp: white_button def select_color (sender) Sluttslutt 
 
 
 
 det "setter root view controller" do @ application.windows.first.rootViewController.should.be.instance_of PaintingControllerend < p> Legg fem knapper til visningen kontrolleren syn ved å dra knappeobjekter på utsikten fra objektbiblioteket til høyre. 
 
 på høyre og ta tittelen. Vær sikker på at Standard staten er valgt i staten Config drop-down menyen og sette bakgrunnsbildet til button_black.png. Sett  Tint 
 eiendom av knappen for å gjennomsiktig. 
 
 
, endre bredden og høyden på knappen til 50. 
 
 
 tasten på tastaturet og dra fra visningen kontrolleren til den første knappen. En meny vil komme opp når du slipper musen. Velg black_button fra menyen. Deretter holder du nede  Ctrl 
 tasten og dra fra knappen til visningen kontrolleren og velg select_color metode fra menyen som dukker opp. Gjenta disse to trinnene for de andre knappene. 
 
 avkrysnings under  Ctrl 
 i  Egenskaper Inspektør 
 
 
 beskrive PaintingController gjøre tester PaintingController,:. dreiebok = > 'main',: id = > 'PaintingController' beskrive "#black_button" do it "er koblet i dreieboken" gjør controller.black_button.should.not.be.nil end end beskrive "#purple_button" do it "er koblet i dreieboken" gjør controller.purple_button. should.not.be.nil end end beskrive "#green_button" do it "er koblet i dreieboken" gjør controller.green_button.should.not.be.nil end end beskrive "#blue_button" do it "er koblet i dreieboken "gjør controller.blue_button.should.not.be.nil end end beskrive" #white_button "do it" er koblet i dreieboken "gjør controller.white_button.should.not.be.nil slutten Sluttslutt 
 
 def select_color (sender) [black_button, purple_button, green_button, blue_button, white_button] .each gjøre |. Knapp | button.selected = false slutten sender.selected = trueend 
. 
 beskrive "#select_color" do før gjøre controller.select_color (controller.green_button ) avslutte det "opphever de andre fargene" gjøre controller.black_button.state.should == UIControlStateNormal controller.purple_button.state.should == UIControlStateNormal controller.blue_button.state.should == UIControlStateNormal controller.white_button.state.should == UIControlStateNormal avslutte det "velger farge" gjøre controller.green_button.state.should == UIControlStateSelected Sluttslutt 
 
 ovenfor Motion :: Prosjekt :: App.setup. 
 
 FARGER = ["# 333333" .uicolor, "# 7059ac" .uicolor, "# 196e76" .uicolor, "# 80a9cc" .uicolor "#fafafa" .uicolor] 
 def select_color (sender) buttons.each gjøre | knapp | button.selected = false slutten sender.selected = truecolor = FARGER [sender.tag] endprivatedef knappene [black_button, purple_button, green_button, blue_button, white_button] end 
 def selected_color FARGER [buttons.find_index {| knapp | button.state == UIControlStateSelected}] end 
 beskrive "#selected_color" do før gjøre controller.select_color (controller.green_button) avslutte det "returnerer riktig farge" gjør controller.selected_color.should == PaintingController.: .: FARGER [2] Sluttslutt 
 
 Konklusjon 
 
 

