Skip to content

Commit

Permalink
Add iOS and Objective-C to existing guides
Browse files Browse the repository at this point in the history
* Add iOS to Best Practices
* Add iOS to Style Guidelines
* Add iOS to Protocol
* Add sample Objective-C code
  • Loading branch information
hyperspacemark committed Oct 15, 2012
1 parent c4bd004 commit d4809ea
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 8 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ Guides for getting things done, programming well, and programming in style.
* [Best Practices](/thoughtbot/guides/blob/master/best-practices)
* [Style](/thoughtbot/guides/blob/master/style)

A note on the language:

* "Avoid" means don't do it unless you have good reason.
* "Don't" means there's never a good reason.
* "Prefer" indicates a better option and its alternative to watch out for.
* "Use" is a positive instruction.

Credits
-------

Expand Down
6 changes: 6 additions & 0 deletions best-practices/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,9 @@ Browsers

* Don't support clients without Javascript.
* Don't support IE6.

Objective-C
-----------

* Prefer categories on `Foundation` classes to helper methods.
* Prefer string constants to literals when providing keys or key paths to methods.
37 changes: 37 additions & 0 deletions protocol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ A guide for getting things done.
Set up laptop
-------------

Install the latest version of Xcode from the App Store.

Set up your laptop with [this script](/thoughtbot/laptop)
and [these dotfiles](/thoughtbot/dotfiles).

Expand All @@ -20,6 +22,41 @@ Create the app.

suspenders app --heroku true --github organization/app

Create iOS app
--------------

Create a new project in Xcode with these settings:

* Check 'Create local git repository for this project'.
* Check 'Use Automatic Reference Counting'.
* Set an appropriate 2 or 3 letter class prefix.
* Set the Base SDK to 'Latest iOS'.
* Set the iOS Deployment Target to 5.0.
* Use the Apple LLVM compiler.

Add a `.gitignore` file with contents:

*~
*~.nib/
*.dat
*.dep
*.hmap
*.LinkFileList
*.mode1
*.mode1v3
*.mode2v3
*.o
*.pbxuser
*.perspective
*.perspectivev3
*.xcworkspace
build/
xcuserdata

Add a `.gitattributes` file with contents:

*.pbxproj binary merge=union

Set up Rails app
----------------

Expand Down
38 changes: 30 additions & 8 deletions style/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ High level guidelines:
* Don't rewrite existing code to follow this guide.
* Don't violate the conventions without a good reason.

A note on the language:

* "Avoid" means don't do it unless you have good reason.
* "Don't" means there's never a good reason.
* "Prefer" indicates a better option and its alternative to watch out for.
* "Use" is a positive instruction.

Git
---

Expand Down Expand Up @@ -77,7 +70,7 @@ CoffeeScript

* Initialize arrays using `[]`.
* Initialize empty objects and hashes using `{}`.
* Use `CamelCase` for classes, `mixedCase` for variables and functions,
* Use `CamelCase` for classes, `lowerCamelCase` for variables and functions,
`SCREAMING_SNAKE_CASE` for constants, `_single_leading_underscore` for
private variables and functions.

Expand Down Expand Up @@ -176,3 +169,32 @@ Testing
* Use an `it` example for each execution path through the method.
* Use one factories.rb file per project.
* Use [stubs and spies](http://goo.gl/EciDJ) (not mocks) in isolated tests.

Objective-C
-----------

[Sample](/thoughtbot/guides/blod/master/style/samples/ObjectiveC.m)

* `#import` linked frameworks in the prefix header (`ProjectName-Prefix.pch`).
* Keep `.xib` files grouped with their associated view class.
* Order `#import` statements alphabetically.
* Order `@class` directives alphabetically.
* Order `@property` modifiers: memory management, atomicity, writability.
* Organize classes into `models`, `views`, `controllers`, `categories`,
and `services` directories.
* Prefer `@class` to `#import` when referring to external classes in a public
`@interface`.
* Prefix class names with a 2-letter project acronym.
* Remove `#import` statements for `Foundation` and `UIKit` in new project
templates.
* Separate methods by function using `#pragma mark - <Section Name>`
* Separate sections into subsections using `#pragma mark <Subsection Name>`
* Write methods using the happy path. Indent the exceptional cases. Keep the
optimal case in the left-most column.
* Use `@interface ClassName ()` to declare private properties.
* Use `lowerCamelCase` for method names.
* Use `NSAssert` in methods that require the presence of certain arguments.
* Prefer `@property` to declaring instance variables.
* Prefix string constants being used as keys with 'k'.
* Use `@[arrayObject]`, `@{@"key" : value}`, `@(YES or NO)`, and `@5.0`
literals.
71 changes: 71 additions & 0 deletions style/samples/ObjectiveC.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#import "Alpha.h"
#import "Beta.h"

// Use @interface extensions for private properties
@interface ClassName () <Protocols>

// Keep @properties grouped together by function
@property (strong, nonatomic) IBOutlet UISearchBar *searchBar;
@property (strong, nonatomic) IBOutlet UITableView *tableView;

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;

@property (strong, nonatomic, readonly) TBObject *someObject;

@end

// Use static NSString points to consts for string constants
static NSString *const ConstantName = @"Constant";

// Prepend constants with 'k' when being used as keys
static NSString *const kFirstName = @"FirstName";

@implementation ClassName

/*
- Use #pragma mark to organize code by function
- Use descriptive names for #pragma mark
- Use class names if overriding or implementing protocol methods
*/
#pragma mark - Initialization

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];

// Return early if conditions prohibit the intended function of the method
// Use conditionals for exceptional cases
// Keep the 'optimal' path non-indented
if (!self)
return nil;

return self;
}

#pragma mark - UI

// Opening brackets belong on the next line
- (void)shuffleCards
{
// Objective-C literals are your friend
NSDictionary *themeColors = @{ kRedColor : [UIColor redColor], kBlueColor : [UIColor blueColor] };
NSArray *robots = @[ @"Ralph", @"Bender", @"The Iron Giant" ];

NSMutableArray *deckOfCards = [NSMutableArray arrayWithCapacity:52];

// Newlines before and after conditional blocks
for (Card *card in deckOfCards)
NSLog(@"%@", [card description]);

Card *jokerCard = [Card joker];
[deckOfCards addObject:jokerCard];

// Use ! to check for nots. Comparing to 'nil' is redundant
if (![creditCard isValid])
{
//...
}
}

@end

0 comments on commit d4809ea

Please sign in to comment.