Synopsis

This document is for the Objective-C and Objective-C++ coding standards at Appcelerator. As with other coding standards documents, the primary goal is clean, readable code, which is comprable to common existing conventions.

Note that we do not encourage specific design patterns or engineering conventions in this document. This is for source code formatting and other sensible conventions; there is a separate document coming for those issues.

Basis for this document

We attempt to follow the Google coding standards and Apple Cocoa guidelines. The remainder of this document reiterates information from these where appropriate, and otherwise provides exceptions to their standards.

Appcelerator C/C++ standards

You are expected to follow the C/C++ coding guidelines when writing Objective-C except where explicitly specified. These standards take precedence over any generic rules listed in the style guidelines above, although we have our own exceptions.

However, for consistency, any pure-C functions you write in Objective-C source files are to follow the Objective-C rules with C exceptions.

Standards

The following are the standard set of spacing, formatting, and naming conventions we expect for Objective-C(++) code.

#import vs. #include

Always #import Objective-C headers, and #include C (or C++) headers.

@class

Prefer the usage of #import over @class to ensure that proper dependencies are included in the implementation.

Class naming

@interface TiExampleClass : NSObject {
// ivars
}

// properties

// methods

The @interface directive should not be indented, and neither should @property or method declarations.

Protocols

Protocols follow the same naming conventions as classes, with the following exceptions:

@protocol TiScrolling; // Gerund; behavior type is "this object scrolls"
@protocol TiFocusable; // Action set; describes actions related to "focusing" and "TiFocusing" seems inappropraite ("this object focuses" vs. "this object performs actions related to focusing")
@protocol TiScrollViewDelegate; // Delegate

Protocols must always include the @required directive explicitly.

Category naming

Header files which define an interface for a category only should be named <base class>+<category>.h.

ivars

Instance variables for a class should be intended one tabstop.

Instance variables should be named in camelcase, and are not required to follow any other specific naming convention. We do recommend that ivars end with an underscore character, and are accessed through property getters rather than directly if possible. The only punctuation considered acceptable in an ivar name is a trailing underscore.

@public, @protected, and @private

Use of access specifiers is discouraged at this time (use publicly-declared and private-category @property instead). In the case that they are used in a class, or this rule is changed, follow the C++ ordering convention of:

Where the access specifier is not indented (aligned at column 0).

@property and @synthesize

All ivars which are intended to be publicly accessed must have a @property declaration to go with them, which must include nonatomic explicitly if on iOS (optional if on OS X, since not everything needs to be nonatomic there), and either readonly or a storage specifier.

ivars which require @property accessors for internal usage only can have these properties declared as part of a private category.

Naturally every @property is required to have a @synthesize, unless all accessors for it are overloaded. If you write an overloaded setter for a @property you are required to follow the access specifier declared for it.

Methods

+(void)x:(int)y
{
}

-(void)veryLongMethodName:(NSObject*)veryLongArgumentName
                     arg2:(NSObject*)anotherArg
                     arg3:(NSObject*)moreArg
{
}

init

-(id)init
{
    if (self = [super init]) {
        // here...
    }
    return self;
}

Note the single braces. You may wish to turn off the "initializer not fully bracketed" clang warning in Xcode as a result.

Blocks

typedef int ^(intBlock)(int);

intBlock foo = ^(int foo) {
    return 2*foo;
};

Fast enumeration (for x in y)

Prefer fast enumeration loops to other looping constructs where possible. Note that if y is a method call, the result of it should be pre-cached. Do not write fast enumeration loops which would modify y (whether an object or a method call) as a side-effect of the loop contents.

Objective-C++

All of the rules for Objective-C apply to Objective-C++ as well.

The only formal rule we have regarding Objective-C++ at this time is that you should intend to avoid using it. Unless your source explicitly includes or references C++ classes, or must make use of a C++ header that is not extern "C" (which should never, ever happen - that is a bug in the C++ header) you should not tag your file with the .mm extension - this prevents useful XCode features such as refactoring (XCode refuses to refactor C++ code, wisely) and increases compilation time (a C++ compiler must be invoked instead of a C compiler).

To reiterate: Do not use Objective-C++ file designators unless you are absolutely certain the code you have written is in Objective-C++, and cannot be compiled by a C compiler. It leads to very serious bugs that only show up during linking.

File names

The following file names are acceptable for Objective-C:

@implementation ordering

Methods should be ordered in @implementation in the following way:

The protocol implementation sections may be repeated as necessary.

nil and NULL

BOOL types

BOOL types should only be assigned to from YES, NO, or an explicit boolean operation. Do not mix BOOL types with C++ boolean or the C macros TRUE and FALSE - doing so may lead to subtle comparator errors for truth.

Exceptions to the C standard

There are a number of exceptions to the C standard, to make our Objective-C code more compatible with existing source and follow standard conventions. Any C code which is written within an Objective-C source file (.m) must also follow these conventions, for readability purposes.

Comments

Order of declarations

Rather than namespace-contents, the basic block for an Objective-C header is objc-contents:

The following is the order of declarations for an Objective-C or Objective-C++ header:

Braces

Rather than spacing a brace on a newline in C, in Objective-C there are some cases in which an opening brace is placed on the same line as the preceding statement, with a space before it:

Variables

All variables are named in camel-case and should not contain punctuation.

Exceptions to the C++ standard

There are no exceptions to the C++ standard at this time.

Other Rules

3rd party libraries

As with all other source, the style in 3rd party libraries should be consistent with the style there rather than any Appcelerator coding standards. This holds true even for extensions we write to them.

Deprecated classes and methods

Avoid the usage of deprecated methods from standard frameworks where an alternative is available, unless it breaks backwards compatibility with a version of software that we support.

@compatibility_alias

Do not use the @compatibility_alias directive unless it is explicitly required due to a conflict between external libraries to a project, or multiple internal versions required by different 3rd party libraries.

#pragma mark

Use #pragma mark liberally to annotate sections of your code where necessary, in addition to the rules spelled out above.