71
1

Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

  • Upload
    yandex

  • View
    118

  • Download
    0

Embed Size (px)

DESCRIPTION

Building Quality Code That Lasts: A Dropbox Story

Citation preview

Page 1: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

1

Page 2: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Building Quality Code That Lasts: A Dropbox StoryAshley Nelson-Hornstein · 10 - 30 - 14

2

Page 3: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Product

Testing

Background

Case Studies

Future of iOS at Dropbox

TODAY’S TALK

3

Page 4: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Dropbox for iOSDeveloped natively

Team of one engineer

First consumer of Dropbox public APIs

Released for iPhone in 2009

iPad support in 2010

4

Page 5: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Sync SDK

UI Code

Core SDK

Data Layer

5

Page 6: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

6

Page 7: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

6

Page 8: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

6

Page 9: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

6

Page 10: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

TODAY’S TALK

Product

Testing

Background

Case Studies

Future of iOS at Dropbox

7

Page 11: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Product RoadmapCollaborative process

Mix of

Infrastructure

User facing features

Code modernization

8

Page 12: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Release ManagerRotating role

Feature gatekeeper

Project manager

Task prioritization

Scheduling

Build stabilization

9

Page 13: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Development

10

Page 14: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

BranchingDefault branch

All changes are checked in here first

Release branch

hg graft —log from default branch

Verified by release manager

11

Page 15: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

12

Page 16: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

13

Page 17: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

13

Page 18: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Style Guide

14

Page 19: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Coding ConventionsPrefix internal methods with db_

Prefer class methods

Hide implementation detail

Class extensions

15

Page 20: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

16

// DBFile.h !

@interface DBFile : NSObject !

@property (readonly, strong) NSData *contents; !

@property (readonly, strong) NSURL *publicShareLink; !

@property (strong) NSDictionary *permissions; !

- (void)copyToNewPath:(NSString *)newPath; !

@end

// DBFile.m !

@interface DBFile () !

@property (readwrite, strong) NSData *contents; !

@property (strong) NSString *localFilePath; @end !

@implementation DBFile !

- (void)copyToNewPath:(NSString *)newPath { ... } @end

Page 21: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Comments// TODO: (ashleynh) 2014-10-30

Reminder for future improvement

// FIXME: (ashleynh) 2014-10-30

Generates compiler warning, not for release

// HAX: (ashleynh) 2014-10-30

Non-obvious API workaround

17

Page 22: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Builds

18

Page 23: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Continuous IntegrationPool of build machines

Executes functional tests

Builds are available to office

State changes are emailed to team

19

Page 24: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

20

Page 25: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Crash ReporterDeveloped in-house

Predates other crash report services

Uploads crash logs from device

Groups crashes by stack trace

Provides symbolication

21

Page 26: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

22

Page 27: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

TODAY’S TALK

Testing

Case Studies

Future of iOS at Dropbox

Background

23

Product

Page 28: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Developer SettingsToggle features on/off

View

Run log

Network and device stats

File cache inspection

24

Page 29: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Shake to ReportInternal bug reporting

Captures

Screenshot

Crash log (if applicable)

Run log

Issues reported directly to bug tracking tool

25

Page 30: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Helper Apps

26

Page 31: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

DropolineDeveloped in-house

Tests inter-app workflows

File import/export

Photo backup

Storage provider extension

27

Page 32: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Car KeysDeveloped in-house

Keychain

Inspection

Deletion

28

Page 33: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Automata

29

Page 34: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Automata BackgroundFunctional testing framework

Developed in-house

Run tests locally or using Jenkins

Python API

Rich set of libraries to simplify automation

High productivity

30

Page 35: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Automata BenefitsSeparate process enables inter-app testing

Single test can manipulate two apps

Automating screenshots and screenshot diffs

Objective-C experience not required

Hooks into Objective-C runtime

31

Page 36: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

32

Automata

Dropbox Dropoline

Page 37: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

32

Automata

Dropbox Dropoline

Page 38: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Automata FutureSupport for iOS 8 extensions

GUI that records test scripts

Open source

33

Page 39: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

TODAY’S TALK

Testing

Case Studies

Future of iOS at Dropbox

Background

34

Product

Page 40: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

File Cache

35

Page 41: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

BackgroundProvides access to user’s Dropbox files

Coordinates with REST API and disk

Critical component

36

Page 42: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesFile names of stored files are Dropbox paths

Unusually long file paths

Unsupported unicode characters

File loading race conditions

Providing readwrite access to file refs

37

Page 43: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

/* * Hello there, friend. I wish you luck in your voyage through the following code. * * We need to avoid doing disk I/O in this callback, because it will be called in quick succession * repeatedly on photos tab as we load lots of thumbs. Since we're on the main thread right now, * we can't afford to do costly disk I/O. It will seriously impact scroll performance on photos tab * if we do. * * The following code checks to see if what we just loaded has only a thumbnail repr. If it does, * it updates the cacheSize property of the file to -1. -1 is a special flag, indicating to the LRU cleanup * mechanism that this file doesn't need to be purged from the disk during LRU cleanup. * * Why not cleanup these files during LRU cleanup? Because with the release of photos tab, we may * have thousand of files on disk. And starting them all during LRU cleanup is much too slow. So, * we've opted to just not clean up files that only have thumbnail reprs. * * This code is not "correct". For example, if you load a thumbnail *AND* the BestFit repr, the thumbnail * could now be cleaned up during LRU cleanup. * * This is basically a huge hack to make scrolling performance not stutter in photos tab. * */

38

Page 44: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

/* * Hello there, friend. I wish you luck in your voyage through the following code. ! * This is basically a huge hack to make scrolling performance not stutter in photos tab. */

39

Page 45: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

GoalsEnsure file name integrity

Operations on separate queue

Smarter file loading system

Defensive return values

40

Page 46: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

ApproachUnit Tests

Uncovered existing bugs

Set a baseline for expected behavior

Maintained API for consumers

Limited project scope

41

Page 47: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

ImplementationStore files by UUID instead of Dropbox path

File Cache on background serial queue

Return immutable stubs of file refs

LoadingFileManager

42

Page 48: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Consumer FileCache

RO Cached File

Core Data

Disk

Loading File Manager

Single Background Queue

43

Page 49: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

BenefitsEasier to understand

Performant

Stable

44

Page 50: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

App Delegate

45

Page 51: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

[[UIApplication sharedApplication] delegate]

46

Page 52: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

47

Page 53: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Issues

48

Page 54: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp could be entered in a number of ways

48

Page 55: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp could be entered in a number of ways

User initiated

48

Page 56: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp could be entered in a number of ways

User initiated

File import

48

Page 57: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp could be entered in a number of ways

User initiated

File import

API connection

48

Page 58: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp could be entered in a number of ways

User initiated

File import

API connection

Notification

48

Page 59: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp could be entered in a number of ways

User initiated

File import

API connection

Notification

Etc.

48

Page 60: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp entry state could be

48

Page 61: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp entry state could be

Passcode on

48

Page 62: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp entry state could be

Passcode on

Passcode off

48

Page 63: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp entry state could be

Passcode on

Passcode off

Locked out

48

Page 64: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

IssuesApp entry state could be

Passcode on

Passcode off

Locked out

Already displaying a modal

48

Page 65: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

Overly complex logic

48

Page 66: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

GoalsProperly define app states

Encapsulate state logic

Transition easily between states

Speed launches

49

Page 67: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

ImplementationState Pattern

DBState

Initial

NotLoggedIn

ContinueAs

LoggedInNoPasscode

LoggedInPasscode

50

Page 68: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

BenefitsReduced 2600 lines to 500 lines

Easier to understand

Encapsulated logic in clear boundaries

51

Page 69: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

TODAY’S TALK

Testing

Case Studies

Future of iOS at Dropbox

Background

52

Product

Page 70: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

SwiftExcited by the promise

Practical approach

Tooling

Encapsulated features

53

Page 71: Building Quality Code That Lasts: A Dropbox Story. Ashley Nelson-Hornstein

54