iOS Development
                 Lecture 2 - The practical stuff



Petr Dvořák
Partner & iOS Development Lead
@joshis_tweets
Outline
Outline
• Using location services and maps
  • Adding maps to an app
  • Determining user’s location
  • Geocoding/Reverse geocoding
Outline
• Using system dialogs
  • Picking a contact
  • Taking a photo
  • Composing an e-mail or SMS
Outline
• Getting a bit social
  • Twitter API
  • Facebook iOS SDK
Outline
• Threading
  • NSThread
  • GCD (Grand Central Dispatch)
  • NSOperation
Outline
• If there is still time...
  • Using UIWebView
  • iOS app localization
Maps & Location
MapKit

• Implementation of
 Google Maps

• High-level API
• Annotations, Routes,
 Overlays
MKMapView
• UIView subclass
• Based on adding “annotations”
  • = model classes
• Support for user’s location
• Customizable maps & annotations
• Delegate-based API
MKAnnotation
• Protocol that enables model class for
  showing up on maps
 • coordinate, title, subtitle
• MKPlacemark
  • conforms to MKAnnotation
  • country, state, city, address
MKAnnotationView
• View related to a particular
  MKAnnotation instance
• Reused in the map view
• MKPinAnnotationView
  • The classic “iOS map pin”
  • Three colors
Core Location
• Access to GPS module
• Configurable precision (vs. time)
• Significant Location Changes
• May run on background
CLLocationManager
• Provides callbacks for location and
  heading
• Delegate based
• Check for availability and state of the
  location services before using
CLGeocoder
• Allows geocoding and reverse
  geocoding
• Does not use Google API
 •   ... doesn’t work perfectly outside the USA

• Block based
CLGeocoder* g = [[CLGeocoder alloc] init];

[g reverseGeocodeLocation:location
        completionHandler:^(NSArray *placemark, NSError *error) {
    // ...
}];

[g geocodeAddressString:@”Brno”
      completionHandler: ^(NSArray *placemark, NSError *error) {
    // ...
}];

// [g cancelGeocode];
System dialogs
System dialogs
• Allow performing usual tasks in
  a consistent manner
• Complete process handling
• Delegate based
Address Book
• Creating and searching contacts
• Allows manual access via C API
 •   ABAddressBookCreate

 •   ABAddressBookCopyArrayOfAllPeople

 •   ABAddressBookSave

• Contains predefined dialogs
ABPeoplePickerNavigationController

 • System dialog for picking a contact
 • Allows picking a contact or a contact
   property
ABPeoplePickerNavigationController *pp =
    [[ABPeoplePickerNavigationController alloc] init];
pp.peoplePickerDelegate = self;
[self presentModalViewController:pp
                        animated:YES];

//...

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)p
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    //...
}
ABNewPersonViewController
• System dialog for creating a contact
• May be pre-initialized
ABPersonViewController
• System dialog for displaying a contact
• Optional editing
UIImagePickerController
• System dialog for picking a photo
• Uses “sourceType” flag to determine
  source
 • camera, library, saved photos
• Check for camera before touching it
• Delegate based
MFMailComposeViewController

• System dialog for composing an
  e-mail message
• May be pre-filled with e-mail data
• Support for attachments
• + (BOOL) canSendMail;
MFMessageComposeViewController

 • System dialog for composing an
   SMS message
 • No MMS / attachments
 • May be pre-filled with message body
   and recipients (string array)
 • + (BOOL) canSendText;
Social Networks
Twitter API
• Native Twitter support
  since iOS 5
• Uses Twitter app for
  authentication
• Twitter uses OAuth 1.0a
  under the hood =>
  secure, hard to
  implement
TWTweetComposeViewController

 • System dialog for composing an
   Tweet
 • Text, Images, URLs
  •   add methods return NO if length exceeds 140 chars

 • Block based
  •   TWTweetComposeViewControllerCompletionHandler

 • + (BOOL) canSendTweet;
Facebook iOS SDK

• Facebook publishes official iOS SDK
 •   https://github.com/facebook/facebook-ios-sdk

• Requires Facebook application (web)
• Uses official Facebook app for
  authentication
 •   Alternatively: web authentication, embedded FB authentication dialog


• Uses URL scheme handling
Threading
Why threads?

• Slow operations must not block UI
  • Network operations
  • Computations
  • Filesystem operations
NSThread

• Low level thread abstraction
• Requires you to do all the
  synchronisation manually
- (void) detachAsyncOperation {
    [NSThread detachNewThreadSelector:@selector(operation:)
                     toTarget:self
                     withObject:contextData];
}


- (void) operation:(id)contextData {
    @autorelease {
        // slow code here
        // ...
        [self performSelectorOnMainThread:@selector(updateUI:)
                               withObject:contextData
                            waitUntilDone:NO];
    }
}
GCD

• Working with NSThread is difficult
• GCD makes an abstraction above
  threads
• C API, functions/macros starting with
  “dispatch_” prefix
Dispatch Queue

• Queue of blocks to be performed
 •   FIFO, synchronized

• Reference-counted
 •   dispatch_queue_create ➞ dispatch_release

• One queue per use-case
dispatch_queue_t main_queue = dispatch_get_main_queue()
dispatch_queue_t network_queue = dispatch_get_global_queue(priority, 0);
// dispatch_queue_t network_queue2 =
//             dispatch_queue_create("eu.inmite.net", NULL);

dispatch_async(network_queue, ^ {
    // some slow code
    dispatch_async(main_queue, ^{
        // update UI
    });
    // dispatch_release(network_queue2);
});
Dispatch Semaphore

•   dispatch_semaphore_create
•   dispatch_semaphore_wait
•   dispatch_semaphore_signal
NSOperation
• Abstraction above “operation”
• Meant to be subclassed
 •   main - code to be executed

 •   start - start the operation

 •   cancel - set the cancel flag


• Operation priority
• Dependencies
 •   [op1 addDependency:op2];
NSInvocationOperation
• NSOperation subclass
• Operation based on target & selector

 [[NSInvocationOperation alloc] initWithTarget:target
                                      selector:selector
                                        object:context];
NSBlockOperation
• NSOperation subclass
• Operation based on block

 [NSBlockOperation blockOperationWithBlock:^{
       // some code...
 }];
NSOperationQueue
• NSOperations are not meant to be
  run directly
• NSOperationQueue runs the
  operations correctly
• Configurable number of concurrent
  operations
NSOperationQueue


 NSOperationQueue *queue = [NSOperationQueue mainQueue];
 // queue = [NSOperationQueue currentQueue];
 // queue = [[NSOperationQueue alloc] init];

 [queue addOperation:anOperation];
Singleton pattern

• Assures access to a shared instance
• Usually allows multiple instance
  creation
• Simple pattern, many problems
• Threading
// within class Foo
+ (Foo*) getDefault {
    static Foo *inst = nil;
    if (!inst) {
        inst = [[Foo alloc] init];
    }
    return inst;
}
// within class Foo
+ (Foo*) getDefault {
    static Foo *inst = nil;
    @synchronized (self) {
        if (!inst) {
            inst = [[Foo alloc] init];
        }
    }
    return inst;
}
// within class Foo
+ (Foo*) getDefault {
    static Foo *inst = nil;
    if (!inst) { // double-check locking
        @synchronized (self) {
            if (!inst) {
                 inst = [[Foo alloc] init];
            }
        }
    }
    return inst;
}
// within class Foo
+ (Foo*) getDefault {
    static volatile Foo *inst = nil;
    if (!inst) { // double-check locking
        @synchronized (self) {
            if (!inst) {
                 Foo *tmp = [[Foo alloc] init];
                 OSMemoryBarrier();
                 inst = tmp;
            }
        }
    }
    OSMemoryBarrier();
    return inst;
}
// within class Foo
+ (Foo*) getDefault {
    static volatile Foo *inst;
    static dispatch_once_t pred;
    dispatch_once(&pred, ^ {
        inst = [[Foo alloc] init];
    });
    return inst;
}
Thank you
                   http://www.inmite.eu/talks



Petr Dvořák
Partner & iOS Development Lead
@joshis_tweets

iOS 2 - The practical Stuff

  • 1.
    iOS Development Lecture 2 - The practical stuff Petr Dvořák Partner & iOS Development Lead @joshis_tweets
  • 2.
  • 3.
    Outline • Using locationservices and maps • Adding maps to an app • Determining user’s location • Geocoding/Reverse geocoding
  • 4.
    Outline • Using systemdialogs • Picking a contact • Taking a photo • Composing an e-mail or SMS
  • 5.
    Outline • Getting abit social • Twitter API • Facebook iOS SDK
  • 6.
    Outline • Threading • NSThread • GCD (Grand Central Dispatch) • NSOperation
  • 7.
    Outline • If thereis still time... • Using UIWebView • iOS app localization
  • 8.
  • 9.
    MapKit • Implementation of Google Maps • High-level API • Annotations, Routes, Overlays
  • 10.
    MKMapView • UIView subclass •Based on adding “annotations” • = model classes • Support for user’s location • Customizable maps & annotations • Delegate-based API
  • 11.
    MKAnnotation • Protocol thatenables model class for showing up on maps • coordinate, title, subtitle • MKPlacemark • conforms to MKAnnotation • country, state, city, address
  • 12.
    MKAnnotationView • View relatedto a particular MKAnnotation instance • Reused in the map view • MKPinAnnotationView • The classic “iOS map pin” • Three colors
  • 13.
    Core Location • Accessto GPS module • Configurable precision (vs. time) • Significant Location Changes • May run on background
  • 14.
    CLLocationManager • Provides callbacksfor location and heading • Delegate based • Check for availability and state of the location services before using
  • 15.
    CLGeocoder • Allows geocodingand reverse geocoding • Does not use Google API • ... doesn’t work perfectly outside the USA • Block based
  • 16.
    CLGeocoder* g =[[CLGeocoder alloc] init]; [g reverseGeocodeLocation:location completionHandler:^(NSArray *placemark, NSError *error) { // ... }]; [g geocodeAddressString:@”Brno” completionHandler: ^(NSArray *placemark, NSError *error) { // ... }]; // [g cancelGeocode];
  • 17.
  • 18.
    System dialogs • Allowperforming usual tasks in a consistent manner • Complete process handling • Delegate based
  • 19.
    Address Book • Creatingand searching contacts • Allows manual access via C API • ABAddressBookCreate • ABAddressBookCopyArrayOfAllPeople • ABAddressBookSave • Contains predefined dialogs
  • 20.
    ABPeoplePickerNavigationController • Systemdialog for picking a contact • Allows picking a contact or a contact property
  • 21.
    ABPeoplePickerNavigationController *pp = [[ABPeoplePickerNavigationController alloc] init]; pp.peoplePickerDelegate = self; [self presentModalViewController:pp animated:YES]; //... - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)p shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier { //... }
  • 22.
    ABNewPersonViewController • System dialogfor creating a contact • May be pre-initialized ABPersonViewController • System dialog for displaying a contact • Optional editing
  • 23.
    UIImagePickerController • System dialogfor picking a photo • Uses “sourceType” flag to determine source • camera, library, saved photos • Check for camera before touching it • Delegate based
  • 24.
    MFMailComposeViewController • System dialogfor composing an e-mail message • May be pre-filled with e-mail data • Support for attachments • + (BOOL) canSendMail;
  • 25.
    MFMessageComposeViewController • Systemdialog for composing an SMS message • No MMS / attachments • May be pre-filled with message body and recipients (string array) • + (BOOL) canSendText;
  • 26.
  • 27.
    Twitter API • NativeTwitter support since iOS 5 • Uses Twitter app for authentication • Twitter uses OAuth 1.0a under the hood => secure, hard to implement
  • 28.
    TWTweetComposeViewController • Systemdialog for composing an Tweet • Text, Images, URLs • add methods return NO if length exceeds 140 chars • Block based • TWTweetComposeViewControllerCompletionHandler • + (BOOL) canSendTweet;
  • 29.
    Facebook iOS SDK •Facebook publishes official iOS SDK • https://github.com/facebook/facebook-ios-sdk • Requires Facebook application (web) • Uses official Facebook app for authentication • Alternatively: web authentication, embedded FB authentication dialog • Uses URL scheme handling
  • 30.
  • 31.
    Why threads? • Slowoperations must not block UI • Network operations • Computations • Filesystem operations
  • 32.
    NSThread • Low levelthread abstraction • Requires you to do all the synchronisation manually
  • 33.
    - (void) detachAsyncOperation{ [NSThread detachNewThreadSelector:@selector(operation:) toTarget:self withObject:contextData]; } - (void) operation:(id)contextData { @autorelease { // slow code here // ... [self performSelectorOnMainThread:@selector(updateUI:) withObject:contextData waitUntilDone:NO]; } }
  • 34.
    GCD • Working withNSThread is difficult • GCD makes an abstraction above threads • C API, functions/macros starting with “dispatch_” prefix
  • 35.
    Dispatch Queue • Queueof blocks to be performed • FIFO, synchronized • Reference-counted • dispatch_queue_create ➞ dispatch_release • One queue per use-case
  • 36.
    dispatch_queue_t main_queue =dispatch_get_main_queue() dispatch_queue_t network_queue = dispatch_get_global_queue(priority, 0); // dispatch_queue_t network_queue2 = // dispatch_queue_create("eu.inmite.net", NULL); dispatch_async(network_queue, ^ { // some slow code dispatch_async(main_queue, ^{ // update UI }); // dispatch_release(network_queue2); });
  • 37.
    Dispatch Semaphore • dispatch_semaphore_create • dispatch_semaphore_wait • dispatch_semaphore_signal
  • 38.
    NSOperation • Abstraction above“operation” • Meant to be subclassed • main - code to be executed • start - start the operation • cancel - set the cancel flag • Operation priority • Dependencies • [op1 addDependency:op2];
  • 39.
    NSInvocationOperation • NSOperation subclass •Operation based on target & selector [[NSInvocationOperation alloc] initWithTarget:target selector:selector object:context];
  • 40.
    NSBlockOperation • NSOperation subclass •Operation based on block [NSBlockOperation blockOperationWithBlock:^{ // some code... }];
  • 41.
    NSOperationQueue • NSOperations arenot meant to be run directly • NSOperationQueue runs the operations correctly • Configurable number of concurrent operations
  • 42.
    NSOperationQueue NSOperationQueue *queue= [NSOperationQueue mainQueue]; // queue = [NSOperationQueue currentQueue]; // queue = [[NSOperationQueue alloc] init]; [queue addOperation:anOperation];
  • 43.
    Singleton pattern • Assuresaccess to a shared instance • Usually allows multiple instance creation • Simple pattern, many problems • Threading
  • 44.
    // within classFoo + (Foo*) getDefault { static Foo *inst = nil; if (!inst) { inst = [[Foo alloc] init]; } return inst; }
  • 45.
    // within classFoo + (Foo*) getDefault { static Foo *inst = nil; @synchronized (self) { if (!inst) { inst = [[Foo alloc] init]; } } return inst; }
  • 46.
    // within classFoo + (Foo*) getDefault { static Foo *inst = nil; if (!inst) { // double-check locking @synchronized (self) { if (!inst) { inst = [[Foo alloc] init]; } } } return inst; }
  • 47.
    // within classFoo + (Foo*) getDefault { static volatile Foo *inst = nil; if (!inst) { // double-check locking @synchronized (self) { if (!inst) { Foo *tmp = [[Foo alloc] init]; OSMemoryBarrier(); inst = tmp; } } } OSMemoryBarrier(); return inst; }
  • 48.
    // within classFoo + (Foo*) getDefault { static volatile Foo *inst; static dispatch_once_t pred; dispatch_once(&pred, ^ { inst = [[Foo alloc] init]; }); return inst; }
  • 49.
    Thank you http://www.inmite.eu/talks Petr Dvořák Partner & iOS Development Lead @joshis_tweets