RubyMotion è un framework che ti consente di creare applicazioni iOS in Ruby. Ti offre tutti i vantaggi del linguaggio Ruby, ma poiché il tuo codice è compilato in codice macchina, ottieni tutte le prestazioni non elaborate dello sviluppo in Objective-C. RubyMotion ti consente di utilizzare direttamente l'SDK di iOS, il che significa che puoi accedere a tutte le funzionalità più recenti della piattaforma. Puoi includere il codice Objective-C nel tuo progetto e RubyMotion funziona anche con CocoaPods.
In questo tutorial, costruirai un'applicazione per la pittura da zero. Ti mostrerò come incorporare Interface Builder nel tuo flusso di lavoro e come testare correttamente la tua applicazione. Se non hai precedenti esperienze su iOS o Ruby, ti consiglio di saperne di più su quelli per primi. I tutorial Tuts + Ruby for Newbies e Learning SDK per iOS da zero sono un ottimo punto di partenza.
Prima di poter iniziare la codifica, è necessario che RubyMotion sia installato e configurato. Per i dettagli su come eseguire questa operazione, consultare la sezione Prerequisiti della guida introduttiva di RubyMotion.
Dopo averlo fatto, apri il tuo terminale e crea un nuovo progetto RubyMotion eseguendo:
movimento crea vernice vernice cd
Questo crea a dipingere directory e diversi file:
rastrello -T
dalla riga di comando.RubyMotion genera anche a spec / main_spec.rb file. Ti mostrerò come testare la tua applicazione un po 'più avanti in questo tutorial. Per ora, puoi cancellare questo file eseguendo rm spec / main_spec.rb
dalla riga di comando.
Installa le dipendenze dell'applicazione eseguendo installazione bundle
seguito da pacchetto rake exec
per avviare la tua applicazione.
Woohoo! Uno schermo nero Lo renderà più interessante in un minuto.
Anche se è bello avere un'app in esecuzione, uno schermo nero è un po 'noioso. Aggiungiamo un po 'di colore.
Come l'SDK iOS nativo, RubyMotion non ti obbliga a organizzare i tuoi file in alcun modo specifico. Tuttavia, è utile creare alcune cartelle nel file App directory per mantenere il tuo progetto organizzato. Eseguire i seguenti comandi dalla riga di comando per creare una directory per i modelli, le viste e i controller.
mkdir app / models mkdir app / views mkdir app / controller
Quindi, dai uno sguardo all'interno del app / app_delegate.rb file:
classe AppDelegate def application (application, didFinishLaunchingWithOptions: launchOptions) true end end
Se hai familiarità con lo sviluppo di iOS, noterai che questo metodo appartiene al UIApplicationDelegate
protocollo, che fornisce diversi hook nel ciclo di vita dell'applicazione. Si noti che il AppDelegate
la classe non dichiara che implementa il UIApplicationDelegate
protocollo. Ruby si basa sulla digitazione anatra in quanto non supporta i protocolli. Ciò significa che non gli importa se la tua classe dice che implementa un protocollo, se ne importa solo se implementa i metodi corretti.
La definizione di applicazione: didFinishLaunchingWithOptions:
metodo all'interno del AppDelegate
la lezione potrebbe sembrare un po 'strana. In Objective-C, questo metodo dovrebbe essere scritto in questo modo:
- Applicazione (BOOL): l'applicazione (UIApplication *) ha fattoFinishLaunchingWithOptions: (NSDictionary *) launchOptions;
Poiché i nomi dei metodi Objective-C possono essere suddivisi in più parti, Ruby li implementa in un modo unico. La prima parte di applicazione: didFinishLaunchingWithOptions:
è quello che sarebbe il nome del metodo nella risonanza magnetica. Il resto della firma del metodo è scritto come argomenti di parole chiave. In RubyMotion, applicazione: didFinishLaunchingWithOptions:
è scritto così:
fine applicazione (applicazione, didFinishLaunchingWithOptions: launchOptions)
Implementiamo questo metodo.
class AppDelegate def application (application, didFinishLaunchingWithOptions: launchOptions) @window = UIWindow.alloc.initWithFrame (UIScreen.mainScreen.bounds) @ window.makeKeyAndVisible @ window.rootViewController = UIViewController.alloc.initWithNibName (nil, bundle: nil) true end end
Le prime due righe del applicazione: didFinishLaunchingWithOptions:
metodo crea un nuovo oggetto finestra e lo rende la finestra chiave dell'applicazione. Perché è @finestra
una variabile di istanza? RubyMotion raccoglierà i rifiuti dalla finestra a meno che non li archiviamo. L'ultima riga del metodo imposta il controller della vista radice della finestra su un nuovo controller di visualizzazione vuoto.
Esegui l'applicazione per fare in modo che tutto funzioni ancora.
Hmm. L'applicazione viene eseguita, ma lo schermo è ancora nero. Come sai che il tuo codice funziona? Puoi eseguire un rapido controllo di integrità aggiungendo quanto segue in fondo alla pagina applicazione: didFinishLaunchingWithOptions:
, prima vero
. Assicurati di rimuoverlo prima di andare avanti.
@ window.rootViewController.view.backgroundColor = UIColor.yellowColor
Nessuna applicazione è completa senza una solida serie di test. I test consentono di essere sicuri che il codice funzioni e consente di apportare modifiche senza preoccuparsi di rompere il codice esistente.
RubyMotion viene fornito con una porta della libreria di test Bacon. Se hai familiarità con Rspec, Bacon si sentirà molto familiare.
Per iniziare, rispecchia il App struttura di directory nel spec directory eseguendo i seguenti comandi dalla riga di comando.
mkdir spec / models mkdir spec / views mkdir spec / controller
Quindi, crea il AppDelegate
Il file delle specifiche di spec / app_delegate_spec.rb. Per convenzione, i file di origine sono specchi nella directory spec e hanno _spec aggiunto alla fine del nome del file.
Inizia questo corso definendo a descrivere
blocco che dice al lettore che cosa sta testando il tuo file.
descrivere AppDelegate do end
Successivamente, aggiungi un secondo descrivere
blocco all'interno del primo per mostrare che si desidera testare il applicazione: didFinishLaunchingWithOptions:
metodo.
descrivi AppDelegate descrivi "#application: didFinishLaunchingWithOptions:" fai end end
Hai notato il #
all'inizio della firma del metodo? Per convenzione, i metodi di istanza iniziano con un hash e i metodi di classe iniziano con un punto.
Quindi, aggiungi una specifica usando un esso
bloccare.
descrivi AppDelegate descrivi "#application: didFinishLaunchingWithOptions:" fai "crea la finestra" fai UIApplication.sharedApplication.windows.size.should == 1 end end end
Una delle cose migliori di Bacon e di altri framework di test BDD è che le specifiche sono molto chiare su ciò che stanno testando. In questo caso, ti stai assicurando che il applicazione: didFinishLaunchingWithOptions:
metodo crea una finestra.
Le tue specifiche non devono chiamare il applicazione: didFinishLaunchingWithOptions:
metodo direttamente. Si chiama automaticamente quando Bacon avvia la tua applicazione.
Esegui le specifiche della tua applicazione eseguendo bundle exec rake spec
dalla riga di comando. Dovresti vedere un output come questo:
1 specifiche (1 requisiti), 0 guasti, 0 errori
Questo ti dice che Bacon ha eseguito un test e non ha riscontrato errori. Se una delle tue specifiche fallisce, vedrai 1 fallimento
e Bacon stamperà una descrizione dettagliata del problema.
Quanto sopra funziona, ma lo userete UIApplication.sharedApplication
per tutte le tue specifiche Non sarebbe bello se potessi afferrare questo oggetto una volta e usarlo in tutte le specifiche? Puoi con a prima
bloccare.
descrivi AppDelegate descrivi "#application: didFinishLaunchingWithOptions:" fai prima do @application = UIApplication.sharedApplication e "crea la finestra" do @ application.windows.size.should == 1 end end end
Ora puoi facilmente aggiungere il resto delle specifiche dell'applicazione.
descrivi AppDelegate descrivi "#application: didFinishLaunchingWithOptions:" fai prima do @application = UIApplication.sharedApplication e "crea la finestra" do @ application.windows.size.should == 1 termina "rende la chiave della finestra" do @application .windows.first.isKeyWindow.should.be.true fine "imposta il controller della vista radice" do @ application.windows.first.rootViewController.should.be.instance_of UIViewController end end end
Esegui questi per assicurarsi che tutto funzioni prima di proseguire.
Esistono diversi modi per creare l'interfaccia utente usando RubyMotion. Il mio preferito è usare Interface Builder con la gemma IB. Apri il tuo Gemfile e aggiungi la gemma IB.
fonte 'https://rubygems.org' gemma 'rastrello' gemma 'ib'
Correre installazione bundle
dalla riga di comando per installare la gemma. Se utilizzi Git, aggiungi ib.xcodeproj
alla tua .gitignore file.
Interface Builder è una parte di Xcode. Avvia Interface Builder eseguendo bundle exec rake ib: aperto
. Questo crea un progetto Xcode su misura per la tua applicazione. Creare un nuovo file di interfaccia utente selezionando Nuovo> File ... da Xcode's File menu e selezionare storyboard dal Interfaccia utente categoria a sinistra. Clic Il prossimo due volte per completare questo passaggio.
Salva lo storyboard in risorse directory come main.storyboard. Apri lo storyboard in Xcode e trascina un nuovo Visualizza controller in esso dal Libreria di oggetti sulla destra. Impostare il ID storyboard campo del controller a PaintingController
.
Trascina un'etichetta nella vista del controller della vista da Libreria di oggetti a destra e imposta il suo testo a Ciao
.
Quindi, apri app / app_delegatee sostituire l'ultima riga di applicazione: didFinishLaunchingWithOptions:
con il seguente:
storyboard = UIStoryboard.storyboardWithName ("main", bundle: nil) @ window.rootViewController = storyboard.instantiateInitialViewController
Quindi, eseguire nuovamente i test dell'applicazione con bundle exec rake spec
per assicurarsi che passino ancora. Nota come non hai dovuto cambiarne nessuno? Le buone specifiche testano il comportamento del codice, non la sua implementazione. Ciò significa che dovresti essere in grado di cambiare Come il tuo codice è implementato e le tue specifiche dovrebbero ancora funzionare. Esegui la tua applicazione per testare la tua nuova interfaccia utente.
Quello che hai costruito finora è grandioso, ma non sarebbe bello se la tua app avesse effettivamente fatto qualcosa? In questa sezione, aggiungerai i controlli per cambiare il colore del pennello. Crea due nuovi file, un controller e le sue specifiche, eseguendo i seguenti comandi.
touch app / controller / painting_controller.rb touch spec / controller / painting_controller_spec.rb
Implementare il PaintingController
lo scheletro insieme alle sue specifiche.
classe PaintingController < UIViewController end
Descrivere PaintingController esegue i test di PaintingController,: storyboard => 'main',: id => 'PaintingController' fine
RubyMotion gestisce le specifiche del controller in un modo speciale. Il prova PaintingController,: storyboard => 'main',: id => 'PaintingController'
linea del file spec dice a RubyMotion di usare il controller con un ID storyboard di PaintingController
nel principale storyboard. Puoi usare il controllore
variabile per testarlo.
Successivamente, dovrai aggiungere punti vendita al tuo controller. Questi ti permettono di connettere oggetti al tuo controller in Interface Builder.
classe PaintingController < UIViewController extend IB outlet :black_button outlet :purple_button outlet :green_button outlet :blue_button outlet :white_button def select_color(sender) end end
estendere IB
aggiunge diversi metodi al controller, inclusi presa
. Hai aggiunto cinque punti vendita, uno per ogni pulsante.
Le immagini per i pulsanti sono incluse nei file sorgente di questo tutorial. Scarica le immagini e copiali nel risorse directory. È necessario rigenerare il progetto Xcode per consentire a Interface Builder di raccogliere le modifiche apportate. Il modo più semplice per farlo è chiudendo Xcode ed eseguendo bundle exec rake ib: aperto
, che riaprirà il progetto.
Seleziona il controller di visualizzazione e modifica la sua classe in PaintingController
.
Aperto spec / app_delegate_spec.rb e modificare l'ultima specifica per verificare il PaintingController
classe.
"imposta il controller della vista radice" do @ application.windows.first.rootViewController.should.be.instance_of PaintingController end
Aggiungi cinque pulsanti alla vista del controller della vista trascinando Pulsante oggetti sulla vista dal Libreria di oggetti sulla destra.
Questi pulsanti sono un po 'noiosi. Seleziona il primo pulsante, cambia il suo tipo in costume
nel Ispettore degli attributi a destra e rimuovere il suo titolo. Assicurati di Predefinito
lo stato è selezionato nel Stato Config menu a discesa e impostare l'immagine di sfondo su button_black.png
. Impostare il Tinta proprietà del pulsante per trasparente.
Impostare il Stato Config menu a discesa a Selezionato
e cambia l'immagine di sfondo in button_black_selected.png
.
Nel Ispettore di taglia, cambia la larghezza e l'altezza del pulsante in 50
.
Ripeti questa procedura per gli altri pulsanti.
Il prossimo passo è quello di agganciare i pulsanti alle prese del controller della vista che abbiamo dichiarato in precedenza. Tenere premuto il tasto Controllo tasto sulla tastiera e trascina dal controller della vista al primo pulsante. Quando si rilascia il mouse, viene visualizzato un menu. Selezionare black_button
dal menu. Quindi, tieni premuto il tasto Controllo tasto e trascinare dal pulsante al controller della vista e scegliere il select_color
metodo dal menu che si apre. Ripeti questi due passaggi per gli altri pulsanti.
Infine, seleziona il primo pulsante e fai clic su Selezionato checkbox sotto Controllo nel Ispettore degli attributi.
Ora è il momento giusto per aggiungere alcune specifiche utili a spec / painting_controller_spec.rb.
descrivere PaintingController esegue i test di PaintingController,: storyboard => 'main',: id => 'PaintingController' descrive "#black_button" do it "è connesso nello storyboard" do controller.black_button.should.not.be.nil end end descrive "#purple_button" fallo "è connesso nello storyboard" do controller.purple_button.should.not.be.nil end end descrive "#green_button" fallo "è connesso nello storyboard" do controller.green_button.should.not. be.nil end end descrive "#blue_button" do it "è connesso nello storyboard" do controller.blue_button.should.not.be.nil end end descrive "#white_button" do it "è connesso nello storyboard" do controller. white_button.should.not.be.nil end end end
Queste specifiche assicurano che le prese siano correttamente connesse in Interface Builder. Come sempre, è una buona idea eseguirli prima di procedere per assicurarsi che passino tutti.
Successivamente, implementerai il select_color
metodo in PaintingController
. Quando viene chiamato questo metodo, il pulsante che è stato toccato viene selezionato e il pulsante selezionato in precedenza viene deselezionato.
def select_color (sender) [black_button, purple_button, green_button, blue_button, white_button] .each do | button | button.selected = false end sender.selected = true end
Aggiungi le specifiche a spec / controller / painting_controller_spec.rb.
descrivere "#select_color" prima di fare controller.select_color (controller.green_button) terminarlo "deseleziona gli altri colori" do controller.black_button.state.should == UIControlStateNormal controller.purple_button.state.should == UIControlStateNormal controller.blue_button.state .should == UIControlStateNormal controller.white_button.state.should == UIControlStateNormal termina "seleziona il colore" do controller.green_button.state.should == UIControlStateSelected end end
Esegui l'applicazione e assicurati che la selezione dei pulsanti funzioni. Quando si tocca un pulsante, dovrebbe aumentare di dimensioni. Mentre questo è bello, ciò che si vuole veramente è che un colore venga selezionato quando si preme il pulsante. Questo è facile da realizzare con alcune aggiunte.
Sugarcube è un set di estensioni iOS per RubyMotion che rendono più semplici, come la creazione di colori, più semplici. Inserisci gemma 'sugarcube'
al tuo Gemfile e corri installazione bundle
. Quindi aggiungi richiedere "colorazione sugarcube"
alla tua Rakefile sopra Movimento :: :: Progetto App.setup
.
La gemma rende facile creare colori usando il loro codice esadecimale. Nel PaintingController
class, aggiungi il seguente frammento di codice sotto la dichiarazione dei punti vendita:
COLORS = ["# 333333" .uicolor, "# 7059ac" .uicolor, "# 196e76" .uicolor, "# 80a9cc" .uicolor, "#fafafa" .uicolor]
Successivamente, refactoring la matrice di pulsanti in select_color
in un metodo di supporto privato:
def pulsanti select_color (sender) .each do | button | button.selected = false end sender.selected = true @color = COLORS [sender.tag] end pulsanti def privati [black_button, purple_button, green_button, blue_button, white_button] end
Infine, aggiungi un nuovo metodo di seguito select_color
che restituisce il colore selezionato.
def selected_color COLORS [buttons.find_index | button | button.state == UIControlStateSelected] end
Questo metodo acquisisce l'indice del pulsante selezionato e seleziona il colore corrispondente. Ovviamente, questo metodo non sarebbe completo senza test.
descrivere "#selected_color" prima di fare controller.select_color (controller.green_button) terminare "restituisce il colore corretto" do controller.selected_color.should == PaintingController :: COLORS [2] end end
Esegui nuovamente la tua applicazione per assicurarti che tutto funzioni come previsto.
Hai coperto molto terreno in questo tutorial. Hai imparato come configurare ed eseguire un'applicazione RubyMotion, hai lavorato con Interface Builder e hai creato un'interfaccia utente.
Nella seconda parte di questo tutorial, approfondirai il modello Model-View-Controller su iOS e l'organizzazione della tua applicazione. Aggiungerai anche una vista pittura e scrivi il codice che consente all'utente di disegnare. Rimanete sintonizzati.