Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DeveloperUG 2013: Developing for iOS - When to do what and how

DeveloperUG 2013: Developing for iOS - When to do what and how

In this session we will look at the tools, framework and languages available to build applications for the iOS. The session will explore various development approaches for creating iOS apps including native, hybrid and web. Tools that we be covered include Xcode (ObjC), MonoTouch (C#) and other web-based and hybrid frameworks.

This session will also discuss development strategies to apply when targeting many devices.

Martin Cronjé

September 10, 2013
Tweet

More Decks by Martin Cronjé

Other Decks in Programming

Transcript

  1. Developing for iOS - When to do what and how
    @martincronje
    [email protected]

    View full-size slide

  2. 7 billion mobile phones

    View full-size slide

  3. 1,5 billion smartphones

    View full-size slide

  4. Android won, right?

    View full-size slide

  5. Android has 75% market share

    View full-size slide

  6. Platform
    Mobile OS
    2013[a]
    Mobile OS
    2017[a]
    App
    downloads
    2013[b]
    Web usage
    2013[c]
    3.9% 10.2% 3.7% 1.5%
    16.9% 17.9% 47.8% 54.91%
    75.3% 68.3% 48.6% 25.7%
    3.9% 3.6% - 17,89%
    Target platform (Global market share)?
    a) IDC Worldwide Mobile Phone Tracker, June 6, 2012
    b) XYO Global App Download Reports 1.0
    c) NetMarketShare Mobile Operating System Aug 2013

    View full-size slide

  7. native vs. hybrid vs. web

    View full-size slide

  8. When you want the worst of both...
    Hybrid:

    View full-size slide

  9. != !=
    Hybrid…

    View full-size slide

  10. “The biggest mistake we’ve made as a
    company is betting on HTML5 over native.”
    Mark Zuckerberg

    View full-size slide

  11. When you want to extend your phone...
    Native:

    View full-size slide

  12. When you want cost-effective...
    Web:

    View full-size slide

  13. Approach characteristics
    User
    Experience
    Device
    Access
    Works
    offline
    Cost of
    ownership
    Reach
    Native Highest Yes Yes Highest Specific
    Cross Platform High Yes * Yes * High ** Common *
    Hybrid Low Yes * Partially * Medium ** Common *
    Web (Rich) Low Limited No Low 30%
    Web (Light) Lowest None No Lowest 80%
    * Depends on framework and approach chosen.
    ** Depending on support offered by relevant platform

    View full-size slide

  14. becoming an iOS developer

    View full-size slide

  15. Developing Apps for iPhone and iPad
    (Winter 2013)

    View full-size slide

  16. My setup
    MacBook Pro 15”
    (Retina Display, 8GB RAM, i7, SSD)
    OSX Mountain Lion 10.8.4 Windows 8
    Xcode / AppCode
    Xamarin Studio
    Visual Studio 2012
    Xamarin Studio
    VMWare
    Fusion

    View full-size slide

  17. My software on OSX
    IDE Xcode, AppCode and Xamarin Studio
    Editors vi and Sublime
    Shell iTerm, zsh and oh-my-zsh
    Misc Homebrew, Alfred, AirMail, Fanstical and 1Password

    View full-size slide

  18. Methods
    [myObject insertObject:objectToInsert atIndex:0];!

    View full-size slide

  19. -(id)doYouKnowTheMuffinMan:(TheMuffinMan *)theMuffinMan;!

    View full-size slide

  20. Blocks
    int result = myBlock(4); // result is 28!

    View full-size slide

  21. Literals
    NSNumber *number;!
    !
    number = [NSNumber numberWithChar:'X'];!
    number = [NSNumber numberWithInt:12345];!
    number = [NSNumber numberWithUnsignedLong:12345ul];!
    number = [NSNumber numberWithLongLong:12345ll];!
    number = [NSNumber numberWithFloat:123.45f];!
    number = [NSNumber numberWithDouble:123.45];!
    number = [NSNumber numberWithBool:YES];!
    number = @'X’;!
    number = @12345;!
    number = @12345ul;!
    number = @12345ll;!
    number = @123.45f;!
    number = @123.45;!
    number = @YES;!

    View full-size slide

  22. Literals
    dict = [NSDictionary dictionaryWithObjects:@[o1, o2, o3]!
    forKeys:@[k1, k2, k3]];!
    !
    dict = @{ k1 : o1, k2 : o2, k3 : o3 };!
    !
    !
    !
    !
    array = [NSArray arrayWithObjects:a, b, c, nil];!
    !
    array = @[ a, b, c ];!
    !

    View full-size slide

  23. Automatic Reference Counting (ARC)

    View full-size slide

  24. ObjectiveC is a wild horse

    View full-size slide

  25. Notification centre

    View full-size slide

  26. Key-value observing

    View full-size slide

  27. Animated
    - (void)reset:(BOOL)animated {!
    if(animated) {!
    [UIView animateWithDuration:0.3f!
    delay:0.0f!
    options:(UIViewAnimationOptionCurveEaseIn)!
    animations:!
    ^{!
    self.front.alpha = 1.0;!
    self.front.frame = CGRectMake(0, 0, width, height);!
    } completion:nil];!
    } else {!
    self.front.alpha = 1.0;!
    }!
    }!

    View full-size slide

  28. Asynchronous Processing
    [NROperationQueue runInBackground:^() {!
    // Some long-running operation!
    [NROperationQueue runOnMain:^() { !
    // Update the UI !
    }];!
    }];!
    !
    !
    !
    @implementation NROperationQueue!
    + (void)runOnMain:(void (^)(void))block {!
    [[NSOperationQueue mainQueue] addOperationWithBlock:block];!
    }!
    + (NSOperationQueue *)backgroundQueue {!
    return [self instance].backgroundQueue; // NSOperationQueue !
    }!
    @end!

    View full-size slide

  29. Factory Methods
    #import "ECMIncident.h"!
    #import "NSDictionary+Conversions.h"!
    !
    @implementation ECMIncident!
    !
    - (id)initFromJSON:(NSDictionary *)jsonObject {!
    if(self = [super init]) {!
    self.activity = [jsonObject stringForKey:@"activity"];!
    self.age = [jsonObject numberForKey:@"age"];!
    }!
    return self;!
    }!
    !
    + (ECMIncident *)incidentFromJSON:(NSDictionary *)dictionary {!
    return [[ECMIncident alloc] initFromJSON: dictionary];!
    }!
    !
    @end!

    View full-size slide

  30. Test-driven development
    -  (void)testShouldParseJsonIntoModel {!
    NSData *content = [self loadFile:@"incident.simple"];!
    !
    NSError *error = nil;!
    NSDictionary *jsonObject = [NSJSONSerialization !
    JSONObjectWithData : content!
    options : nil !
    error : &error];!
    !
    ECMIncident *incident = [ECMIncident incidentFromJSON: jsonObject];!
    !
    STAssertNotNil(incident, @"Expected populated object");!
    STAssertTrue([incident.summary isEqualToString:@"Foo Bar"]);!
    }!

    View full-size slide

  31. Some other tips
    •  Information hiding
    •  Singletons and dependency injection

    View full-size slide

  32. Cocoapods
    $ gem install cocoapods!
    $ cat Podfile!
    platform :ios, :deployment_target => '6.0'!
    pod 'AFNetworking'!
    pod 'Objection'!
    pod 'Facebook-iOS-SDK'!
    pod 'OCHamcrest'!
    !
    $ pod setup!

    View full-size slide

  33. Frank
    Feature: General (Main)!
    Scenario: My details!
    !
    Given I logged in with "my-user-1" !
    And I wait for "Logging in…" to go away!
    When I touch the "My Details" table cell!
    Then I wait to see a navigation bar titled "My Details"!
    And I should see a table containing the following:!
    | Column 1 |!
    | Username | !
    | Email |!
    | First Name |!
    ...!
    When I type "Martin" into the Username text field!
    And I ...!

    View full-size slide

  34. Frank
    Then /^I wait to see a navigation bar titled "([^\"]*)"$/ do |expected_mark|!
    quote = get_selector_quote(expected_mark)!
    message = "waited to see a navigation bar titled #{quote}#{expected_mark}#{quote}"!
    wait_until( :timeout => 30, :message => message) {!
    element_exists( "navigationItemView marked:#{quote}#{expected_mark}#{quote}" )!
    }!
    end!
    !
    When /^I touch the "([^\"]*)" table cell$/ do |name|!
    touch("tableView view marked:'#{name}'")!
    end!
    !
    When /^I type "([^"]*)" into the ([^"]*) text field$/ do |value, field|!
    selector = "label marked:'#{field}' parent tableViewCell textField"!
    text_fields_modified = frankly_map(selector, "setText:", value )!
    raise "could not find text fields to update" if text_fields_modified.empty?!
    end!

    View full-size slide

  35. Frank
    Then /^I should see a table containing the following:$/ do |table|!
    !
    table.rows.each do |row|!
    selector = String.new!
    !
    row.each do |cell|!
    if selector.empty?!
    selector = "tableView view marked:'#{cell}'"!
    else!
    selector << " parent tableViewCell view marked:'#{cell}'"!
    end!
    end!
    check_element_exists( selector )!
    end!
    end!

    View full-size slide

  36. mono vs objective-c

    View full-size slide

  37. Development platform
    Platform IDE SDK Language OS
    Visual Studio Windows Phone C#, etc. Windows
    Xcode Cocoa Touch Objective-C OSX
    Eclipse Android Java All

    View full-size slide

  38. Development platform
    Platform IDE SDK Language OS
    Visual Studio Windows Phone C#, etc. Windows
    Visual Studio
    Xamarin Studio
    Cocoa Touch C#
    (Compiled to ObjC)
    Windows* /
    OSX
    Visual Studio
    Xamarin Studio
    Android C# Windows / OSX
    * OSX build server required

    View full-size slide

  39. Sharing Code
    Application Layer
    User Interface
    Android SDK
    Android SDK
    Cocoa Touch
    Cocoa Touch
    Win Phone SDK
    Win Phone SDK
    Shared
    - Model
    - Data Access
    - Business Logic
    - Service Access

    View full-size slide

  40. Android SDK
    Cocoa Touch
    Win Phone SDK
    Xamarin.Mobile
    App Layer
    Sharing Code
    UI
    Android SDK
    Cocoa Touch
    Win Phone
    SDK
    Shared
    Business
    Logic
    Adapter pattern
    View Controller

    View full-size slide