Programování pro iOS - 2. Začínáme programovat - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

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:

Seriály

Více seriálů



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):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Tipy a Triky  

 » Rubriky  » Začínáme s  

 » Rubriky  » Software  

 

 

 

Nejčtenější články
Nejlépe hodnocené články
Apple kurzy

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: