Upload
kuba-brecka
View
251
Download
2
Embed Size (px)
DESCRIPTION
Úvod do vývoje pro platformu iOS [ZČU 24.4.2014]
Citation preview
Struktura• Dnešní přednáška – 24.4.2014
• Úvod do vývoje pro platformu iOS (135 min)
• Zítřejší workshop – 25.4.2014
• Efektivní vývoj vzdělávacích aplikací pro iOS (4x 90 min)
• praktické programování jednoduché aplikace od nuly
Obsah přednášky• Co je iOS, iPhone, iPad
• Programovací jazyk Objective-C
• IDE Xcode a iOS SDK
• Stavební bloky iOS aplikace
• Typické návrhové vzory a metodika
• App Store, iTunes Connect
Podíl v ČROstatní
9 %Windows Phone
5 %
Symbian 8 %
iOS 11 %
Android 67 %
data: srpen 2013, využití internetu ze smartphonu zdroj: Lupa.cz / Mobile Internet Forum / Seznam.cz http://www.lupa.cz/clanky/mobile-internet-forum-2013-uzivatele-utesene-rostou-nasledovat-by-mely-i-penize/
Podíl v USAOstatní
7 %
iOS 41 %
Android 52 %
data: únor 2014, aktivně používané smartphony zdroj: TheNextWeb/comScore
http://thenextweb.com/mobile/2014/04/04/comscore
Počty stažení a tržby
data: Q1 2014, počet stažení a obrat zdroj: AppAnnie
http://blog.appannie.com/app-annie-index-market-q1-2014/
“Uživatelů iPhonu je v ČR sice výrazně méně než uživatelů Androidu, ale o to více jsou slyšet v médiích. Kdo má iPhone, ten o tom rád mluví.” (volná citace)
Petr Dvořák (Inmite), mezi řečí ve výtahu
Ekosystém iOS• Apple – výrobce zařízení, dohled nad aplikacemi
• App Store – distribuční kanál aplikací
• iOS – operační systém pro iPhone, iPod Touch, iPad a Apple TV
• iPhone – mobilní telefon, iPad – tablet
• uživatelé – “vyšší” třída, nároční, ochotní platit
• Xcode, iOS SDK – nástroje pro vývojáře
Dnešní iOS zařízení• iPhone 5S
• GSM/3G/4G, retina displej, dual-core CPU, 1 GB RAM, multi-touch, gyroskop, akcelerometr, kompas, GPS, GLONASS, 2 fotoaparáty/kamery, …
• iOS 7 – 87% zastoupení
• App Store, Siri, App Store, iTunes, PassBook, FaceTime, Maps, Mobile Safari, Game Center, iMessage, Push notifications, sandboxing, …
Vývoj aplikací pro iOS• Vývojář potřebuje:
• Mac počítač (iMac, MacBook, Mac Mini, Mac Pro)
• Poslední Mac OS X (zdarma)
• Fyzické iOS zařízení
• Vývojářskou licenci ($99 ročně) – bez ní nelze testovat/ladit na fyzickém zařízení, jen v simulátoru
• Xcode (zdarma v Mac App Storu)
Xcode• Primární vývojové prostředí
• editor kódu, správa projektu, editor GUI, debugger, simulátor, verzování (Git), statická analýza, distribuce do App Storu, …
• Je aktivně vyvíjený Applem, aktualizace s novými iOS verzemi, integrace novinek z iOS
• Pouze pro OS X
• Alternativa: AppCode od JetBrains (ale stejně vyžaduje Xcode)
Demo Xcode, build&run, iOS simulator, interface
builder
Programovací jazyk Objective-C
• Rozšíření jazyka C (a není to C++)
• platný kód v C je platný i v Objective-C
• velmi často se toho využívá, např. existují některá API od Applu, která mají jen C-čkové rozhraní
• Objektově orientovaný jazyk
• třídy, metody, vlastnosti, instance, dědičnost, …
• přípona .m
Třídy v Objective-C• Hlavičkový soubor MyStack.h:
#import <Foundation/Foundation.h> !@interface MyStack : NSObject !- (void)push:(int)number; - (int)pop; !@end
• Implementace, MyStack.m:
#import "MyStack.h" !@implementation MyStack !- (void)push:(int)number { ... } !- (int)pop { ... } !@end
Metody
• Metoda má hlavičku (signaturu) a tělo: - (void)method:(int)parameter { int x = parameter + 10; printf("%d", x); }
• Uvnitř těla metody je kód, třeba jakýkoliv kód v C
Použití objektu• Vytvoření objektu: MyStack *mystack = [MyStack new];
• Volání metody: [mystack push:10];
• Vytvoření objektu pomocí statické metody “new” vrátí ukazatel (referenci) na nový objekt
• Na tomto objektu pak lze volat metody (instanční)
• Všechny objekty jsou dynamicky alokované
Základní třídy• Prakticky všechny vestavěné třídy mají prefix (2-3
písmena), NS = NextStep, neexistují jmenné prostory
• Framework = knihovna, která exportuje nějaké třídy
• NSObject, NSArray, NSString, NSData, NSDate, NSURL, NSValue, NSDictionary
• základní třídy jsou immutable, pak existují jejich mutable varianty:
• NSMutableArray, NSMutableString, NSMutableData
Zkrácené konstruktory• @"hello world" – vytvoří NSString
• @(10), @(3.14) – vytvoří NSNumber
• @[a, b, c] – vytvoří NSArray (a,b,c musí být platné objekty)
• @{ @“email”: a, @“password”: b } – vytvoří NSDictionary (a,b musí být objekty), indexy nemusí být jen NSStringy, ale musí to být objekty
Práce s polem NSMutableArray *array = [NSMutableArray new]; [array addObject:@"hello"]; [array addObject:@"world"]; for (int i = 0; i < array.count; i++) { NSLog(@"%@\n", array[i]); }
• array.count je zkratka za volání [array count]
• array[i] je také zkratka za volání metody
• NSLog(@“format-string”, …) je výpis do konzole
• specifikátor %@ umí vypsat obsah objektu
C a Obj-C• Lze volat C-čkové funkce (a používá se to!)
• NSLog
• Lze používat C-čkové primitivní typy a struktury
• int, float, CGPoint (= struktura se dvěma floaty x, y)
• Lze používat pointery (ale to se nepoužívá)
• Reference na objekty jsou sice technicky pointery, ale logicky něco zcela jiného
• Program začíná C-čkovou funkcí “main”
Víceparametrové metody
• Deklarace: - (void)insertNumber:(int)number atIndex:(int)index;
• Volání: [mystack insertNumber:10 atIndex:5];
• Proměnný počet parametrů: [NSString stringWithFormat:@"%d %d %d", 10, 20, 30]
Vlastnosti a instanční proměnné
• Vlastnosti lze definovat pouze v interface (ne v implementaci) třídy:
!@interface MyStack : NSObject !@property NSMutableArray *storage; @property int numberOfItems; !- (void)push:(int)number; - (int)pop; !@end
• Vlastnosti mohou mít modifikátory, dnes se použítá zřídka: @property (weak) id<UIApplicationDelegate> delegate;
Vlastnosti a instanční proměnné
• Definice vlastnosti ve skutečnosti vytvoří getter, setter a instanční proměnnou:
!@property NSMutableArray *storage;
• Vytvoří getter s názvem “storage”, setter s názvem “setStorage” a instanční proměnnou “_storage”
• lze pak volat:
• [obj storage] – zkráceně obj.storage
• [obj setStorage:…] – zkráceně obj.storage = …
Instanční proměnné
• Lze definovat v interfacu i v implementaci: @interface MyClass : NSObject { int a; NSString *b; } !... !@end
• Dnes se moc nepoužívá, preferuje se @property
Konstruktory a inicializátory• [NSString new]
• [[NSString alloc] init]
• [[NSString alloc] initWithString:@“abc”]
• [NSMutableString string]
• [NSString stringWithFormat:@“%d”, 10]
• [NSString stringWithCString:”c-string” encoding:NSUTF8StringEncoding]
• [[NSString alloc] initWithCString:”c-string” encoding:NSUTF8StringEncoding]
Další klíčová slova• id = libovolný typ objektu
• nil = ukazatel na “žádný” objekt (obdoba NULL)
• self = aktuální objekt, jako “this” z jiných jazyků, super = objekt nadtřídy
• BOOL = dvouhodnotový typ (není to objekt)
• hodnoty jsou YES a NO
• NSInteger, CGFloat, … – typedefy na hodnotové typy (také nejsou objekty)
• konstruktor [MyClass new] je zkratka za volání:
• [[MyClass alloc] init] – alloc alokuje paměť, init je inicializátor
@interface MyStack : NSObject !@property NSMutableArray *storage; !- (void)push:(int)number; - (int)pop; !@end !———————————————————————————————————————————————————————— !@implementation MyStack !- (void)push:(int)number { if (! self.storage) self.storage = [NSMutableArray new]; NSNumber *objectNumber = @(number); [self.storage addObject:objectNumber]; } !- (int)pop { NSNumber *objectNumber = [self.storage lastObject]; [self.storage removeLastObject]; return [objectNumber intValue]; } !@end
@interface MyStack : NSObject !@property NSMutableArray *storage; !- (void)push:(int)number; - (int)pop; !@end !———————————————————————————————————————————————————————— !@implementation MyStack !- (id)init { self = [super init]; if (self) { self.storage = [NSMutableArray new]; } return self; } !- (void)push:(int)number { ... } !- (int)pop { ... } !@end
@interface MyStack : NSObject !- (void)push:(int)number; - (int)pop; !@end !———————————————————————————————————————————————————————— !@interface MyStack () !@property NSMutableArray *storage; !@end !@implementation MyStack !- (id)init { self = [super init]; if (self) { self.storage = [NSMutableArray new]; } return self; } !... !@end
Dokumentace
• StackOverflow je váš přítel
• http://www.raywenderlich.com/tutorials
• https://developer.apple.com/library/
Foreach
• for…in přes kontejnery podporující “fast enumeration”
! NSArray *array = @[@1, @2, @3]; for (NSNumber *number in array) { NSLog(@"%@", number); }
• Může podporovat i vaše třída
Co Obj-C nemá
• Nemá jmenné prostory (namespaces)
• Nemá generika a typované kontejnery
• Nemá vícenásobnou dědičnost
• Nemá šablony
• Nemá overloading metod
Třídy a typování• Veškerá volání metod (včetně přístupů přes tečku)
jsou dynamická/virtuální a až za běhu je nalezena příslušná implementace (late-binding)
• Na objektu typu “id” lze volat libovolnou známou metodu
!! NSArray *array = @[@"a", @"b"]; id untypedObject = array; // ok [untypedObject count]; // ok NSDictionary *wronglyTypedObject = untypedObject; // ok [wronglyTypedObject count]; // ok [wronglyTypedObject objectForKey:@"key"]; // crash
Kategorie• Způsob, jak do nějaké třídy přidat další metody:
!@interface NSString (MyStringExtraFeatures) !- (NSString *)MD5hash; !@end
• Pak lze volat [@“hello” MD5hash]
• Bezejmenné kategorie (class extension) umí navíc přidávat vlastnosti, ale jen pro vlastní třídy:
!@interface MyStack () @property NSMutableArray *storage; @end !@implementation MyStack ... @end
Protokoly• protokol je něco jako interface, třídy mohou protokol(y)
implementovat, mohou mít “volitelné” metody: !@protocol MyProtocol <NSObject> !- (void)requiredMethod; !@optional - (void)optionalMethod; !@end
• Použití protokolu: !@interface MyStack : NSObject<MyProtocol> ... @end
Slovník• Selektor = název metody
• - (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
• selektor je insertObject:atIndex:
• Zaslání zprávy = volání metody = vyvolání selektoru na objektu
• zaslání zprávy objektu “nil” je v pořádku a neudělá nic
• Protokol = interface
• Třída vyhovuje protokolu (class conforms to protocol) = třída implementuje interface
• Neformální protokol = všechny metody jsou optional (typicky u delegátů)
Memory management• Objective-C nemá garbage collector
• V novodobém Objective-C funguje ARC, Automatic Reference Counting
• předtím se reference počítaly manuálně
• kompilátor počítá reference, přiřazení objektu do proměnné nebo přidání do pole zvýší o jedna, a naopak; není-li žádná reference, objekt se uvolní
• retain cycle … kruhové reference jsou problém a programátor je musí řešit: weak references
Bloky
• Blok = anonymní funkce + uzávěr (closure), tj. umí si sáhnout do vnějšího rozsahu (scope)
• Velice šikovné pro asynchronní programování, notifikace o událostech, animace, …
id object = ...; dispatch_async(queue, ^{ doSomethingWithObject(object); });
Popisné názvy metod• -[NSDictionary isEqualToDictionary:]
• -[NSString hasPrefix:]
• - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
• -[UIButton setTitle:forState:] [UIColor colorWithRed:0.5 green:1.0 blue:0.0 alpha:1.0]
Konvence• Prefix velkými písmeny (2-3): XYZ
• Názvy tříd a protokolů: MyCustomButton, XYZRedButton, NSCoding
• Názvy delegátů se slovem “Delegate”: UIApplicationDelegate
• názvy metod popisně: -[UIView insertSubview:atIndex:]
• názvy vlastností camelCasem: @property NSString *fileType;
• události s “did” nebo “will”:
• -[UIApplicationDelegate applicationDidFinishLaunching:]
• -[UIApplicationDelegate application:didReceiveRemoteNotification:]
Demo Objective-C, třídy, metody, práce s objekty
MVC• Návrhový vzor Model-View-Controller
• rozdělení kódu a odpovědnosti
• Model = vaše třídy, případně Core Data
• data, business logic, práce s databází, …
• View = UIView a jejich potomci, hierarchické uspořádání (každé UIView může mít subviews)
• vykreslování, přeposílání interakce od uživatele ke kontroleru
• Controller = UIViewController a jejich potomci, hierarchie (každý UIViewController může mít child view controllers)
MVC v iOS
• Aplikace se spustí s jedním objektem UIWindow, ten má vlastnost rootViewController
• Každý UIViewController má své “view”, tj. všechno co se má v dané obrazovce zobrazit
• Typicky jedna obrazovka = jeden kontroler = jedna poděděná třída od UIViewController
Kontejnerové kontrolery
• UINavigationController
• umí dělat přechody “push” a “pop”
• UITabBarController
• umí přepínat mezi několika kontrolery
Interface Builder• Vizuální editor UI, integrovaný do Xcode
• editor atributů pro každý element (view, controller, …)
• drag&drop komponent
• obvykle není problém s absolutním pozicováním
• na iPhone existují jen 2 velikosti displeje, šířka je vždycky 320
Storyboardy
• Více obrazovek v jednom editoru
• Obdoba wireframe diagramů, ale lze implementovat skutečné UI
• Pěkně zobrazuje přechody mezi obrazovkami a kontejnerové kontrolery
Demo Interface Builder, storyboards
UIKit a Objective-C• UIView = obdélník (rozměry a pozice) dané barvy (může
být průhledná), může v sobě obsahovat další UIView objekty
• všechny ostatní UI elementy jsou poděděné od UIView
• CGRect = struktura obsahující x,y,width,height
• veškeré jednotky se udávají v bodech (CGFloat)
• na ne-retina zařízeních 1 bod = 1 pixel
• na retina zařízeních 1 bod = 2 pixely
Základní frameworky• Foundation.framework
• základní podpora jazyka Objective-C
• UIKit.framework
• všechny vizuální elementy, UIButton, UILabel, UIView, UIImageView, …
• kontrollery, UIViewController, …
• gesture recognizers, UIColor, …
• CoreGraphics.framework (C-čkové API)
• využíván UIKitem (UIKit je vlastně jen high-level nadstavba nad CG)
• CGPoint, CGRect, CGFloat, práce s obrázky, přechody, fonty, …
iOS simulátor• Velice rychlý (spuštění aplikace trvá vteřinu),
plynulé animace a skrolování
• Není to emulátor, nepoužívá virtuální stroj
• jen několik omezení oproti skutečnému zařízení
• nemá App Store, nefungují push notifikace, …
• simulace GPS pozice, HW klávesnice, externího dipleje, …
Delegáty• Návrhový vzor pro notifikace o událostech ale i pro jiné
účely
• UIApplication má delegáta (váš vlastní objekt), který dostává oznámení o událostech (třeba když aplikace přejde do pozadí):
!@implementation AppDelegate !- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... } - (void)applicationWillResignActive:(UIApplication *)application { ... }
Singleton• Návrhový vzor, chceme mít pouze jedinou
instanci dané třídy přístupnou odkudkoliv
• Hodí se pro databázi, pro služby na pozadí (např. geolokace)
• V mnoha jazycích považováno za anti-pattern, v iOS se naopak vyskytuje velice často
NSFileManager *manager = [NSFileManager defaultManager]; [manager currentDirectoryPath];
Režimy aplikace
• Aplikace neukončuje uživatel ale systém
• Operace “na pozadí” jsou omezeny
• žádná interakce (UI)
• časové omezení
App Store• od roku 2008, 70% ceny jde vývojáři (plus-mínus),
obchody samostatné pro různé země
• žebříčky, stránka “Featured”, výběry redakce
• Enterprise App Store – firma může mít svůj vlastní App Store pro distribuci svým zaměstnancům
• Aplikace z App Storu jsou digitálně podepsané a šifrované pro konkrétní zařízení (resp. Apple ID)
iTunes Connect• primární nástroj pro nahrávání aplikací do App Storu,
sledování prodejů, podpis smluv s Applem, …
• Proces nahrání aplikace:
• Vytvoření metadat v iTC (popis, screenshoty, …)
• Upload z Xcode
• Čekání na review
• Pokud review dopadne dobře, aplikace je ke stažení
Apple Developer Portal• Pro majitele licence ($99 ročně):
• Přístup k betaverzím iOS a Xcode
• Generování certifikátů, registrování vývojových zařízení, generování profilů, …
• Pro všechny:
• Dokumentace, videa z WWDC a Tech Talks, diskuzní fóra
Další technologie pro iOS• Core Data – ORM
• Core Animation, Core Audio, Core Graphics, Core Image, iCloud, Push Notifications, WebKit, MapKit, GCD, …
• CocoaPods – 3rd party správce knihoven + repozitář
• Reveal – 3rd party runtime debugger pro UI
Bezpečnost iOS zařízení• sandboxing – aplikace nemají technicky možnost dělat
neplechu
• boj proti jailbreaku
• šifrování aplikací
• Keychain
• šifrování souborů – zamknutý iPhone nemá v paměti klíč
• iMessage používá end-to-end asymetrické šifrování