64
Growing iOS Projects Nicolas Seriot CocoaHeads Lausanne December 2011

Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 2: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Growing iOS ProjectsQuand un projet grandit, quand les spécifications s'étoffent, quand il s'agit de faire évoluer un logiciel ancien, l'estimation des tâches et leur réalisation peuvent devenir extrêmement difficiles. Le projet risque alors de s'enliser et de tomber dans le cercle vicieux des "quick fix", des bugs, des retards et de la baisse de motivation.

Cette présentation discute des principes, techniques et outils qui, au delà d'une bonne connaissance du SDK, permettent d'aborder les changements avec sérénité, d'écrire et surtout conserver un code en bon état, d'effectuer les modifications souhaitées dans les délais estimés.

La présentation traite spécifiquement des projets iOS et espère favoriser une discussion sur les façons de faire de chacun.

- for any developer or project manager- 45 - 60 minutes- difference between small and medium/large projects management- personal approach, what works for me

Page 3: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Complexity

t

- code gets dirtier with time- methods used get deprecated- changes pollute and break the original structure

Page 4: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Complexity

t

hell

- you lose the overall vision- chages become long and difficult- technical debt gets very expensive- estimates become random- fixing a bug yields two other bugs- the project is late- people lose motivation

Page 5: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Complexity

t

hellre-enginering

- avoid full rewrite- assert existing behaviour with unit tests- big refactoring

Page 6: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

audit

hell

Complexity

t

re-enginering

- project gets unusable- audit to save what can be saved- list key components with their state- list dependancies- make priorities

Page 7: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Complexity

t

decisions

Taking the right decisions allow the project to remain manageable.

Page 8: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

A clever person solves a problem.

A wise person avoids it.

- Albert Einstein

How Not to Get There

- but how to avoid troubles?

- keep a clean architecture- use the right tools- test- …

Page 9: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Simplicity

Simplicity is the ultimate sophistication.

- Leonardo da Vinci

Simplicity and elegance are unpopular because they require hard work and discipline to achieve and education to be appreciated.

- Dijkstra

- engineering principle- avoid getting into trouble- minimize costs and risks- not always easy- it’s not because of lazyness nor fear

Page 10: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Keep It Simple, Stupid

- developers often love over-engineerin- because we’re curious- because we love challenges

Page 11: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Good Developers

• know the tools

• know the frameworks

• know the business

• know people

• write good code…

- programming is ubiquitous in science and technology- anybody cannot be a good developer, though

1) Xcode, Instruments, App Store…2) don’t fight the framework, know good practices3) don’t work only for fame, but to fulfill the business needs3) able to anticipate changes, able to say NO4) knows what to expect from people

Page 12: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Good Code

• written for humans

• clean code allow precise estimates

• clean code is it own documentation

• good code in often aesthetic

• browse the framework for consistency

• messy code is costly (bugs, change, …)

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html

good code is good documentation to the reader

Page 13: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Bugs

• bugs should not be written in the first place

• read the code, errors, doc

• concentrate, minimize interruptions

• get a bug tracker

• debugging

• test an hypothesis

- good: start gdb and fix the bug- better: read the code and fix the bug- best: don’t write the bug

Page 14: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Revision Control Systems

• CVS, SVN, Git, Mercurial, …

• they still have to be used properly

• HEAD should always be ready for release

• commit messages, tags

• “leave the place cleaner than you found it”

Page 15: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Agility• ability to move quickly and easily

• best practices formalization, communication

• good process is not a substitute for good people

Success in software is 95% people, 5% process.

A team of highly skilled and highly motivated developers can create a successful project using almost any process... or even no process.

Software processes can enhance a skilled and motivated team. They can't do much if you don't have the talent or motivation in the organization.

Page 16: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Process

correct

clean

fast

start

unit tests refactoring

optimizations

- refactoring should be part of estimates- it’s not just “art for art”- minimize risks and costs- and most importantly keep a maintainable code base

Page 17: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

• always check return status, early return

• always ask yourself: what could go wrong?

A good programmer is someone who looks both ways before crossing a one-way street.

- Doug Linder

Make it Robust

Page 18: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

NSData *data = [NSData dataWithContentsOfFile:path];

NSError

NSError *error = nil;NSData *data = [NSData dataWithContentsOfFile:path options:0 error:&error];if(data == nil) { // deal with error return;}

- the file could be unreadable- the file could be on a very slow network- the file could be 2 GB- the file could be modified by another process

Page 19: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

NSError Creation

NSString *errorDescription = NSLocalizedString(@"file cannot be read", @"");

NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errorDescription forKey:NSLocalizedDescriptionKey];

NSError *error = [NSError errorWithDomain:@"MyFileReader" code:0 userInfo:userInfo];

NSLog(@"-- %@", [error localizedDescription]);

Page 20: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Messaging nil// 1if(price && [price hasConsistentHighLow]) { // deal with price}

// 2if(prices) { for(Price *p in prices) { /* */ }}

// 3[prices addObject:p];

if(p) [prices addObject:p];

Page 21: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Comments

Good code is its own best documentation.

As you're about to add a comment, ask yourself, "How can I improve the code so that this comment isn't needed?"

- Steve McConnell, Code Complete

comments are substitutes for our incapacity to express ourselves in the code

Page 22: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

// compute prices deltadouble delta = price.high - price.low;

// we need delta to ensure data is correctdouble delta = price.high - price.low;

BOOL priceHasConsistentHighLow = price.high >= price.low;

BOOL canSave = [price hasConsistentHighLow];

Comments

1. “what” -> bad2. “why” -> better3. good identifier -> better4. good code -> best

we replaced a bad comment with good code

Page 23: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Keep is Short

• long class > 300 lines

• long method > 15 lines

• minimize states (ivars)

• the goal is maintainability

code has to stay short to be maintainable

Page 24: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Documentation

• A “suitable qualified individual” should be able to understand what / where / why

• Wiki for co-workers

• text files / markdown for technical doc

- documentation should also be short- it’s more about environment- also project philosophy and architecture

Page 25: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Naming Things

Besides a mathematical inclination, a mastery of one's native tongue is the most vital asset of a competent programmer.

- Edsger Dijkstra

Page 26: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Methods Names

insert:at:

insertObject:atIndex:

viewWithTag:

taggedView:

- mutator methods start with a verb- accessor methods start with a nouns

- the last one is unclear because the parameter is not named

Page 27: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Avoid Generic Terms

• Factory, AbstractFactory

• Fooable interface

• Handler, Service

• Manager (except for singletons like NSFileManager, NSFontManager, …)

Page 28: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Unit Tests• document classes usage

• avoid regressions

• help in improving design

• see 2008 CocoaHeads presentation

• OCUnit should be enough

#ifdef UNIT_TESTS block();#else [queue addOperationWithBlock:block];#endif

Page 29: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Other Kind of Tests

• functional tests

• small scenarios (“user stories”)

• beta testers

• OTA distribution is really easy

- how else can you know that a code is a good code ?

Page 30: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

• Working software is the primary measure of progress - Agile manifesto

• Maintenance burden, number of bugs

• Ultimate metrics

• money

• customer’s satisfaction

Metrics

Page 31: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

One of my most productive days was throwing away 1,000 lines of code.

- Ken Thompson

Measuring programming progress by lines of code is like measuring aircraft building progress by weight. - Bill Gates

Page 32: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Lines of Code

• code is an liability, not an asset

• the real goal isto be maintainable before being small

- code is worth the business goal it fulfills- code has a cost, understanding and maintenance- removing code while keeping functionalities is adding value- but not to the detriment of clarity

Page 33: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

$ find . -name "*.m" -print | xargs wc -l | sort

18 ./Classes/NSMutableArray+SQ.m 18 ./Classes/SQKeyValueObject.m 19 ./Classes/NSArray+SQ.m... 723 ./DynamicCharts/PricesContentsView.m 892 ./ManagedObjects/Quote.m 3059 ./ThirdParties/JSONKit/JSONKit.m 18098 total

several ways to count lines of code

Page 34: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

$ cloc.pl . 17 text files. 17 unique files. 1 file ignored.

http://cloc.sourceforge.net v 1.55 T=1.0 s (16.0 files/s, 2839.0 lines/s)-------------------------------------------------------------------------------Language files blank comment code-------------------------------------------------------------------------------Objective C 9 533 361 1581C/C++ Header 7 102 132 130-------------------------------------------------------------------------------SUM: 16 635 493 1711-------------------------------------------------------------------------------

Page 35: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

$ gnuplot loc.gp && open loc.png

http://quickies.seriot.ch/index.php?id=13

Page 36: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Third Party Libraries

• “don't reinvent the wheel”

• except when libraries are buggy…

• ASIHTTPRequest with iOS 5 (5+ kLoc)

• replaced with 300 Loc wrapper

Page 37: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Logging#ifdef DEBUG

#define MyLog(fmt, ...) NSLog((@"%@ [Line %d] %s " fmt), [self class], __LINE__, __FUNCTION__, ##__VA_ARGS__);

#define MyLogError(fmt, ...) NSLog((@"[Error] %@ [Line %d] %s " fmt), [self class], __LINE__, __FUNCTION__, ##__VA_ARGS__);

#else

#define MyLog(fmt, ...)

#define MyLogError(fmt, ...) NSLog((@"[Error] %@ [Line %d] %s " fmt), [self class], __LINE__, __FUNCTION__, ##__VA_ARGS__);

#endif

no need to import external classes

Page 38: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Code Coverage

- find and remove dead code- necessarily dynamic in Objective-C- .gcda and .gcno files

Page 39: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

objc_cover.py

Page 40: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

- (void)notUsed { return;}

- (void)actuallyUsed { return;}

// ...

[self actuallyUsed];

$ python objc_cover.py myBinaryFile # the following methods may be unreferenced-[MyClass notUsed]

Page 41: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Code Duplication

// MyClass.hextern NSString * const kMyString;

// MyClass.mNSString * const kMyString = @"xxx";

Page 42: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Code Duplication

$ find . -name "*.m" -print | xargs sort | uniq -c | sort

...

7 sl.backgroundColor = [UIColor clearColor].CGColor;

12 ![activityIndicator stopAnimating];

13 [ma addObject:[NSNull null]];

...

Page 43: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

objc_strings.py• searches *.m and Localizable.strings

• compares entries

Page 44: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il
Page 45: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il
Page 46: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Concurrency• Always use main thread, except:

• lengthy computations, network access, …

• most of time use main thread for CoreData

- simplify your life every time it’s possible

Page 47: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

- (void)dataWithCompletionBlock:(void (^)(NSData *data))completionBlock errorBlock:(void (^)(NSError *error))errorBlock {

NSOperationQueue *q = [[[NSOperationQueue alloc] init] autorelease];

[q addOperationWithBlock:^{ NSData *theData = nil; NSError *error = nil; // potentially slow access if(theData == nil) { errorBlock(error); return; } completionBlock(theData); }];}

[file dataWithCompletionBlock:^(NSData *data) { // handle data} errorBlock:^(NSError *error) { // handle error}];

Page 48: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Reduce Coupling

1. blocks, when possible (few methods)

2. delegates, good (couple of methods)

3. notifications

4. key-value observing (hard to debug)

Page 49: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Single Responsibility

The only way to write complex software that won’t fall on its face is to build it out of simple modules connected by well-defined interfaces, so that most problems are local and you can have some hope of fixing or optimizing a part without breaking the whole.

The Art of Unix Programming

Page 50: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

objc_dep.py

• directed graph of #import directives

• inter-module dependencies analysis

• understand and improve architecture

• minimize coupling

• enforce MVC

Page 51: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

$ objc_dep.py . > myproject.dotdigraph G {! node [shape=box];! "SearchVC" -> "AllClasses";! "SearchVC" -> "ClassStub";! "SearchVC" -> "ClassCell";! "HTTPRedirectResponse" -> "HTTPLogging";! "HTTPRedirectResponse" -> "HTTPResponse";! "InfoVC" -> "AppDelegate";! "ListTVC" -> "AllClasses";! "ListTVC" -> "ClassStub";! "ListTVC" -> "ClassDisplayVC";! "ListTVC" -> "ClassCell"; ...}

Page 53: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

SearchVC

AllClasses

ClassStub

ClassCell

HTTPRedirectResponse

HTTPLogging HTTPResponse

InfoVC

AppDelegateListTVC

ClassDisplayVC

MethodCell

DDLog

DDASLLogger

ClassDisplay

FrameworkCell

HTTPDynamicFileResponse

HTTPAsyncFileResponse

HTTPConnection

HTTPAuthenticationRequest

HTTPMessage

HTTPDataResponse

GCDAsyncSocket

TreeTVC

DDRange

DDNumber

main

HTTPServer

WebSocket

DDData

FrameworksTVC

ObjectsTVC

MyIP

DDTTYLogger

HTTPFileResponse

DDFileLogger

RuntimeBrowser_Prefix

- blue: double imports- red: imports from .pch

Page 54: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

SearchVC

AllClasses

ClassStub

ClassCell

InfoVC

AppDelegateListTVC

ClassDisplayVC

MethodCellClassDisplay

FrameworkCell

TreeTVC main

CocoaHTTPServer

FrameworksTVC

ObjectsTVC

RuntimeBrowser_Prefix

Page 56: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

SearchVC

AllClassesClassStub

ClassCell

InfoVC

AppDelegate

ListTVC

ClassDisplayVC

MethodCell

ClassDisplay

FrameworkCell

TreeTVC

CocoaHTTPServer

FrameworksTVC

ObjectsTVC

Views

Controllers

NetworkRuntime Browser Logic

- double import- AppDelegate has way too much responsibilities

Page 58: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Runtime Browser Logic

ClassStubClassDisplay

BrowserCell

BrowserNodeAllClasses

AppControllerNSTextView+SyntaxColoring

Controller

View

- BrowserCell should not import BrowserNode

Page 59: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

# number of imports

0 | *********** 1 | ********** 2 | *** 3 | ***** 4 | *** 5 | ** 6 | 7 | 8 | 9 | *10 | 11 | 12 | 13 | *

...

9 | AppDelegate13 | HTTPConnection

# times imported

0 | 1 | ********* 2 | ***** 3 | ****** 4 | ** 5 | *** 6 | 7 | * 8 | *

...

7 | HTTPResponse 8 | HTTPLogging

bonus: stats on stderr

Page 60: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Network

Mac OS X Views

iPhone Controllers

Runtime Browser Logic

Mac OS X Controllers

iPhone Views

Foundation

AppKit UIKit

Page 61: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Recap

• simplicity principle

• tools and techniques

• clear & simple code, design, communication

• make good software

Page 62: Growing iOS Projects - Seriotseriot.ch/resources/talks_papers/growing_ios_projects.pdfGrowing iOS Projects Quand un projet grandit, quand les spécifications s'étoffent, quand il

Conclusion

• frustration is part of the process

• comp. prog. is a craft, a science and an art

• no silver bullet

• sharing ideas which may help in finding solutions

Yes, this is hard. No, you are not stupid.

Aaron Hillegass