Wikimedia Apps/Team/iOS/ObjectiveCStyleGuide

In addition to the guidelines below, you can find the current canonical examples of our coding style in the WMFCodingStyle.h and WMFCodingStyle.m files.

Influences
Here are some of the documents that informed the style guide. If something isn't mentioned here, it's probably covered in great detail in one of these:


 * The Objective-C Programming Language
 * Cocoa Fundamentals Guide
 * Coding Guidelines for Cocoa
 * iOS App Programming Guide
 * CocoaDevCentral Style Guide Part 1 and Part 2
 * Luke Redpath Style Guide
 * Github Style Guide

Dot-Notation Syntax
Dot-notation should always be used for accessing and mutating properties. Bracket notation is to be used in all other instances.

For example:

Not:

Using dot-notation for instance methods is not encouraged, but is OK if they are cheap and pure, meaning there's little-to-no processing and absolutely zero side effects. Some examples of instance methods which are acceptable to call using dot notation are:,  ,  , etc...

Spacing

 * Indent using 4 spaces. Never indent with tabs. Be sure to set this preference in Xcode.
 * Method braces and other braces ( / / / etc.) always open on the same line as the statement but close on a new line.
 * Configure Xcode to automatically trim trailing whitespace in the Editing preferences.

For example:
 * There should be exactly one blank line between methods to aid in visual clarity and organization. Whitespace within methods should separate functionality, but often there should probably be new methods.
 * and  should each be declared on new lines in the implementation.

Conditionals
Conditional bodies should always use braces even when a conditional body could be written without braces (e.g., it is one line only) to prevent errors. These errors include adding a second line and expecting it to be part of the if-statement. Another, even more dangerous defect may happen where the line &quot;inside&quot; the if-statement is commented out, and the next line unwittingly becomes part of the if-statement. In addition, this style is more consistent with all other conditionals, and therefore more easily scannable.

For example:

or

Not:

or

Golden Path
When coding with conditionals, the left hand margin of the code should be the "golden" or "happy" path. That is, don't nest   statements. Multiple return statements are ok.

For example:

Not:

Ternary Operator
The Ternary operator, ? , should only be used when it increases clarity or code neatness. A single condition is usually all that should be evaluated. Evaluating multiple conditions is usually more understandable as an if statement, or refactored into instance variables.

For example:

or, you can use the  operator to simplify ternary statements into a style similar to Ruby and Javascript's   operator behavior:

Not:

Error handling
When methods return an error parameter by reference, switch on the returned value, not the error variable.

For example:

Not:

Some of Apple’s APIs write garbage values to the error parameter (if non-NULL) in successful cases, so switching on the error can cause false negatives (and subsequently crash).

Declaration
In method signatures, there should be a space after the scope (-/+ symbol). There should be a space between the method segments, but not between method arguments and their preceding colon.

For Example:

 Not: 

Definition
Method definitions should follow the same indentation rules as declaration, with the opening curly brace on the last line of the method signature:

Variables
Variables should be named as descriptively as possible. Single letter variable names should be avoided except in  loops.

Asterisks indicating pointers belong with the variable, e.g.,  not   or. This is especially important when using the  qualifier, as   (constant pointer to  ) is not the same as   (pointer to a constant  ). Note how the variables and their types are read from right to left.

Property definitions should be used in place of naked instance variables unless there is an extremely good reason. If you need to make your variables private, use an anonymous category as outlined in the section on private properties.

Direct instance variable access should be avoided except in initializer methods (, , etc…),   methods and within custom setters and getters. For more information on using Accessor Methods in Initializer Methods and dealloc, see here.

should not be written out explicitly unless you need to override the default instance variable name.

For example:

Not:

Block types
Types of blocks should be defined using a, so that the type can be easily referenced in other places. Like constants, you should define your blocks as close to the code where they are used, like in the header of the class that uses them. Block definitions should also omit their return type when possible as well as their arguments when they are void. Block arguments should always be declared in the.

For example:

Not:

Block parameters
Block parameters should always be named so that they are filled in on autocomplete (Developers can rename the variables when using the block if they choose).

For example:

Not:

Block as arguments
Block arguments should always be the last arguments for a method.

For example:

Block properties
NOTE: This needs to be investigated, as Objective-C block implementation might already handle copy-on-retain. Blocks should always be copied when used outside the lexical scope in which they are declared, e.g. asynchronous completion blocks. This goes for storage in a property or in a collection (i.e.,  , etc.).

Protocols
Unless a good reason is given, all protocol methods should be  (the default). Single method protocols are always. Use  sparingly to prevent from having to sprinkle   throughout your code.

Protocols can be defined in their own header, or in the header of the class that requires that protocol. Typically delegates should follow the later pattern.

An example of a Delegate protocol:

Protocols should always inherent from the NSObject protocol. The first parameter in a protocol method should be the object calling the protocol method:

Naming Delegate Protocols
Delegate protocols should always be named in &quot;notification&quot; style. &quot;…didUpdate…&quot;, &quot;…willChange…&quot;, &quot;…shouldChange…&quot;

Categories
Categories should be named for the sort of functionality they provide. Try not to create umbrella categories. They should also be prefixed:

Categories are also useful for removing methods that subclasses require out of the public interface:

Always name your category files as the &quot;Class+CategoryName&quot;:

Category instance methods should always have a prefix (similar to classes) to prevent name collisions. For example, we'll be using  to prefix our categories on platform API classes.

ARC
ARC should be enabled for all new projects. All existing projects should be converted to ARC as soon as possible.

Naming
Apple naming conventions should be adhered to wherever possible, especially those related to memory management rules (NARC).

Long, descriptive method and variable names are good.

For example:

Not

A 2-4 letter prefix (e.g. ) should always be used for class names and constants. Constants should be camel-case with all words capitalized and prefixed by the related class name for clarity.

For example:

Not:

Properties and local variables should be camel-case with the leading word being lowercase.

Instance variables should be camel-case with the leading word being lowercase, and should be prefixed with an underscore. This is consistent with instance variables synthesized automatically by LLVM. If LLVM can synthesize the variable automatically, then let it.

For example:

Public Interfaces
Your class interfaces should ONLY contain methods and properties that need to be exposed publicly. All other code should be in the implementation file.

All methods and properties should be clearly named (you were doing that all ready, no?), and commented so that documentation can be generated automatically.

Comments
In general, code should be self-documenting. Comments should be used when necessary for clarity. Here are a few specific situations:

Class Interfaces
Always include a high level description in a block comment at the top of the header file. What the class is used for, Why you may use it, etc…

All methods and properties should be clearly named, as mentioned above. However, you should also add Java style comments to be used to generate documentation. The easiest way to do that is to use the VVDocumenter Xcode plugin.

In addition to the parameters and return values, each method and property should be documented with any default values or behavior that the user must understand to use the API.

Method Implementations
In general, implementations should not include comments. Block comments should generally be avoided, as code should be as self-documenting as possible, with only the need for intermittent, few-line explanations.

When they are needed, comments should be used to explain why a particular piece of code does something. Any comments that are used must be kept up-to-date or deleted.

An example may be a complex algorithm that cannot be broken up easily (something like JSON parsing, or other complex math or logic).

init and dealloc
methods should be structured like this:

Only implement dealloc if required. For instance, when unsubscribing from notifications.

Literals
,,  , and   literals should be used whenever creating immutable instances of those objects. Pay special care that  values not be passed into   and   literals, as this will cause a crash.

For example:

Not:

CGRect Functions
When accessing the,  ,  , or   of a  , always use the functions instead of direct struct member access. From Apple's  reference:

All functions described in this reference that take CGRect data structures as inputs implicitly standardize those rectangles before calculating their results. For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics. For example:

Not:

Constants
Constants should be kept in the classes/files in which they are used for easy reference. You should not create a &quot;Constants&quot; file and use it as a junk drawer for all constants in the app. For instance, if you define a notification, that should be defined in the header of the class posting the notification.

Constants are preferred over in-line string literals or numbers, as they allow for easy reproduction of commonly used variables and can be quickly changed without the need for find and replace. Constants should not be declared using. Instead, use the  qualifier within your implementation file, or   for public constants in the header.

For example:

Not:

Enumerated Types
When using s, it is recommended to use the new fixed underlying type specification because it has stronger type checking and code completion. The SDK now includes a macro to facilitate and encourage use of fixed underlying types —

Example:

Bitmasks
When working with bitmasks, use the  macro.

Example:

Private Properties
Private properties should be declared in class extensions (anonymous categories) in the implementation file of a class. Named categories (such as  or  ) should never be used unless extending another class.

For example:

Booleans
Since  resolves to   it is unnecessary to compare it in conditions. Never compare something directly to, because   is defined to 1 and a   can be up to 8 bits.

This allows for more consistency across files and greater visual clarity.

For example:

Not:

-

For a, here are two examples:

Not:

-

If the name of a  property is expressed as an adjective, the property can omit the “is” prefix but specifies the conventional name for the get accessor, for example:

Text and example taken from the [|Cocoa Naming Guidelines].

Singletons
Singleton objects should use a thread-safe pattern for creating their shared instance. Unless there is a reason, singleton methods should always be named  so that classes with singletons are easy to identify.

This will prevent possible and sometimes prolific crashes.

Image Naming and Asset Catalogs
Images should be placed in the asset catalog in all new projects.

Image names should be named consistently to preserve organization and developer sanity. They should be named as one camel case string with a description of their purpose, followed by the un-prefixed name of the class or property they are customizing (if there is one), followed by a further description of color and/or placement, and finally their state.

For example:


 * /  and   /
 * /  and   /.

Do your best to communicate these standards to the designer slicing the artwork. Even still, images sliced by the designer might not conform to our standards. If this is the case, you can just change the name in the asset catalog **WITHOUT* changing the file name. That way when your slices are updated, you don't have to rename them again.

Header Files
Header files should only ever declare the public interface. Private/protected methods should be contained in class continuations inside the implementation file.

Use the @class directive to forward declare classes referenced in the header instead of importing header files. This prevents compile time issues.

Order of Content

 * Each header file should contain the following in this order:
 * Class/Header imports
 * declarations
 * External constants (e.g. NSNotification constants)
 * External Function Declarations
 * Structs / Enums
 * Class Delegate Protocols Declarations
 * Class Interface
 * Class Categories
 * Class Delegate Protocols

Grouping of Methods and Properties
Methods and properties should be grouped in a sensical way according to function. Not required, but using #pragma marks to group sections for large header files increases readability. Common groupings are Initialization, configuration, etc…

Implementation Files
Within an implementation, all methods should be logically grouped using #pragma marks, including protocol implementations. This allows faster code navigation in Xcode.

Do not forward declare methods at the top of the file, this no longer necessary with the latest versions of Xcode.

Do use the anonymous category for any &quot;private&quot; properties.

Order of Content

 * Class/Header Imports
 * Constants (e.g. NSNotification constants)
 * Function Implementations
 * Anonymous Class Category (for private properties)
 * Class Implementation
 * Class Categories

Grouping and order of class Implementation

 * @synthesize / @dynamic (only if required)
 * dealloc
 * init methods
 * class methods
 * accessors
 * subclass overides
 * other groups (including logical functional areas and protocol implementations)

Directory Structure
All code files (including header, implementation, nibs, and storyboards) should be kept in a directory called &quot;Source&quot;. You should not divide these files into subdirectories. This does make the project &quot;less browsable&quot; in the finder and command line, but increases flexibility when moving files between groups in Xcode - which is where most developers interact with the source files. Trying to keep Xcode groups in sync with actual file system directories is not worth the hassle.

Xcode Project
The organization of files should happen in the Xcode Project file. Your groups should make it easy to find your code and the names should be descriptive to the reader. Consider your project organization to be part of your documentation.

Groups
Structure the Project with the following top level groups:


 * Source (or &quot;App Name&quot;)
 * Application
 * UI
 * Tests
 * Dependencies
 * Frameworks

Within each folder, code should be grouped not only by type, but also by feature for greater clarity.

Application
Place the app delegate, info plist, global.h/.m, prefix-header and any other application level files within the Application Folder (functions, macros).

UI
Place all view controllers, story boards, nibs, asset catalogs and view classes within the UI group. This also includes any UI specific categories or protocols. Group UI sources according "Scenes", and "Flows" - this will map closely to view controllers, but this is a higher level abstraction and groups may include multiple view controllers. Group common code (used across several view controllers / flows) in a &quot;Common&quot; of "Shared" group and further subdivide that into specific areas (cells, controls, collection view layouts, transitions, etc…). If a view is only used by one view controller, it should NOT be placed in the &quot;Common&quot; group.

Other Top Level Groups
Group all non-UI classes functionally. This includes all models, model controllers, network controllers, categories and protocols. Group according to function. Place any non-application specific external classes within this group.