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 Slide

  2. agenda

    View Slide

  3. the market

    View Slide

  4. 7 billion mobile phones

    View Slide

  5. 1,5 billion smartphones

    View Slide

  6. View Slide

  7. why iOS?

    View Slide

  8. Android won, right?

    View Slide

  9. Android has 75% market share

    View Slide

  10. 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 Slide

  11. View Slide

  12. View Slide

  13. View Slide

  14. native vs. hybrid vs. web

    View Slide

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

    View Slide

  16. != !=
    Hybrid…

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. 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 Slide

  21. becoming an iOS developer

    View Slide

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

    View Slide

  23. View Slide

  24. View Slide

  25. my setup

    View Slide

  26. 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 Slide

  27. 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 Slide

  28. Objective-C

    View Slide

  29. Classes

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. 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 Slide

  34. 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 Slide

  35. Automatic Reference Counting (ARC)

    View Slide

  36. ObjectiveC is a wild horse

    View Slide

  37. Cocoa

    View Slide

  38. MVC

    View Slide

  39. Notification centre

    View Slide

  40. Key-value observing

    View Slide

  41. 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 Slide

  42. Tips

    View Slide

  43. 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 Slide

  44. 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 Slide

  45. 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 Slide

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

    View Slide

  47. Frameworks

    View Slide

  48. 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 Slide

  49. 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 Slide

  50. 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 Slide

  51. 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 Slide

  52. View Slide

  53. mono vs objective-c

    View Slide

  54. 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 Slide

  55. 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 Slide

  56. 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 Slide

  57. 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 Slide