Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
Informace
Programování pro iOS - 2. Začínáme programovat
12. srpna 2010, 00.00 | Rozdíly mezi Mac OS X a jeho omezenou, uzavřenou verzí iOS máme za sebou. Dnes se pustíme do samotného programování pro iOS.
Na čas se v našem seriálu o objektovém programování v prostředí Cocoa soustředíme na sestavování aplikací pro iOS – tedy pro iPhone, iPod Touch, iPad a případné další potvory, řízené týmž operačním systémem, které si na nás Apple v budoucnosti vymyslí.
Minule jsme si jen velmi orientačně letem-světem ukázali ty hlavní a nejzásadnější rozdíly mezi Mac OS X (a psaním aplikací pro něj, tedy něčím, čím se zabýváme už několik let) a jeho omezenou, uzavřenou verzí iOS. Dnes se do programování pro iOS pustíme doopravdy.
Co potřebujeme
Potřebujeme především Mac mladší než hnědé uhlí. Na žádné jiné platformě (ponecháme-li stranou "Hackintoshe" na jedné straně a "jailbreak" na straně druhé) pro iOS v současnosti vyvíjet nelze. Dále pak na něm musíme mít instalované vývojové prostředí Xcode v některé z aktuálních verzí (spolu s dalšími pomocnými programy, především s Interface Builderem), a v něm musíme mít vývojový "plugin" pro "platformu" iPhone.
Xcode – stejně jako ostatní vývojářské prostředky – nalezneme standardně ve složce /Developer. Vlastní aplikace Xcode je v /Developer/Applications. Instalované platformy pak jsou ve složce /Developer/Platforms; prozatím je třeba, abychom tam měli alespoň "iPhoneSimulator.platform". Kdo je tam má, může přeskočit na další oddíl. Ostatní mohou číst dále.
Pokud cokoli z toho chybí, je zapotřebí získat a nainstalovat aktuální vývojářské prostředí. To Apple nabízí zdarma, ale nikoli zcela volně. Abychom je mohli získat, musíme mít libovolnou vývojářskou registraci. Ta základní je zdarma a můžeme si ji kdykoli vytvořit přímo na stránkách Apple.
Otevřeme tedy stránku developer.apple.com/iphone a pomocí odkazu vpravo nahoře se přihlásíme (pokud již vývojářskou registraci u Apple máme), nebo zaregistrujeme a vyplníme to, co Apple vyplnit požaduje. Po (případné registraci a) úspěšném přihlášení klepneme na odkaz "Downloads" – je ve stránce hned první – a stáhneme si aktuální "Xcode and iOS SDK"; ve chvíli psaní tohoto článku jde o Xcode 3.2.3 a SDK 4.0.1, ale pro naše první krůčky není konkrétní verze ani jednoho, ani druhého příliš podstatná. Balík, obsahující vývojové prostředí, standardně otevřeme a nainstalujeme – standardní volby obvykle není zapotřebí měnit (resp. ten, kdo tak činit potřebuje, obvykle sám ví proč a jak).
Vlastní zařízení prozatím potřebovat nebudeme a spokojíme se s prací v emulátoru. Až se později dostaneme k práci se zařízením, budeme potřebovat také odpovídající certifikáty, jak jsme si řekli minule; to ale zatím ponecháme stranou.
První projekt
Spustíme aplikaci Xcode ze složky /Developer/Applications. Prozatím si její detaily popisovat nebudeme; v základních rysech stále platí to, co jsme si o ní řekli před šesti lety, a věci, které jsou mezitím jinak a (obvykle, bohužel zdaleka ne vždy) lépe, si ukážeme přímo při práci.
Začneme tedy rovnou tím, že vytvoříme nový projekt: z nabídky vybereme příkaz "File / New Project...", a v panelu, který se nám otevře, zvolíme "iPhone OS / Application / Utility Application" a přepínač "Use Core Data for storage" ponecháme vypnutý.
Xcode (či, přesněji řečeno, zvolená platforma) obsahuje předem připravené vzory pro nejčastěji užívané typické konfigurace projektu – použití takového vzoru nám ušetří trochu práce. Vzor "Utility Application" je aplikace, jež má jednu "pracovní" stránku a jednu stránku s nastavením a dalšími informacemi, do níž se může uživatel přepnout pomocí standardní ikonky "i" v pravém dolním rohu, podobně, jako tomu je např. ve standardní aplikaci "Stocks".
Po klepnutí na tlačítko "Choose..." vybereme místo, kam se má projekt uložit, zadáme jeho jméno a Xcode jej připraví a otevře. Podívejme se, co vše nám vzor projektu vytvořil:
Ponecháme-li stranou standardní soubor "main.m" (do nějž prakticky nikdy nezasahujeme, a který obsahuje pouze volání jednoduché knihovní funkce, která obsahuje vše potřebné pro vlastní spuštění aplikace) a pomocný soubor .pch (ten nás prozatím nemusí zajímat vůbec), budou pro nás podstatné následující soubory zhruba v tomto pořadí:
• (jméno projektu)-Info.plist: soubor, který obsahuje obecné informace o naší aplikaci. Jeho obsah málokdy editujeme přímo; obvykle k tomu používáme inspektor cíle (když jsme si jej před lety popisovali, užívali jsme ohavného tvaru "inspektor targetů"). To si ukážeme za chvilku; prozatím stojí za zmínku to, že kromě jiného je v tomto souboru uložena informace o tom, že hlavní objektová síť aplikace se jmenuje "MainWindow.nib" (co je objektová síť víme už dávno; je ale vhodné zdůraznit, že současný Interface Builder se od toho, který jsme si tehdy popsali, liší. A ještě více se liší základní grafické uživatelské rozhraní aplikací pro iPhone od toho, jež jsme si ukázali u aplikací Mac OS X);
• MainWindow.xib je objektová síť, representující hlavní (a jediné) okno aplikace: vedle samotného okna je zde uložena také instance (co je to instance?) našeho aplikačního delegáta (co je to delegát?), a instance řídicího objektu hlavního rámce (k tomu se hned dostaneme). Na rozdíl od Mac OS X, v němž bývá práce s okny nezřídka dost složitá, v aplikacích iOS je prakticky vždy jen jedno jediné okno, s nímž neděláme zhola nic – pouze uvnitř něj podle potřeby měníme rámce ("views"), obsahující vlastní grafické uživatelské rozhraní. Nepřekvapí proto, ponecháme-li tento soubor zcela beze změny;
• (jméno projektu)AppDelegate.h a (jméno projektu)AppDelegate.m: zdrojový kód delegáta aplikace – tedy řídicího objektu, s nímž se knihovní aplikační kód "radí" o tom, co a jak přesně udělat, kdykoli dojde k nějaké události, jež je pro aplikaci významná. Později si ukážeme, k čemu a jak jej můžeme využít; prozatím jej ale ponecháme také beze změny, protože nám postačí zcela standardní funkčnost, již jsme dostali "zadarmo" na základě projektového vzoru. Ta totiž standardně již obsahuje to hlavní (a také prakticky jediné) co v jednoduché aplikaci od delegáta potřebujeme – instalaci hlavního rámce ("MainView") do okna a jeho zobrazení poté, co byla aplikace spuštěna;
• Funkčnost prvků grafického uživatelského rozhraní uložených v hlavním rámci zajišťuje kód jeho řídicího objektu; ten máme připravený v souborech MainViewController.h a MainViewController.m. Uvidíme, že kromě jiného zde je pro nás již předem připravená služba, jež po stisknutí standardního tlačítka "i" do hlavního (a jediného) okna aplikace umístí druhý rámec ("FlipsideView");
• MainView.xib je objektová síť hlavního rámce – tedy primárního grafického uživatelského rozhraní naší aplikace. Řídicí objekt si ji načte zcela automaticky ve chvíli, kdy je to zapotřebí (a to nastane na základě kódu, který nám projektový vzor uložil do delegáta). Tímto souborem tedy při práci na aplikaci začneme – otevřeme jej jako první (v aplikaci, jež je pro editaci objektových sítí určena, tedy v Interface Builderu), a začneme v něm sestavovat uživatelské rozhraní. Uvidíme, že kromě jiného zde je pro nás již předem připraveno standardní tlačítko "i" vpravo dole (a že je navázáno na odpovídající službu řídicího objektu);
• Podobně pak objektová síť FlipsideView.xib representuje druhý rámec – ten, který se objeví jako druhá část grafického uživatelského rozhraní po přepnutí pomocí tlačítka "i". Projektový vzor Xcode nám do něj připravil tlačítko "Done". Kód zajišťující odpovídající funkčnost pro prvky z rámce "Flipside" implementujeme ve zdrojových souborech FlipsideViewController.h a FlipsideViewController.m – uvidíme opět, že díky projektovému vzoru už je tam hotová služba pro návrat k hlavnímu rámci, s tlačítkem "Done" již spojená.
Funkční struktura aplikace
Podívejme se znovu na vnitřní strukturu aplikace a na vzájemné vazby jejích jednotlivých prvků – začínáte-li s programováním, čtěte pomalu, krok za krokem:
Výchozím bodem je kód, vygenerovaný ze souboru main.m (v jazyce C):
// podstatná část souboru main.m:
int main(int argc, char *argv[]) {
... zatím nedůležité ...
int retVal=UIApplicationMain(argc,argv,nil,nil);
... zatím nedůležité ...
return retVal;
}
právě ten – konkrétně funkce main – se vždy spustí jako první po startu aplikace. Nedělá ovšem nic jiného, než že zavolá jednu jedinou nejzákladnější knihovní funkci UIApplicationMain; a ta sama "rozjede" veškeré standardní chování aplikace.
To zahrnuje především načtení informačního souboru Info.plist (který je v podstatě kopií našeho zdrojového souboru (jméno projektu)-Info.plist v projektu); v něm se zjistí jméno základní objektové sítě – MainWindow.nib:
// podstatná část souboru ...Info.plist:
... zatím nedůležité ...
<key>NSMainNibFile</key>
<string>MainWindow</string>
... zatím nedůležité ...
Soubor MainWindow.nib vzniká překladem našeho zdrojového souboru MainWindow.xib v projektu. Ten, jak jsme si řekli výše, obsahuje hlavní okno, instanci aplikačního delegáta a instanci řídicího objektu hlavního rámce. Delegát vznikl překladem zdrojového souboru (jméno projektu)AppDelegate.m v projektu, a jeho součástí je mj. tento kód (v Objective C):
// podstatná část souboru ...AppDelegate.m:
... zatím nedůležité ...
-(BOOL)application:
(UIApplication*)application
didFinishLaunchingWithOptions:
(NSDictionary*)launchOptions {
[window addSubview:mainViewController.view];
[window makeKeyAndVisible];
return YES;
}
... zatím nedůležité ...
Až se budeme zabývat objektovými sítěmi a aplikací Interface Builder, ukážeme si, jak je zajištěno, aby v proměnné view byl odkaz na okno a v proměnné mainViewController aby byl odkaz na řídicí objekt hlavního rámce.
Aplikace po spuštění svému delegátu vždy pošle zprávu (co je to zpráva?) application:didFinishLaunchingWithOptions: – a v jejím těle se nejprve uloží do okna window rámec mainViewController.view – řídicí objekt má vždy odkaz na svůj rámec v atributu view (co je to atribut?) – a okno se zobrazí zprávou makeKeyAndVisible.
V tuto chvíli tedy aplikace "běží" – na displeji iPhonu (nebo simulátoru) vidíme všechny grafické prvky hlavního rámce; jeho řídicí objekt je připraven zajistit všechny služby, které si jejich pomocí vyžádáme. Kromě toho je v paměti řada objektů, jež nás příliš nezajímají: delegát aplikace už svou povinnost splnil (ale nadále zůstává k dispozici, kdyby jej snad někdo potřeboval); okno slouží jako "pozadí", v němž se zobrazuje náš rámec.
A co druhý rámec a jeho řídicí objekt?
Zatím nic. Tak dlouho, dokud uživatel neklepne na tlačítko "i" v pravém dolním rohu. Pokud to udělá, tlačítko pošle řídicímu objektu zprávu showInfo: (to je tak nastaveno v objektové síti MainWindow.xib pomocí mechanismu akce/cíl). Odpovídající metoda (co je to metoda?) řídicího objektu vypadá takto:
// podstatná část souboru MainViewController.m:
... zatím nedůležité ...
-(IBAction)showInfo:sender {
FlipsideViewController *controller=
[[FlipsideViewController alloc]
initWithNibName:@"FlipsideView" bundle:nil];
controller.delegate=self;
controller.modalTransitionStyle=
UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller
animated:YES];
[controller release];
}
... zatím nedůležité ...
Detaily si vysvětlíme později – a zkušenější programátoři jistě tuší –, ale v zásadě se zde nejprve vytvoří řídicí objekt druhého rámce (až dosud jeho instance k dispozici nebyla), specifikuje se, že jeho obsah (objektová síť s prvky grafického uživatelského rozhraní) je uložena v souboru FlipsideView.nib, a celé se to s patřičnou animací zobrazí "přes" hlavní rámec (přitom si ovšem řídicí objekt vlastní objektovou síť ze souboru FlipsideView.nib automaticky načte).
Zbývá už jen otázka, jak se druhý rámec opět skryje: to nastane ve chvíli, kdy v něm uživatel klepne na tlačítko "Done". To je – opět pomocí mechanismu akce/cíl – propojeno s metodou done: v řídicím objektu. Ta by mohla rámec zrušit rovnou; programátoři Apple, kteří připravovali projektový vzor, však raději skrytí implementovali v řídicím objektu hlavního rámce – a řídicí objekt "Flipside" si to jen vyžádá pomocí zprávy flipsideViewControllerDidFinish:, takto:
// podstatná část souboru FlipsideViewController.m:
... zatím nedůležité ...
-(IBAction)done:sender {
[self.delegate flipsideViewControllerDidFinish:self];
}
... zatím nedůležité ...
// podstatná část souboru MainViewController.m:
... zatím nedůležité ...
-(void)flipsideViewControllerDidFinish:
(FlipsideViewController*)controller {
[self dismissModalViewControllerAnimated:YES];
}
... zatím nedůležité ...
A to je prozatím vše.
Pokud není něco zřejmé, napište prosím do diskuse; zkušeným programátorům v Cocoa, obávám se, bude tento článek připadat rozvláčný, ovšem je také možné, že mezi čtenáři se objeví řada těch, kdo s programováním teprv začínají – proto zatím postupujeme zvolna.
Příště začneme pracovat na tom, aby naše aplikace "opravdu něco dělala" – tedy něco více, než zobrazení dvou prázdných rámců (až na standardní tlačítka) a přepínání mezi nimi.
Obsah seriálu (více o seriálu):
- Nastal čas na kakao...
- Tak nejdřív kakao ochutnáme...
- Programovací jazyk C: velmi, velmi stručně
- Objective C: to si vysvětlíme podrobněji
- Co jsme si o Objective C ještě neřekli...
- Nastal čas na kakao - Vznik a zánik objektů
- Nastal čas na kakao - Kopírování objektů
- Nastal čas na kakao - Skryté podtřídy
- Nastal čas na kakao - Základní služby objektů
- Nastal čas na kakao - Jak správně psát v Objective C
- Nastal čas na kakao - Jak správně importovat
- Nastal čas na kakao - Podtřídy, delegáti, vkládání, jak se to rýmuje?
- Nastal čas na kakao - Využití kategorií namísto dědičnosti
- Nastal čas na kakao - Vkládání objektů a přesměrování zpráv
- Nastal čas na kakao - Inicializace a rušení objektů
- Nastal čas na kakao - Metody initWith... a designovaný inicializátor
- Nastal čas na kakao - Inicializace: tipy a triky
- Nastal čas na kakao - Accesory: přístup k proměnným instancí
- Nastal čas na kakao - Šedá je teorie, zelený je strom života...
- Nastal čas na kakao - Více o XCode: inspektory
- Nastal čas na kakao - Aplikace RSS2: datový model
- Nastal čas na kakao - Aplikace RSS: implementace datového modelu
- Nastal čas na kakao - Aplikace RSS: parsování XML
- Nastal čas na kakao - Interface Builder a uživatelské rozhraní
- Nastal čas na kakao - Interface Builder: atributy objektů
- Nastal čas na kakao - Interface Builder: atributy objektů
- Nastal čas na kakao - Druhý kontrolér a dokončení aplikace
- Nastal čas na kakao - Drobná vylepšení a zdokonalení...
- Nastal čas na kakao - Ladění
- Nastal čas na kakao - Třídy Foundation Kitu
- Nastal čas na kakao - Třídy Foundation Kitu (2)
- Nastal čas na kakao - Textové řetězce: NS(Mutable)String
- Nastal čas na kakao - Čísla, binární data a další...
- Nastal čas na kakao - Archivace objektů
- Nastal čas na kakao - Trocha magie, aneb distribuované objekty
- Nastal čas na kakao - Málem bychom zapomněli: NSAutoreleasePool
- Nastal čas na kakao - Zpracování výjimek: NSException
- Nastal čas na kakao - NSInvocation a černá magie
- Nastal čas na kakao - Kakao v Tygrovi
- Nastal čas na kakao - Notifikace: nepřímé předávání zpráv
- Nastal čas na kakao - NSUserDefaults
- Nastal čas na kakao - Co nového ve Foundation Kitu
- Nastal čas na kakao – s Intelem, s Intelem, jedeme do...
- Co nového v Xcode
- Začínáme s AppKitem
- Jak MVC v Kakau vypadá doopravdy?
- Jak MVC v Kakau vypadá doopravdy: dokončení
- Přehled tříd AppKitu
- Nastal čas na kakao - Přehled tříd AppKitu 2
- Přehled tříd AppKitu 3: zbývající třídy GUI
- Přehled tříd AppKitu 4: textový systém
- Nastal čas na kakao - Přehled tříd AppKitu 5: hlavně grafika
- Přehled tříd AppKitu 6: dokumentový systém
- Přehled tříd AppKitu 7: dokončení
- Pojmenované vlastnosti objektů
- Pojmenované vlastnosti objektů: implementace
- Pojmenované vlastnosti objektů: relace 1:N
- Pojmenované vlastnosti objektů: řazení jmen a agregační funkce
- Sledování změn objektů
- Sledování změn objektů – ukázka
- Sledování změn objektů – zdrojový kód
- Sledování změn objektů: kód modelu
- Sledování změn objektů: přímý přístup
- Kontroléry a vazby
- Vázání vazeb
- Další vazby s jednoduchým kontrolérem
- Implementace a použití převodu hodnot
- Validace hodnot
- Validace a chyby, a jedna hezká vazba...
- Práce s polem objektů
- Základní vazby NSArrayControlleru
- Převodníky, přepínače, placeholdery
- Mírná vylepšení v mezích zákona
- Objective C 2.0 - novinky z Leoparda
- NSTreeController
- Programování v Cocoa - Pár tipů a triků
- Programování v Cocoa - Základy kreslení
- Kterak nakreslit modrý obdélník...
- Další služby pro kreslení
- Obrázky a písmenka...
- Události a myš
- Lepší práce s myší
- Události klávesnice
- Input Management
- Příkazy a schránka
- Další události
- Táhni a padni
- Byli jsme na tahu; nyní padneme.
- Zvolme si, jak vhodit
- Drobnosti a chybičky
- Speciální případy tahání či házení
- Kterak táhnout něco, co neexistuje?
- Jak na sítě...
- NSURLConnection
- Safari za minutu
- Služby WebKitu
- Kakao v Leopardu
- Druhé Objective C
- Druhé Objective C: různé drobnosti
- Druhé Objective C: kategorie a protokoly
- Druhé Objective C: nový příkaz cyklu
- Druhé Objective C: atributy a accesory
- Druhé Objective C: atributy a accesory
- 64 je dvakrát 32
- Ubicumque dulce est, ibi et acidum invenies...
- Irbis: že prý žádné novinky?
- Blok sem, blok tam, nám už je to všechno jasné...
- Bloky jsou i v AppKitu
- Irbis a Foundation Kit
- Kde jsou má data?
- Kde jsou má data? V NSCache!
- Soubor, jméno, URL, jak se to rýmuje...
- Další podpora NSURL
- Zabíjení!
- A máme tady i...OS!
- Systémové prvky GUI
- Programování pro iOS 1. díl - Rozdíly mezi "i" a "Mac"
- Programování pro iOS - 2. Začínáme programovat
- Programování pro iOS - 3. základní ovladače a propojení GUI s kódem
- Programování pro iOS - 4. Varovná hlášení
- Programování pro iOS - 5. Rámce a jejich řídicí objekty
- Programování pro iOS - 6. Ukládání dat
- Programování pro iOS - 7. Správa paměti a starý restík
- Programování pro iOS - 8. Dokončení aplikace
- Programování pro iOS - 9. Jak dostat aplikaci do iPhone
- Programování pro iOS - 10. Instalace aplikace do cizího iPhone
- Programování pro iOS - 11. Jak dostat aplikaci do libovolného iPhone
- Programování pro iOS - 12. Touching!
- Programování pro iOS - 13. Kreslíme na iPhone
- Programování pro iOS - 14. Udělejme gesto
- Programování pro iOS - 15. Další gesta
- Programování pro iOS - 16. Více prstů, více zábavy
- Programování pro iOS - 17. Podpora standardních gest
- Programování pro iOS - 18. Recognizery v iOS
- Programování pro iOS - 19. Další standardní recognizery
- Programování pro iOS - 20. Co nového v iOSu
- Programování pro iOS - 21. "Multitasking"
- Programování pro iOS - 22. Nulla est honesta avaritia nisi temporis
- Programování pro iOS - 23. Jak se aktivovat, jsme-li v pozadí
- Programování pro iOS - 24. Zbývající drobnosti
- Programování pro iOS - 25. Řídicí objekty rámců
- Programování pro iOS - 26. Jak se dělá UIViewController
- Programování pro iOS - 27. Kde vzít rámce
- Programování pro iOS - 28. Základní služby
- Programování pro iOS - 29. Práce s rámci
- Programování pro iOS - 30. Rotace zařízení
- Programování pro iOS - 31. Správa paměti v rámcích
- Programování pro iOS - 32. Řídicí objekt pro tabulky
- Programování pro iOS - 33. Řídicí objekt pro strom
- Programování pro iOS - 33. Více o UINavigationControlleru
- Programování pro iOS - 35. Ještě jednou UINavigationController
- Programování pro iOS - 36. Po navigátoru taby
- Programování pro iOS - 37. Více o UITabBarControlleru
- Programování pro iOS - 38. Dokončení UITabBarControlleru
- Programování pro iOS - 39. UIPopoverController
- Programování pro iOS - 40. Další triky UIPopoverControlleru
- Programování pro iOS - 41. Zbývající služby UIPopoverControlleru
- Programování pro iOS - 42. UISplitViewController
- Programujeme v
iTunesXcode 4 - Programování pro iOS - 44. Předvolby Xcode 4
- Programování pro iOS - 45. Práce v Xcode 4
- Xcode 4: projekt a cíle
- Xcode 4: práce s cíli
- Xcode 4: Build Settings
- Xcode 4: Build Phases
- Xcode4: Build Phases podruhé
- Xcode 4: Co jsou to Build Rules?
- Xcode4: taje editoru
- Xcode4: automatické doplňování v editoru
- XIBy chyby
- Více o XIBech
- Editor XIBů
- Inspektory pro XIBy
- Vazby mezi objekty v XIBech
- Vazby mezi objekty v kódu
- Paletky Xcode pro XIBy
- Xcode 4: levý sloupec
- Xcode 4: okno Organizer
- Xcode 4: okno Organizer, část druhá
- Xcode 4: co je to Workspace?
- Xcode 4: základy schémat
- Xcode 4: akční schémata