Vývoj aplikací pro iOS

2,624 views
2,537 views

Published on

Přednáška pokrývá úvod do mírně pokročilých oblastí vývoje pro iOS.

- vícevláknové programování
- práce s XML a JSON na iOS
- datová persistence
- MapKit a Core Location
- Systémové dialogy
- URL schémata

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,624
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Vývoj aplikací pro iOS

    1. 1. Vývoj aplikací pro iOS FI MUNI, 22. 4. 2011
    2. 2. Program Přednáška Coding Session 4 hodiny
    3. 3. Program
    4. 4. Program
    5. 5. Program ±4 hodiny
    6. 6. Obsah - 1. část• Vícevláknové aplikace • Asynchronní provádění operací • Bloky a GCD
    7. 7. Obsah - 2. část• Práce s daty na iOS • Zpracování XML a JSONu • Persistence dat
    8. 8. Obsah - 2. část• Polohové služby • Core Location • MapKit
    9. 9. Obsah - 3. část• Systémové dialogy a komunikace mezi aplikacemi • Získání fotografie a kontaktů • URL Schémata
    10. 10. Když zbyde čas...• Freestyle na témata • Práce s UIWebView • Lokalizace aplikací
    11. 11. Vícevláknové aplikace
    12. 12. Proč vlákna?• Pomalé operace nesmí blokovat hlavní vlákno• Operace UIKitu musí běžet na hlavním vlákně
    13. 13. Pattern• Dlouhotrvající operace - separátní vlákno• Update UI - hlavní vlákno
    14. 14. NSThread
    15. 15. NSThread• Nízkoúrovňová abstrakce nad vlákny
    16. 16. NSThread - (void) detachAsyncOperation { [NSThread detachNewThreadSelector:@selector(operation:) toTarget:self withObject:contextData]; } - (void) operation:(id)contextData { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // slow code here [self performSelectorOnMainThread:@selector(updateUI:) withObject:contextData waitUntilDone:NO]; [pool release]; }
    17. 17. NSThread NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(operation:) object:context]; [thread setThreadPriority:1.0]; // [0.0, 1.0], 1.0 = highest [thread start]; ... [thread cancel]; ... [thread release];
    18. 18. Bloky
    19. 19. Bloky^
    20. 20. Bloky^• “blok” = “kousek kódu”• široká škála použití v různých částech SDK• ~ Lambda, ~ anonymní
    21. 21. Bloky ^ BOOL (int a, int b) { /* code */ }
    22. 22. Bloky ^ BOOL (int a, int b) { /* code */ } ^ void (void) { /* code */ } ^ { /* code */ }
    23. 23. Bloky typedef (void) (^myBlock_t)(int i)
    24. 24. Bloky typedef (void) (^myBlock_t)(int i) void repeat (int times, myBlock_t block) { for (int i = 0; i < times; i++) block(i); }
    25. 25. Bloky int const = 10; myBlock_t iBlock = ^(int i) { NSLog(@”%d”, i * const); } repeat(5, iBlock);
    26. 26. UIKit Animace imageView.alpha = 0.0; [UIView animateWithDuration:1.0 animations:^{ imageView.alpha = 1.0; } completion:^(BOOL finished) { // some completion code, possibly cleanup }];
    27. 27. Bloky NSSet *iSet = [NSSet set]; // ... add objects to the set [set objectsPassingTest:^(id obj, BOOL *stop) { return [self testValue:id]; // custom comparison }];
    28. 28. GCD
    29. 29. GCD• Práce s NSThread je ubíjející• GCD (“Grand Central Dispatch”) práci zjednodušuje• jazyk C, funkce začínají na “dispatch_”
    30. 30. GCD• Dispatch Queue • fronta bloků (FIFO) • jsou reference-counted • dispatch_queue_create ➞ dispatch_release
    31. 31. GCDdispatch_async(queue, ^ { // some slow code});
    32. 32. GCDdispatch_async(network_queue, ^ { // some slow code dispatch_async(main_queue, ^{ // update UI });});
    33. 33. GCD• Dispatch Queue • dispatch_get_main_queue() • dispatch_get_global_queue(priority, 0); • dispatch_queue_create("eu.inmite.net", NULL);
    34. 34. GCD• Dispatch Semaphore • dispatch_semaphore_create • dispatch_semaphore_wait • dispatch_semaphore_signal
    35. 35. GCD• 4 Dispatch Semaphore • dispatch_semaphore_create 3 • dispatch_semaphore_wait 2 • dispatch_semaphore_signal 1
    36. 36. GCD• Dispatch Semaphore • dispatch_semaphore_create • dispatch_semaphore_wait 2 • dispatch_semaphore_signal 1
    37. 37. GCD• Dispatch Semaphore • dispatch_semaphore_create • dispatch_semaphore_wait • dispatch_semaphore_signal !
    38. 38. GCD• 4 Dispatch Semaphore • dispatch_semaphore_create 3 • dispatch_semaphore_wait 2 • dispatch_semaphore_signal 1
    39. 39. GCD• Dispatch Source • reakce na systémové události • soubory, sockety, timer, ...
    40. 40. Singleton
    41. 41. Singleton Pattern // within class Foo + (Foo*) getDefault { static Foo *inst = nil; if (!inst) { inst = [[Foo alloc] init]; // create the instance } return inst; }
    42. 42. Singleton Pattern // within class Foo + (Foo*) getDefault { static Foo *inst = nil; @synchronized (self) { if (!inst) { inst = [[Foo alloc] init]; // create the instance } } return inst; }
    43. 43. Singleton Pattern // within class Foo + (Foo*) getDefault { static Foo *inst = nil; if (!inst) { @synchronized (self) { if (!inst) { inst = [[Foo alloc] init]; // create the instance } } } return inst; }
    44. 44. Singleton Pattern // within class Foo + (Foo*) getDefault { static Foo *inst = nil; if (!inst) { @synchronized (self) { if (!inst) { inst = [[Foo alloc] init]; // create the instance ??? } } } return inst; }
    45. 45. Singleton Pattern // within class Foo + (Foo*) getDefault { static Foo volatile *inst = nil; if (!inst) { @synchronized (self) { if (!inst) { Foo *tmp = [[Foo alloc] init]; // create the instance OSMemoryBarrier(); inst = foo; } } } OSMemoryBarrier(); return inst; }
    46. 46. Singleton Pattern // within class Foo + (Foo*) getDefault { static Foo *inst = nil; if (!inst) { inst = [[Foo alloc] init]; // create the instance } return inst; }
    47. 47. Singleton Pattern // within class Foo + (Foo*) getDefault { static Foo volatile *inst = nil; if (!inst) { @synchronized (self) { if (!inst) { Foo *tmp = [[Foo alloc] init]; // create the instance OSMemoryBarrier(); inst = foo; } } } OSMemoryBarrier(); return inst; }
    48. 48. Singleton Pattern
    49. 49. Singleton Pattern
    50. 50. Singleton Pattern // within class Foo + (Foo*) getDefault { static dispatch_once_t pred; static Foo *inst; dispatch_once(&pred, ^ { inst = [[Foo alloc] init] }); return inst; }
    51. 51. Operation Queues
    52. 52. NSOperation• Abstrakce nad “operac픕 Určeno pro subclassování• KVO compliant
    53. 53. NSOperation• Informace o stavu operace • isCancelled, isFinished, isExecuting, ...• Možnost nastavení priority• Závislosti operací • [op1 addDependency:op2];
    54. 54. NSOperation• main - kód, který se má vykonat• start - spustí operaci• cancel - nastaví příznak zrušení
    55. 55. NSOperation• K dispozici podtřídy • NSInvocationOperation • NSBlockOperation
    56. 56. NSInvocationOperation• Operace vycházející ze selektoru
    57. 57. NSInvocationOperation• Operace vycházející ze selektoru [[NSInvocationOperation alloc] initWithTarget:target selector:selector object:context];
    58. 58. NSBlockOperation• Operace přijímající blok
    59. 59. NSBlockOperation• Operace přijímající blok [NSBlockOperation blockOperationWithBlock:^{ // some code... }];
    60. 60. Spuštění operace - (BOOL)performOperation:(NSOperation*)anOp { BOOL ranIt = NO; if ([anOp isReady] && ![anOp isCancelled]) { if (![anOp isConcurrent]) [anOp start]; else [NSThread detachNewThreadSelector:@selector(start) toTarget:anOp withObject:nil]; ranIt = YES; } else if ([anOp isCancelled]) { [self willChangeValueForKey:@"isFinished"]; [self willChangeValueForKey:@"isExecuting"]; executing = NO; finished = YES; [self didChangeValueForKey:@"isExecuting"]; [self didChangeValueForKey:@"isFinished"]; ranIt = YES; } return ranIt; }
    61. 61. NSOperationQueue• Snadné spouštění instancí NSOperation• Jedna NSOperationQueue instance ~ funkčnost• Možnost nastavit počet paralelních operací
    62. 62. Spuštění operace [queue addOperation:anOperation];
    63. 63. NSOperationQueue [NSOperationQueue mainQueue]; [NSOperationQueue currentQueue];
    64. 64. Úloha: Lorem Pixum• Klient služby “Lorem Pixum”• API: http://lorempixum.com/320/460/• Implementace ke stažení: http://bit.ly/fimuni_01
    65. 65. Práce s daty na iOS
    66. 66. ZpracováníXML a JSON
    67. 67. XML• SAX - NSXMLParser • součást Apple iOS SDK• DOM - TouchXML, KissXML, ... • XML ➞ Strom
    68. 68. Touch XML• Modified BSD Licence• DOM parser + XPath, XML Namespaces• https://github.com/TouchCode/TouchXML
    69. 69. Touch XML• Ukázka kódu
    70. 70. JSON•JavaScript Object Notation• JSON Framework { "id": 1, "name": "Foo", "price": 123, "tags": ["Bar","Eek"] }
    71. 71. JSON Framework• New BSD Licence• JSON parser a generator• http://stig.github.com/json-framework/
    72. 72. JSON Framework• Ukázka kódu
    73. 73. Persistence dat
    74. 74. iOS Filesystem• Aplikace jsou omezené na svůj sandbox • Nemohou číst ani psát mimo něj• Každá aplikace má svůj “Home directory”
    75. 75. iOS Filesystem• Documents • složka pro uživatelské dokumenty • zálohuje se do iTunes
    76. 76. iOS Filesystem• Caches • složka pro soubory cache • nezálohuje se do iTunes
    77. 77. iOS Filesystem• Temp • složka pro dočasné soubory • nezálohuje se do iTunes
    78. 78. iOS Filesystem
    79. 79. iOS Filesystem // temporary directory NSString *tmpDir = NSTemporaryDirectory();
    80. 80. iOS Filesystem // temporary directory NSString *tmpDir = NSTemporaryDirectory(); // documents or caches directory // NSDocuentsDirectory, NSCachesDirectory NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES); NSString *cacheDir = [paths objectAtIndex:0];
    81. 81. iOS Filesystem // temporary directory NSString *tmpDir = NSTemporaryDirectory(); // documents or caches directory // NSDocuentsDirectory, NSCachesDirectory NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES); NSString *cacheDir = [paths objectAtIndex:0]; NSString *path = [cacheDir stringByAppendingPathComponent:fileName];
    82. 82. Property list• formát pro objektovou persistenci• dvě varianty: XML a binární varianta (Apple)
    83. 83. Property list <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>title</key> <string>Blue socks</string> <key>are_new</key> <true/> <key>colors</key> <array> <string>blue</string> </array> </dict> </plist>
    84. 84. Property list• NSArray, NSDictionary • lze zapisovat a číst z plistu
    85. 85. NSCoding•Protokol pro serializaci objektu • encodeWithCoder • decodeWithCoder
    86. 86. NSCoding - (void)encodeWithCoder:(NSCoder *)encoder { // [super initWithCoder:coder]; for subclasses [encoder encodeObject:[self title] forKey:@"title"]; [encoder encodeObject:[self description] forKey:@"description"]; [encoder encodeObject:[self fullContent] forKey:@"fullcontent"]; [encoder encodeObject:[self href] forKey:@"href"]; [encoder encodeObject:[self locationStr] forKey:@"locationstr"]; [encoder encodeObject:[self imageURL] forKey:@"imageurl"]; [encoder encodeBool:[self read] forKey:@"read"]; }
    87. 87. NSCoding - (id)initWithCoder:(NSCoder *)decoder { // [super initWithDecoder:decoder]; for subclasses if (self = [super init]) { [self setTitle:[decoder decodeObjectForKey:@"title"]]; [self setDescription:[decoder decodeObjectForKey:@"description"]]; [self setFullContent:[decoder decodeObjectForKey:@"fullcontent"]]; [self setHref:[decoder decodeObjectForKey:@"href"]]; [self setLocationStr:[decoder decodeObjectForKey:@"locationstr"]]; [self setImageURL:[decoder decodeObjectForKey:@"imageurl"]]; [self setRead:[decoder decodeBoolForKey:@"read"]]; } return self; }
    88. 88. NSKeyedArchiver BOOL success = [NSKeyedArchiver archiveRootObject:self toFile:path];
    89. 89. NSKeyedUnarchiver MyModel *model = (MyModel*)[NSKeyedUnarchiver unarchiveObjectWithFile:path];
    90. 90. NSUserDefaults• Místo pro ukládání uživatelského nastavení aplikace• Pod pokličkou je PList
    91. 91. NSUserDefaults NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
    92. 92. NSUserDefaults NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setValue:@”Blue socks” forKey:@”title”]; [userDefaults setBool:YES forKey:@”are_new”]; [userDefaults synchronize];
    93. 93. NSUserDefaults NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setValue:@”Blue socks” forKey:@”title”]; [userDefaults setBool:YES forKey:@”are_new”]; [userDefaults synchronize]; NSString *title = [userDefaults valueForKey:@”title”]; BOOL are_new = [userDefaults boolForKey:@”are_new”];
    94. 94. NSUserDefaults• Možnost registrace do aplikace “Settings” • Soubor “Settings.bundle” • PSTextFieldSpecifier, PSToggleSwitchSpecifier, PSSliderSpecifier, ... • pouze “deklarativní nastavení”
    95. 95. SQLite3• Light-weight SQL implementace• Vhodná pro mobilní zařízení• Součástí Apple iOS SDK• Implementace v C, existují wrappery
    96. 96. FMDB• MIT Licence• Light-weight Objective-C wrapper nad SQLite• https://github.com/ccgus/fmdb
    97. 97. FMDB• Ukázka kódu
    98. 98. CoreData• Řešení Apple pro management modelu (object graph) a persistenci dat • podobné ORM (ale není to ORM)• Pod pokličkou SQLite• Vizuální tvorba modelu
    99. 99. CoreData
    100. 100. Polohové služby
    101. 101. MapKit Framework
    102. 102. MKMapView• Implementace online Google Map• Podpora pro různé typy map• Poměrně omezená, ale stačí
    103. 103. MKAnnotation• Protokol• Model pro “napínáčky” na mapě• anotace se přidá do mapy, vrací svou pozici a titulek
    104. 104. MKAnnotationView• View anotace na mapě (“napínáček”)• Používá concept reusable identifikátoru• MKPinAnnotationView
    105. 105. MapKit Framework• Ukázka kódu
    106. 106. CLLocationManager• Zjištění aktuální polohy zařízení• Umožňuje nastavit požadovanou přesnost• Dodává pravidelně update pozice
    107. 107. CLLocationManager• Ukázka kódu
    108. 108. Úloha: PlaceNotes• Poznámky k aktuální pozici• Poznámka má nadpis a obsah• Je spojená s GPS souřadnicí• Persistentní data
    109. 109. Systémové dialogy
    110. 110. Systémové dialogy• Aplikace v SandBoxu• Definované API pro funkce telefonu
    111. 111. Image Picker• Fotoaparát, galerie telefonu• UIImagePickerViewController
    112. 112. Person Picker• Volba kontaktů• ABPeoplePickerNavigationController
    113. 113. URL Schémata
    114. 114. URL Schémata• Způsob, jak spouštět jiné aplikace• Umožňuje předávat “malá data”
    115. 115. URL Schémata
    116. 116. URL Schémata if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url]; }
    117. 117. URL Schémata• http://www.abc.com/ - Safari • nebo Google Maps,YouTube či iTunes• mailto:mail@example.com - Mail• tel:777123456 - Phone• sms:777123456 - SMS
    118. 118. URL Schémata• Aplikace může registrovat své URL schéma• Jiná aplikace ji může spustit• Rejstřík: http://handleopenurl.com/
    119. 119. Facebook• Autentizace používá custom URL schéma• Facebook SDK for iPhone • https://github.com/facebook/facebook-ios-sdk
    120. 120. Úloha: Facebook• Nahrávání obrázků na Facebook• Možnost zvolit obrázek z fotoaparátu i telefonu• ID aplikace: 220303784651438
    121. 121. Děkuji @inmite

    ×