Hlavní navigace

Vývoj pro mobilní platformy s C# (druhá část)

Jan Pospíšil

V druhém dílu našeho třídílného seriálu bych vám rád ukázal nějaké praktické ukázky vývoje jednoduché aplikace pro iPhone. V následujícím textu vám proto představím vývojářské nástroje, potřebné knihovny a postupy, jak se vyrovnat s problémy vývoje na mobilní platformě s operačním systémem iOS.

Hello World pro MonoTouch

Pokud chceme vyvíjet jakoukoliv aplikaci pro jakýkoliv produkt Apple, je třeba ji vyvíjet v operačním systému Mac OS X. Dále potřebujeme mít naistalovány:

  • Xcode 4 – je IDE(Integrated Development Environment) pro vývoj aplikací pro produkty Apple, je ho možné získat na OS X App Store, a pouze pokud máme koupený vývojářský profil od Apple. S Xcode získáme také SDK knihoven, přístup do dokumentace a simulátory Apple mobilních zařízení.

  • Mono Framework – je možné stáhnout z oficiálních webových stránek Mono projektu.

  • MonoDevelop – je IDE pro vývoj Mono aplikací

  • MonoTouch

Apple zakazuje ve svých aplikacích mechanismy dovolující vykonávání dalšího kódu, což vylučuje nestandardní běhové systémy, JIT (just-in-time) kompilátory a interprety bytového kódu. Mono stejně jako .Net framework JIT kompilátor používá a až následně převádí bytový kód do vlastního kódu cílové platformy až v běhové fázi. Tento nepřekonatelný problém byl velkou výzvou pro vývojáře Mona. Naštěstí kompilátor Applu podporuje i alternativní model AOT (ahead-of-time), který převede do vlastního kódu cílové platformy jazyk .NET CIL (Common Intermediate Language – obecný zprostředkující jazyk) již v době kompilace. A takto lze Mono aplikace staticky zkompilovat do spustitelných souborů nevyžadujících virtuální stroje či jiné běhové komponenty zakazované Apple. Tento mechanismus už nyní využívá řada her pro iPhone postavených na 3D jádru Unity. To rovněž užívá AOT kompilaci a přijetí mnoha her s tímhle jádrem na App Store dokazuje, že Apple dané řešení považuje za přijatelné.

Správa paměti v Objective-C a v .Net frameworku je velmi odlišná. Objective-C totiž nemá garbage collector implementován stejně jako v .Net frameworku. Paměť pro objekty v Objective-C je ve starších verzích jazyka alokována a uvolňována manuálně. Až od verze 2.0 se používá strategie počítání referencí. Tato strategie uvolňování paměti není v praxi příliš efektivní, proto většina Apple programátorů uvolňuje paměť stále manuálně. MonoTouch sice implementovalo svůj garbabe collector, ale ten nereaguje s dostatečnou pružností. A proto všechny objekty v MonoTouch mají rozhraní IDisposable, aby mohl být každý objekt v MonoTouch uvolněn voláním funkce Disponse. iPhone má velice omezené zdroje a proto programátor musí být velice precizní při uvolňování paměti, ale pokud i přesto na nějaký objekt zapomenete, MonoTouch garbage collector se o něj postará.

Objective-C má vlastnost protocols. Protocols jsou velmi podobné rozhraním v .Net. Definují seznam metod, které třída implementuje, a třída může implementovat jakýkoliv počet protokolů. Je zde jedna důležitá odlišnost a to, že metody obsažené v protokolu nemusí být implementována v třídě, která tento protokol implementuje. MonoTouch to vyřešilo pomocí abstraktních tříd a virtuálních metod. Toto řešení není ideální jelikož .Net nepodporuje vícenásobnou dědičnost. Tento problém se vyřešil pomocí událostí. Virtuální metody, které jsou uvedeny ve více než jednom protokolu, publikují svoje volání pomocí událostí na svoje přepsané potomky. Tuto osvědčenou strategii MonoTouch používá k implementaci více vlastností Objective-C.

Nyní vytvoříme jednoduchou aplikaci s MonoTouch. Aplikace bude mít na úvodní obrazovce pouze jedno tlačítko, po kliknutí na toto tlačítko se objeví druhá obrazovka s textem, který bude obsahovat čas kdy bylo kliknuto na tlačítko. V MonoDevelop vytvoříme nový prázdný projekt, viz Obrázek 1.



V nastavení projektu lze nastavit verzi SDK jaký budeme používat, kde budeme projekt spouštět a také je zde nastaveni linkování projektu. Prázdný projekt obsahuje pouze tři soubory:

  • AppDelegate.cs – je delegát aplikace, který se stará o životní cyklus aplikace.

  • Main.cs – je vstupním bodem aplikace

  • Info.plist – je konfiguračním souborem aplikace

Každá obrazovka v iOS implementuje návrhový vzor Model View Controller, proto dále přidáme do projektu dva nové View Controllery, viz Obrázek 2:

  • MainViewController – toto bude úvodní obrazovka.

  • SecondViewController – bude druhá obrazovka, na kterou aplikace přejde po kliknutí na tlačítko.



Každý View Controller obsahuje tři soubory:

  • MainViewController.xib – obsahuje definici grafického rozhraní, něco jako xaml soubor ve WPF, tento soubor je třeba vytvořit v Xcode. Jde o to jen navrhnout grafické rozložení ovládacích prvků na obrazovce, viz Obrázek 3.

  • MainViewController.designer.cs – je definice rozhraní mezi aplikaci a grafickým rozhraním.

  • MainViewController.cs – je výkonný kód View Controlleru.



Dvojklikem otevřeme MainViewController.xib v Xcode, pomocí návrháře GUI přidáme tlačítko, stejně jako když vyvíjíme klasickou aplikaci v Objective-C. Na tlačítko přidáme ještě akci kliknutí. Přidávat na View Controllery můžeme dva typy objektů:

Outlets – jsou analogické k C# propertám.

Actions – jsou analogické k událostem ve WPF.

Po ukončení editace xib souboru v Xcode a po jeho uložení se můžeme pustit do psaní vlastního výkonného kódu. Po uložení se změny v xib souboru, vytvoření grafických prvků, outletů a akcí, projeví v našem MainViewController.designer.cs, jak je vidět na Příkladu 1.

using MonoTouch.Foundation;
namespace Chapter2.MonoTouchApp
{
    [Register ("MainViewController")]
    partial class MainViewController
    {
        [Outlet]
        MonoTouch.UIKit.UIButton Button { get; set; }

        [Action ("ButtonTapped:")]
        partial void ButtonTapped (MonoTouch.Foundation.NSObject sender);
    }
}

Dále upravíme soubor AppDelegate.cs, viz Příklad 2, tak, aby se MainViewController zobrazil při startu aplikace.

using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace Chapter2.MonoTouchApp
{
    [Register ("AppDelegate")]
    public partial class AppDelegate : UIApplicationDelegate
    {
        private UIWindow _window;
        private UINavigationController _navigationController;
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            _window = new UIWindow (UIScreen.MainScreen.Bounds);
            _navigationController = new UINavigationController();
            _navigationController.PushViewController(new MainViewController(), false);
            _window.RootViewController = _navigationController;
            _window.MakeKeyAndVisible ();
            return true;
        }
    }
}

Nyní musíme upravit MainViewController.cs, který definuje životní cyklus obrazovky. Toto chování se definuje pomocí přepisovaní virtuálních funkcí UIViewController rozhraní, viz Příklad 3. Funkce ViewDidLoad je zavolána po inicializaci všech Views, potom je možné provést nastavení zobrazených komponent na obrazovce. Ve funkci ButtonTapped je implementováno chování po kliknutí na tlačítko, vytvoříme instanci druhé obrazovky, pošleme čas stisku tlačítka a nakonec ji zobrazíme.

using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace Chapter2.MonoTouchApp
{
    public partial class MainViewController : UIViewController
    {
        public MainViewController() : base ("MainViewController", null)
        {
        }
        public override void ViewDidLoad()
        {
            base.ViewDidLoad ();
            Title = "Hello, iOS!";
            Button.SetTitleColor(UIColor.Red, UIControlState.Normal);
        }
        partial void ButtonTapped(NSObject sender)
        {
            NavigationController.PushViewController(
            new SecondViewController(DateTime.Now.ToLongTimeString()), true);
        }
    }
}

Poslední, co je třeba udělat, je upravit SecondViewController.cs, přidat mu vlastnost, přes kterou budeme předávat řetězec s časem stisku tlačítka a nastavit text labelu tak, aby tento řetězec zobrazil, viz Příklad 4.

using MonoTouch.UIKit;
namespace Chapter2.MonoTouchApp
{
    public partial class SecondViewController : UIViewController
    {
        private readonly string _text;
        public SecondViewController(string text) : base ("SecondViewController", null)
        {
            _text = text;
        }
        public override void ViewDidLoad()
        {
            base.ViewDidLoad ();
            Title = "Second View";
            ReceivedText.Text = _text;
        }
    }
}

Aplikace můžeme nyní už spustit. Z MonoDevelop můžeme aplikaci spustit v simulátoru, viz Obrázek 4, nebo přímo do iPhone nebo iPad zařízení. Simulátor sice dokáže nasimulovat většinu funkcí Apple zařízení, ale některé funkce ano, jako např. ovládání více prsty, akcelerometer, lokalizaci, a jiné. Proto je někdy dobré testovat aplikace využívající tyto funkce přímo na zařízení.

Našli jste v článku chybu?

25. 4. 2013 10:20

Multiplatformí vývoj určitě. Ale tohle je na Applu pro Apple s nástoroji a programovacím jazykem Microsoftu. Na serveru primárně o Linuxu mi to přijde minimálně trochu zvláštní, zvlášť když existují lepší alternativy fungující (kromě na Apple a MS) také v Linuxu a pro Linux (Android).

25. 4. 2013 9:18

Teda že zrovna na Rootu bude článek o tom, jak programovat v C# pro iOS, to bych fakt nečekal.

Mnohem víc bych ocenil pořádný seriál o Qt5/QML. Za dveřmi je verze 5.1 s oficiální podporou Androidu (alfa už ke stažení), podpora iOS a WinRT je na cestě. Qt bude podle mě v blízké budoucnosti jednoznačně nejlepší volba pro většinu multiplatformních aplikací.

Root.cz: Nová třída SD karet A1 s vysokým výkonem

Nová třída SD karet A1 s vysokým výkonem

120na80.cz: Boreliózu nelze žádným testem prokázat

Boreliózu nelze žádným testem prokázat

Vitalia.cz: 7 originálních adventních kalendářů pro mlsné

7 originálních adventních kalendářů pro mlsné

DigiZone.cz: R2B2 a Hybrid uzavřely partnerství

R2B2 a Hybrid uzavřely partnerství

DigiZone.cz: SES zajistí HD pro M7 Group

SES zajistí HD pro M7 Group

Podnikatel.cz: Vládu obejde, kvůli EET rovnou do sněmovny

Vládu obejde, kvůli EET rovnou do sněmovny

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

DigiZone.cz: Ohrozí Freedom TV přechodové sítě?

Ohrozí Freedom TV přechodové sítě?

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

DigiZone.cz: Sat novinky: slovenská TV8 HD i ruský NTV Mir

Sat novinky: slovenská TV8 HD i ruský NTV Mir

Lupa.cz: Levný tarif pro Brno nebude, je to kartel

Levný tarif pro Brno nebude, je to kartel

Vitalia.cz: Nejlepší obranou při nachlazení je útok

Nejlepší obranou při nachlazení je útok

Měšec.cz: Za palivo zaplatíte mobilem (TEST)

Za palivo zaplatíte mobilem (TEST)

Vitalia.cz: To nejhorší při horečce u dětí: Febrilní křeče

To nejhorší při horečce u dětí: Febrilní křeče

Vitalia.cz: Test na HIV je zdarma i za pět set

Test na HIV je zdarma i za pět set

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

Podnikatel.cz: E-Ježíšek si zařádí: nákupy od 2 do 5 tisíc

E-Ježíšek si zařádí: nákupy od 2 do 5 tisíc

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky