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

Tips & Tricks of Effective iOS Developers

Tips & Tricks of Effective iOS Developers

Talk given at CocoaConf Chicago, 2014

Ben Scheirman

March 08, 2014
Tweet

More Decks by Ben Scheirman

Other Decks in Programming

Transcript

  1. Tips & Tricks of
    Effective
    iOS Developers

    View Slide

  2. BEN SCHEIRMAN
    @subdigital

    View Slide

  3. View Slide

  4. Weekly Screencasts
    on iOS DEVELOPMENT
    $9/month

    View Slide

  5. Tips & Tricks of
    Effective
    iOS Developers

    View Slide

  6. ?
    Effective

    View Slide

  7. effective |iˈfektiv|
    adjective
    !
    successful in producing a
    desired or intended result

    View Slide

  8. !
    DEVELOPERS
    Effective

    View Slide

  9. !
    DEVELOPERS
    FIX PROBLEMS
    Effective

    View Slide

  10. !
    DEVELOPERS
    WRITE CODE FASTER
    Effective

    View Slide

  11. !
    DEVELOPERS
    CONFIDENTLY REFACTOR
    Effective

    View Slide

  12. !
    DEVELOPERS
    WRITE BETTER CODE
    Effective

    View Slide

  13. !
    DEVELOPERS
    WRITE FEWER BUGS
    Effective

    View Slide

  14. !
    DEVELOPERS
    GET THINGS DONE
    Effective

    View Slide

  15. !
    DEVELOPERS
    SHIP BETTER SOFTWARE
    Effective

    View Slide

  16. SHIP BETTER SOFTWARE

    View Slide

  17. ME?

    View Slide

  18. View Slide

  19. I aspire to be
    Effective

    View Slide

  20. Objective-C
    Tips

    View Slide

  21. Always use braces for conditionals
    if ([self isHungry]) {
    [self eatBurger];
    }
    if ([self isHungry])
    [self eatBurger];
    if ([self isHungry])
    [self eatBurger];
    [self takeNap];
    if ([self isHungry]) {
    [self eatBurger];
    [self takeNap];
    }

    View Slide

  22. if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
    goto fail;
    if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
    goto fail;
    goto fail;
    if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
    goto fail;
    ...
    !
    fail:
    SSLFreeBuffer(&signedHashes);
    SSLFreeBuffer(&hashCtx);
    return err;
    Always use braces for conditionals

    View Slide

  23. View Slide

  24. @interface Player
    !
    - (void)moveLeft;
    - (void)moveRight;
    - (void)jump;
    - (void)hit;
    !
    @end
    Use Class Continuations for Private Properties
    @interface Player ()
    @property CGFloat health;
    @property Texture *texture;
    @end
    !
    @implementation Player

    @end
    Player.h Player.m

    View Slide

  25. Use Class Continuations for Private Properties
    @interface ViewController ()
    @property IBOutlet UILabel *label;
    @end
    !
    @implementation ViewController

    @end

    View Slide

  26. Use intention revealing method names
    - (NSDate *)nextDate:(NSDate *);
    - (NSDate *)nextBillingDateAfterDate:(NSDate *);

    View Slide

  27. Name single parameter BOOL arguments
    -(void)showPanel:(BOOL)animated;
    [self showPanel:NO];

    View Slide

  28. Name single parameter BOOL arguments
    -(void)showPanelAnimated:(BOOL)animated;
    [self showPanelAnimated:NO];

    View Slide

  29. Add Comment Documentation to Public Methods

    View Slide

  30. - (void)viewDidLoad {
    [self.fetchedResultsController performFetch:nil];
    }
    Lazily Initialize Properties
    - (NSFetchedResultsController *)fetchedResultsController {
    if (_frc == nil) {
    _frc = [[NSFetchedResultsController alloc]
    initWithFetchRequest: self.fetchRequest
    ...
    ]
    }
    !
    return _frc;
    }

    View Slide

  31. Lazily Initialize Properties
    - (NSFetchRequest *)fetchRequest {
    if (_fetchRequest == nil) {
    _fetchRequest = …
    }
    return _fetchRequest;
    }

    View Slide

  32. Lazily Initialize Properties
    - (void)didReceiveMemoryWarning {
    self.fetchResultsController = nil;
    self.fetchRequest = nil;

    }

    View Slide

  33. Use Refactor Method judiciously
    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)
    indexPath {
    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@“cell”];
    NSArray *peopleInSection = self.sections[indexPath.section];
    Person *person = peopleInSection[indexPath.row];
    cell.textLabel.text = [NSString stringWithFormat:@“%@ %@“, person.firstName,
    person.lastName];
    cell.detailTextLabel.text = person.email;
    return cell;
    }

    View Slide

  34. Use Refactor Method judiciously
    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)
    indexPath {
    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@“cell”];
    Person *person = [self personAtIndexPath:indexPath];
    cell.textLabel.text = [NSString stringWithFormat:@“%@ %@“, person.firstName,
    person.lastName];
    cell.detailTextLabel.text = person.email;
    return cell;
    }

    View Slide

  35. Use Refactor Method judiciously
    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)
    indexPath {
    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@“cell”];
    Person *person = [self personAtIndexPath:indexPath];
    cell.textLabel.text = person.fullName;
    cell.detailTextLabel.text = person.email;
    return cell;
    }

    View Slide

  36. Use Refactor Method judiciously
    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)
    indexPath {
    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@“cell”];
    Person *person = [self personAtIndexPath:indexPath];
    [self updateCell:cell forPerson:person];
    return cell;
    }

    View Slide

  37. Understand Dependencies
    method1 method2

    View Slide

  38. Understand Dependencies

    View Slide

  39. Understand Dependencies

    View Slide

  40. Understand Dependencies

    View Slide

  41. Keep your dependencies in check
    OO is your friend

    View Slide

  42. objc-dependency-visualizer
    http://paultaykalo.github.io/objc-dependency-visualizer

    View Slide

  43. http://jomnius.blogspot.com/2012/01/dependency-graph-tool-for-ios-projects.html

    View Slide

  44. http://jomnius.blogspot.com/2012/01/dependency-graph-tool-for-ios-projects.html

    View Slide

  45. Reduce Dependencies by…
    Loose Coupling
    Programming to interfaces
    Dependency Inversion
    Reduce God Objects
    Reduce Singletons

    View Slide

  46. With Less Dependencies you can…
    Refactor
    Change your mind
    Change your implementation
    Add features

    View Slide

  47. “Ruthlessly modularize functionality. Design, implement, and
    package everything as if it were to be distributed as 3rd-party
    code”

    View Slide

  48. “Ruthlessly modularize functionality. Design, implement, and
    package everything as if it were to be distributed as 3rd-party
    code”

    View Slide

  49. Mattt Thompson

    View Slide

  50. Slim down your classes

    View Slide

  51. Slim down your classes

    View Slide

  52. Try to impose limits

    View Slide

  53. Challenge Yourself
    Photograph by Mikey Schaefer

    View Slide

  54. Max LOC for .m: ~150
    Max LOC for method: 4-5
    Cesare Rocchi

    View Slide

  55. Automate it

    View Slide

  56. awk

    View Slide

  57. find "${SRCROOT}" \(-name "*.h" -or -name "*.m"\)
    -and \( -path "${SRCROOT}/Pods/*"
    -prune -o -print0 \) |
    xargs -0 wc -l |
    awk '$1 > 400 && $2 != "total" {
    for(i=2;iprintf "%s%s", $i, " “
    }
    print $NF ":1: warning: File more
    than 400 lines (" $1 "), consider
    refactoring." }'
    http://matthewmorey.com/improved-xcode-build-phases/

    View Slide

  58. Xcode
    Tips

    View Slide

  59. Completing Methods

    View Slide

  60. “- ta”

    View Slide

  61. Label your views in
    Interface Builder

    View Slide

  62. Learn Keyboard Shortcuts
    Photo credit: Wikipedia

    View Slide

  63. ⌘0

    View Slide

  64. ⌘⌥0

    View Slide

  65. ⌘⇧J

    View Slide

  66. ⌘⇧Y

    View Slide

  67. ⌘⇧C

    View Slide

  68. ⌘⌃J ⌘⌃←

    View Slide

  69. Jump in Assistant, back

    View Slide

  70. ⌘⌃E (Edit all in Scope)

    View Slide

  71. ⌃I (Re-indent selection)

    View Slide

  72. So many to learn

    View Slide

  73. Pick 2 you don’t know

    View Slide

  74. Deliberately Practice them

    View Slide

  75. Repeat.

    View Slide

  76. View Slide

  77. Snippets

    View Slide

  78. Xcode / TextExpander

    View Slide

  79. “pns”
    @property (nonatomic, strong)

    View Slide

  80. “propint”
    @property (nonatomic, assign) NSInteger

    View Slide

  81. “propstr”
    @property (nonatomic, copy) NSString *

    View Slide

  82. “mark”
    #pragma mark -

    View Slide

  83. #pragma mark

    View Slide

  84. #pragma mark

    View Slide

  85. “tvds”

    View Slide

  86. “swf”

    View Slide

  87. “tvdel”

    View Slide

  88. “networkact”
    [[UIApplication sharedApplication]
    setNetworkActivityIndicatorVisible:YES];

    View Slide

  89. Repetitive code?
    Boilerplate code?
    !
    Make a snippet.

    View Slide

  90. Source Control
    Tips

    View Slide

  91. (git)

    View Slide

  92. Use the
    command
    line

    View Slide

  93. Leverage GUIs for
    specific tasks

    View Slide

  94. http://rowanj.github.io/gitx/
    GitX

    View Slide

  95. Commits aren’t just
    ⌘S

    View Slide

  96. Commit in logical
    chunks.

    View Slide

  97. Write a good commit
    message

    View Slide

  98. http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
    Capitalized, short (50 chars or less) summary
    !
    More detailed explanatory text, if necessary. Wrap it to about 72
    characters or so. In some contexts, the first line is treated as the
    subject of an email and the rest of the text as the body. The blank
    line separating the summary from the body is critical (unless you omit
    the body entirely); tools like rebase can get confused if you run the
    two together.
    !
    Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
    or "Fixes bug." This convention matches up with commit messages generated
    by commands like git merge and git revert.
    !
    Further paragraphs come after blank lines.
    !
    - Bullet points are okay, too
    !
    - Typically a hyphen or asterisk is used for the bullet, followed by a
    single space, with blank lines in between, but conventions vary here
    !
    - Use a hanging indent

    View Slide

  99. $ git log --oneline
    !
    9511f6c Add mixpanel gem
    47a3e6d Add a sleep to not get throttled by facebook
    ce30dcb Kick Jenkins build
    2e6802f Merge pull request #981 from DeliRadio/venue-favorites-rabls
    99eb628 stub master account to avoid fail when run in test suite.
    b4e0435 before(:all) -> before(:each) to avoid certain test to fail when execute
    e4b10b6 Update schema
    7b1e053 Fix banner check for venues in autocomplete
    83ca7cb Update ci reporter
    6eae32f Fix admin manages events spec.
    7c8902b Add new line at the end of file so Github likes it.
    a153a48 Call Rails.application.eager_load! right before it is needed so that its
    4a4d050 Refactoring test so it finishes faster.
    4155ac6 fix crash when correcting country code from geolocated params
    08c5bdb Proper auth token generation for facebook login:
    4efaf1e Venue needs to have shareable_id and shareable_type implementation. Defa
    a9cdd7a Implemented a test to check shareable_id and shareable_type. Since Favor
    9e1e6c2 fix after_party task syntax
    dde3ae9 add after_party task to fill in fb birthdays where we can
    6e99a74 Implemented tests to check renderability of all ActiveRecord instance th
    b174af9 Added four templates that are required for favoritable items.
    07218a0 year_of_birth, not birth_year
    be562bf update attribs from fb even for existing users
    29041f0 Add logging to facebook oauth responses

    View Slide

  100. View Slide

  101. Branches are basically free

    View Slide

  102. View Slide

  103. REBASE
    Learn to

    View Slide

  104. master
    origin/master

    View Slide

  105. master origin/master

    View Slide

  106. master
    origin/master
    MERGE METHOD
    “git pull” by default

    View Slide

  107. master origin/master

    View Slide

  108. master
    origin/master
    REBASE METHOD

    View Slide

  109. 99% of the time you want
    !
    git pull --rebase

    View Slide

  110. Make this the default
    git config branch.autosetuprebase always

    View Slide

  111. Never rebase public branches

    View Slide

  112. git bisect

    View Slide

  113. View Slide

  114. git bisect start

    View Slide

  115. git bisect bad

    View Slide

  116. git checkout HEAD~15

    View Slide

  117. git bisect good

    View Slide

  118. ?

    View Slide

  119. git bisect bad

    View Slide

  120. git bisect bad

    View Slide

  121. View Slide

  122. git bisect good

    View Slide

  123. View Slide

  124. git bisect good

    View Slide

  125. View Slide

  126. git bisect good

    View Slide

  127. View Slide

  128. git bisect run <br/>

    View Slide

  129. Oops, I made a git mistake!

    View Slide

  130. git reflog

    View Slide

  131. View Slide

  132. Branch Per Feature

    View Slide

  133. Keep Master Releasable

    View Slide

  134. Don’t veer too far from
    working software

    View Slide

  135. “I attempt to keep the app in a working state as much as possible.
    That means test driving small changes, committing often, and only
    hooking things up to the UI when I think they're ready…”

    View Slide

  136. “… If I'm not in a position to push my
    code at least every hour or so, I feel like I
    haven't broken my work down properly”

    View Slide

  137. Stew Gleadow

    View Slide

  138. http://collectorcare.blogspot.com/

    View Slide

  139. http://cobcottagegifts.com/

    View Slide

  140. Effective
    Habits

    View Slide

  141. “I'm not a great programmer; I'm just a good programmer with great habits.”
    !
    - Kent Beck

    View Slide

  142. Keep an improvement list
    !
    !

    View Slide

  143. Have a side project
    !
    !

    View Slide

  144. Read Other People’s Code

    View Slide

  145. “I form opinions about the code I study. Not
    all of it is good. I want to reflect on why I
    feel that way.”

    View Slide

  146. Jonathan Penn

    View Slide

  147. Learn how to ask for help

    View Slide

  148. View Slide

  149. View Slide

  150. Don’t ask
    !
    Questions.
    5

    View Slide

  151. Ask
    !
    Question.
    1

    View Slide

  152. Distill
    The
    Problem

    View Slide

  153. Reduce
    Variables

    View Slide

  154. Also works for:

    View Slide

  155. “Before asking for advice, take a careful
    look at what you know and what you are
    looking to have answered. Often that will
    put you in a spot where you answer your
    own question.”
    ! !

    View Slide

  156. Daniel Steinberg

    View Slide

  157. View Slide

  158. Program
    in
    other
    Languages

    View Slide

  159. “Don't just program in Objective C, make
    sure you regularly use another language.
    There is a lot we can learn from other
    technologies and communities”
    !
    - Stew Gleadow
    ! !

    View Slide

  160. Write Tests.

    View Slide

  161. Go Forth,
    and be
    Effective

    View Slide

  162. Thank you
    BEN SCHEIRMAN
    @subdigital
    chaione.com

    View Slide