More Related Content Similar to Vývoj aplikací pro iOS (20) More from Petr Dvorak (20) Vývoj aplikací pro iOS2. Obsah - 1. část
• Vícevláknové aplikace
• Asynchronní provádění operací
• Bloky a GCD
3. Obsah - 2. část
• Práce s daty na iOS
• Zpracování XML a JSONu
• Persistence dat
4. Obsah - 2. část
• Polohové slu#by
• Core Location
• MapKit
5. Obsah - 3. část
• Systémové dialogy a komunikace mezi aplikacemi
• Získání fotografie a kontaktů
• URL Schémata
8. Proč vlákna?
• Pomalé operace nesmí blokovat hlavní vlákno
• Operace UIKitu musí bě#et na hlavním vlákně
12. 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];
}
13. 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];
15. Bloky
^
• “blok” = “kousek kódu”
• "iroká "kála pou#ití v různ!ch částech SDK
• ~ Lambda, ~ anonymní
16. Bloky
^ BOOL (int a, int b) { /* code */ }
^ void (void) { /* code */ }
^ { /* code */ }
17. Bloky
typedef (void) (^myBlock_t)(int i)
void repeat (int times, myBlock_t block) {
for (int i = 0; i < times; i++) block(i);
}
18. Bloky
int const = 10;
myBlock_t iBlock = ^(int i) {
NSLog(@”%d”, i * const);
}
repeat(5, iBlock);
19. UIKit Animace
imageView.alpha = 0.0;
[UIView animateWithDuration:1.0 animations:^{
imageView.alpha = 1.0;
} completion:^(BOOL finished) {
// some completion code, possibly cleanup
}];
20. Bloky
NSSet *iSet = [NSSet set];
// ... add objects to the set
[set objectsPassingTest:^(id obj, BOOL *stop) {
return [self testValue:id]; // custom comparison
}];
22. GCD
• Práce s NSThread je ubíjející
• GCD (“Grand Central Dispatch”) práci
zjednodu"uje
• jazyk C, funkce začínají na “dispatch_”
23. GCD
• Dispatch Queue
• fronta bloků (FIFO)
• jsou reference-counted
• dispatch_queue_create ! dispatch_release
26. GCD
• Dispatch Queue
• dispatch_get_main_queue()
• dispatch_get_global_queue(priority, 0);
• dispatch_queue_create("eu.inmite.net", NULL);
28. GCD
•
4
Dispatch Semaphore
• dispatch_semaphore_create 3
• dispatch_semaphore_wait
2
• dispatch_semaphore_signal
1
31. GCD
•
4
Dispatch Semaphore
• dispatch_semaphore_create 3
• dispatch_semaphore_wait
2
• dispatch_semaphore_signal
1
34. Singleton Pattern
// within class Foo
+ (Foo*) getDefault {
static Foo *inst = nil;
if (!inst) {
inst = [[Foo alloc] init]; // create the instance
}
return inst;
}
35. Singleton Pattern
// within class Foo
+ (Foo*) getDefault {
static Foo *inst = nil;
@synchronized (self) {
if (!inst) {
inst = [[Foo alloc] init]; // create the instance
}
}
return inst;
}
36. 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;
}
37. 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;
}
38. Singleton Pattern
// within class Foo
+ (Foo*) getDefault {
static dispatch_once_t pred;
static Foo *inst;
dispatch_once(&pred, ^ { inst = [[Foo alloc] init] });
return inst;
}
41. NSOperation
• Informace o stavu operace
• isCancelled, isFinished, isExecuting, ...
• Mo#nost nastavení priority
• Závislosti operací
• [op1 addDependency:op2];
42. NSOperation
• main - kód, kter! se má vykonat
• start - spustí operaci
• cancel - nastaví příznak zru"ení
44. NSInvocationOperation
• Operace vycházející ze selektoru
[[NSInvocationOperation alloc]
initWithTarget:target
selector:selector
object:context];
46. 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;
}
52. XML
• SAX - NSXMLParser
• součást Apple iOS SDK
• DOM - TouchXML, KissXML, ...
• XML ! Strom
53. Touch XML
• Modified BSD Licence
• DOM parser + XPath, XML Namespaces
• https://github.com/TouchCode/TouchXML
55. JSON Framework
• New BSD Licence
• JSON parser a generator
• http://stig.github.com/json-framework/
57. 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”
61. 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];
63. 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>
66. 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"];
}
67. 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;
}
70. NSUserDefaults
• Místo pro ukládání u#ivatelského nastavení
aplikace
• Pod pokličkou je PList
71. 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”];
72. NSUserDefaults
• Mo#nost registrace do aplikace “Settings”
• Soubor “Settings.bundle”
• PSTextFieldSpecifier, PSToggleSwitchSpecifier,
PSSliderSpecifier, ...
• pouze “deklarativní nastavení”
73. SQLite3
• Light-weight SQL implementace
• Vhodná pro mobilní zařízení
• Součástí Apple iOS SDK
• Implementace v C, existují wrappery
74. FMDB
• MIT Licence
• Light-weight Objective-C wrapper nad SQLite
• https://github.com/ccgus/fmdb
75. 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
89. URL Schémata
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
91. URL Schémata
• Aplikace mů#e registrovat své URL schéma
• Jiná aplikace ji mů#e spustit
• Rejstřík: http://handleopenurl.com/