"architecting and testing large ios apps: lessons from facebook". adam ernst, facebook

59

Post on 21-Oct-2014

2.973 views

Category:

Technology


2 download

DESCRIPTION

In 2012 Facebook relaunched their iOS app to use native code. This was a big shift in architecting and implementing the Facebook app experience, the most widely used third party app on the entire iOS platform. Adam Ernst will speak about how the decision was made to switch to native code and how the company prepared to rewrite the app. He will share an inside look at the APIs and technical architecture Facebook uses to enable dozens of iOS developers to work on the same application. Automated testing is very important to Facebook, so Adam will also speak about how Facebook uses testing on iOS to keep the app reliable.

TRANSCRIPT

Page 1: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 2: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Adam Ernst

Architecting and Testing Large iOS Apps: Lessons from Facebook

Facebook

Page 3: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

developers

Adam [email protected]

@adamjernstgithub.com/adamjernst

Testing Facebook for iOS

Page 4: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Agenda

▪ “Over the wall”: some history

▪Product Teams and the Core Team

▪Scheduling and Stabilizing Releases

▪How We Develop

▪Eating the Dogfood: Builds

▪A Culture of Unit Testing

▪Future of iOS at Facebook

Page 5: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

History

Page 6: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Facebook for Mobile

▪Web deeply engrained in Facebook’s DNA

▪Use HTML!/Javascript within “wrapper” native app

▪Developed our own framework for advanced integration(image uploads, photo browsers, mixing native/web elements)

Page 7: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

HTML as an app platform

▪What does it bring us?

One CodebaseInstant Updates A/B Testing

Page 8: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

HTML as an app platform

Page 9: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

A few engineers in a room

▪Facebook for iOS !." began as an experiment

Page 10: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

A few engineers in a room

▪Facebook for iOS !." began as an experiment

▪Could we achieve better results with native code?

Page 11: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

A few engineers in a room

▪Facebook for iOS !." began as an experiment

▪Could we achieve better results with native code?

▪High barrier: requires rewriting every part of Facebook’s mobile UI!

Page 12: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

A few engineers in a room

▪Facebook for iOS !." began as an experiment

▪Could we achieve better results with native code?

▪High barrier: requires rewriting every part of Facebook’s mobile UI!

▪Couldn’t disrupt company for something that might not ship(At the time, few iOS engineers at Facebook anyway)

Page 13: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

A few engineers in a room

▪Facebook for iOS !." began as an experiment

▪Could we achieve better results with native code?

▪High barrier: requires rewriting every part of Facebook’s mobile UI!

▪Couldn’t disrupt company for something that might not ship(At the time, few iOS engineers at Facebook anyway)

▪Sequester some engineers in a war room, and have themwrite the product from top to bottom

Page 14: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Reaction

▪Press loved it

▪More importantly…

▪ Perceived Speed way up

▪ User Ratings way up

▪#x Speed increase!

Page 15: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Reaction

▪Press loved it

▪More importantly…

▪ Perceived Speed way up

▪ User Ratings way up

▪#x Speed increase!

Page 16: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Team

Page 17: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

A multi-app ecosystem

Page 18: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

A multi-app ecosystem

Page 19: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

The Team Sandwich

Release Team: Release & Stabilization ProcessRelease Team: Release & Stabilization ProcessRelease Team: Release & Stabilization ProcessRelease Team: Release & Stabilization ProcessRelease Team: Release & Stabilization Process

Photos Feed Search Places Messages

Product Infrastructure Team: Shared LibrariesProduct Infrastructure Team: Shared LibrariesProduct Infrastructure Team: Shared LibrariesProduct Infrastructure Team: Shared LibrariesProduct Infrastructure Team: Shared Libraries

Page 20: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Product Cycle

Page 21: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 22: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 23: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Fixed Release Cycle

▪Waiting for all features in a release to be “done” slowed us down, and we want to move fast

▪So, ship an update every X weeks

▪ … no matter what

▪Popularized by Mozilla

Page 24: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Building features with an “off switch”

▪Every feature must be built with a way to turn it off

▪ If a feature destabilizes the build or isn’t complete, turn it off and try again next time

▪#defines – or runtime switches (preferred)

Page 25: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Building a new “Like Bar”

Page 26: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Building a new “Like Bar”

Page 27: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Development

Page 28: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 29: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 30: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Phabricator

Text

Page 31: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Phabricator

Text

Page 32: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Phabricator

Text

Page 33: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Phabricator

Text

Page 34: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Phabricator

Text

Page 35: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 36: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 37: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Check code

▪ ‘arc lint’

▪Set up rules to catch common mistakes

▪Examples:

▪ Enforce style guidelines

▪ Warn against using certain symbols

▪ Check for common pattern mistakes, and fix them!

Page 38: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

@implementation SampleClass

- (void)setupAccessibility{ self.myView.accessibilityTraits = UIAccessibilityTraitHeader;}

- (void)dealloc{ [_myString dealloc]; [super dealloc];}

@end

Page 39: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 40: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 41: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

RegEx Lint Rule

AST Lint Rule

NEW

clang

AST

Page 42: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

AST Lint Rules

▪Regular expressions have false positives and negatives

▪ Dot notation vs braces

▪ Even mentioning forbidden API in a comment triggers rule!

▪AST lint rules can “understand the code”

Page 43: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Verify changes: Buildbot

▪Continuous integration

▪Distributed across multiple build machines

▪Sanity check:

▪ Do all projects still build?

▪ Do all unit tests still pass?

▪Emails engineer, and updates Phabricator on failure

Page 44: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Static Analyzer Remote Runs

Page 45: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Buildbot failure email

Page 46: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Builds

Page 47: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Multiple Builds

▪Use different bundle IDs and icons for different types of builds:

▪ Development

▪ Daily Build

▪ App Store release

▪ Special branches

▪Burn your build number into your icon

Page 48: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook
Page 49: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Branching

▪Two concurrent branches:

▪Master

▪ Engineers make progress on future features

▪ All changes checked in here first

▪ …including bug fixes for Releases

▪Release

▪ Once verified in Master…

▪ …“Release team” pulls them into Release branch

Page 50: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Testing

Page 51: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Testing is important to Facebook

▪Not in Facebook’s culture:

▪ SDEs “in Test”

▪ Large QA departments

▪Definitely in Facebook culture:

▪ High quality, reliable user experience

▪We believe in developer-authored unit tests

Page 52: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Snapshot Unit Tests

typedef NS_ENUM(NSUInteger, FBActionStyle) { FBActionStyleUndefined = 0, FBActionStyleDefault = 1, FBActionStyleProminent = 2, FBActionStyleSubdued = 3,}

static NSArray *FBActionGetStyles() { return @[@"DEFAULT", @"PROMINENT", @"SUBDUED"];}

NSString *FBActionStringFromStyleValue(FBActionStyle styleValue) { NSArray *styles = FBActionGetStyles();

if (styleValue < [styles count]) { return [styles objectAtIndex:styleValue]; } else { return nil; }}

typedef NS_ENUM(NSUInteger, FBActionStyle) { FBActionStyleUndefined = 0, FBActionStyleDefault = 1, FBActionStyleProminent = 2, FBActionStyleSubdued = 3,}

NSString *FBActionStringFromStyleValue(FBActionStyle styleValue) { switch (styleValue) { case FBActionStyleDefault: return @”DEFAULT”; case FBActionStyleProminent: return @”PROMINENT”; case FBActionStyleSubdued: return @”SUBDUED”; } return nil;}

Old Code: New Code:

Page 53: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Snapshot Test Case Failures

2013-09-24 17:59:01.743 FBAppKitTestHost[44975:a0b] If you have Kaleidoscope installed you can run this command to see an image diff:ksdiff "/Users/adamjernst/Library/Application Support/iPhone Simulator/7.0/Applications/D85DEF94-79B2-49AB-ABAA-093044D754CF/tmp/FBMegaphoneViewSnapshotTests/[email protected]" "/Users/adamjernst/Library/Application Support/iPhone Simulator/7.0/Applications/D85DEF94-79B2-49AB-ABAA-093044D754CF/tmp/FBMegaphoneViewSnapshotTests/[email protected]"/Users/adamjernst/Documents/fbobjc/Libraries/FBAppKit/FBAppKitTests/FBMegaphoneViewSnapshotTests.m:276: SenTestFailureException: "comparisonSuccess__" should be true. Snapshot comparison failed: Error Domain=FBTestSnapshotControllerErrorDomain Code=4 "Images different" UserInfo=0x7b660230 {NSLocalizedDescription=Images different}:

273 FBMegaphoneStoryView *view = [FBMegaphoneStoryView viewForMegaphone:megaphone target:nil frame:CGRectMake(0, 0, 768, 320)];274 NSString *newIdentifier = identifier.length ? [NSString stringWithFormat:@"%@_pad", identifier] : @"pad";275 [view sizeToFit];276 FBSnapshotVerifyView(view, newIdentifier); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

github.com/facebook/ios-snapshot-test-case

NEW

Page 54: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Watchdog Timer

Main Thread work work work work workwork

Page 55: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Watchdog Timer

Main Thread work work work work workwork

Watchdog Thread

ping ac

k

ping ac

k

ping ac

k

ping ac

k

ping ac

k

ping

Uh oh! No ack.Log backtrace.

Page 56: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Watchdog Timer: How it Works

▪Max-priority thread pings main thread every X seconds

▪ If main thread doesn’t respond in time…

▪ Freeze the main thread

▪ Get the backtrace to see what code is running

▪ Log it to our servers for analysis

github.com/facebook/ios-watchdog-timer

NEW

Page 57: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Rage Shake

▪Shake the device to report a bug

▪Captures:

▪ Screen shot (with annotations!)

▪ Network logs

▪ Last crash log

▪ Last x-seconds of logging

▪ Dumps the view hierarchy

▪Automatically files a bug and sends it to Facebook

Page 58: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Internal Settings

▪Toggle features on and off

▪Change parameters

▪Trigger events

Page 59: "Architecting and testing large iOS apps: lessons from Facebook". Adam Ernst, Facebook

Future of iOS @ Facebook