> ## Content Index
> Fetch the complete content index at: https://williamboles.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Objective-C Coding Style Guide
- URL: https://williamboles.com/objective-c-coding-style/
- Published: 2015-12-22T13:40:00.000Z
- Updated: 2026-09-26T09:05:23.000Z
- Description: Everyone has a view on how to style code. None of that matters. What matters is that, as a team, you agree on the most important styles to enable developers to feel a sense of familiarity when navigating the project, regardless of who wrote the code. Here, we look at some style rules.
- Author: William Boles
- Tags: Teamwork, Code Style

I made this style guide to keep the code in my projects similar and allow for easier movement between projects.

One of my key aims is to create projects that are easy to understand from the developers' point of view, so I often favour verboseness when it ensures that the true meaning of what we are attempting is more clearly expressed.

## Table of Contents

- [Language](#language)
- [Code Organization](#code-organization)
- [Braces](#braces)
- [Naming](#naming)
- [Types](#types)
- [Images](#images)
- [Prefixing](#prefixing)
- [Parentheses](#parentheses)
- [Properties](#properties)
- [Instance variables](#instance-variables)
- [Methods](#methods)
- [Protocols](#protocols)
- [Variables](#variables)
- [Dot-Notation Syntax](#dot-notation-syntax)
- [Literals](#literals)
- [Constants](#constants)
- [Enumerated Types](#enumerated-types)
- [Case Statements](#case-statements)
- [Private Properties](#private-properties)
- [Booleans](#booleans)
- [Conditionals](#conditionals)
- [Ternary Operator](#ternary-operator)
- [Init Methods](#init-methods)
- [Class Constructor Methods](#class-constructor-methods)
- [Class Cleanup Methods](#class-cleanup-methods)
- [Happy Path](#happy-path)
- [Error handling](#error-handling)
- [Singletons](#singletons)
- [Line Breaks](#line-breaks)
- [Magic strings](#magic-strings)
- [Warnings](#warnings)
- [Xcode project](#xcode-project)
- [Autolayout vs Frames](#autolayout-vs-frames)
- [Button Action](#button-action)
- [Predicate Format](#predicate-format)
- [Relationship Inverse](#relationship-inverse)
- [Parentheses in mathematical operations](#parentheses-in-mathematical-operations)

## Language

US English should be used.

**Preferred:**

```objc
UIColor *myColor = [UIColor whiteColor];

```

**Not Preferred:**

```objc
UIColor *myColour = [UIColor whiteColor];

```

## Code Organisation

Use `#pragma mark -` to categorise methods in functional groupings and protocol/delegate implementations following this general structure.

The descriptor of the pragma mark should be capitalised and use camel casing.

If needed, you can create sub-groups under a single group by `#pragma mark`

**Preferred:**

```objc
#pragma mark - ButtonActions

#pragma mark NavigationButtonActions

```

**Not Preferred:**

```objc
#pragma mark - butttonActions
#pragma mark - buttton actions

#pragma mark - NavigationButtonActions

```

## Braces

Braces should appear on a newline.

**Preferred:**

```objc
if (user.isHappy)
{
    //Do something
}
else
{
    //Do something else
}

```

**Not Preferred:**

```objc
if (user.isHappy) {
  //Do something
} else {
  //Do something else
}

```

This is especially true for blocks

**Preferred:**

```objc
[UIView animateWithDuration:1.0 animations:^
{
  // something
}
				 completion:^(BOOL finished)
{
  // something
}];

```

**Not Preferred:**

```objc
[UIView animateWithDuration:1.0 animations:^{
  // something
} completion:^(BOOL finished) {
  // something
}];

```

## Naming

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

Long, descriptive method and variable names are good; remember, you are developing this app to be maintained.

**Preferred:**

```objc
UIButton *settingsButton;

```

**Not Preferred:**

```objc
UIButton *setBut;
UIButton *buttonSettings;

```

## Types

`NSInteger` and `NSUInteger` should be used instead of `int`, `long`, etc, per Apple's best practices and 64-bit safety. `CGFloat` is preferred over `float` for the same reasons.

All Apple types should be used over primitive ones. For example, if you are working with time intervals, use `NSTimeInterval` instead of `double` even though it is synonymous.

## Images

Images should be used within **xcassets** resource bundles.

The naming of each individual should follow the same naming conventions as the naming of methods and variables, with the exception that, rather than using camel casing, a "-" should be used to separate different words

**Preferred:**

```objc
background-request-empty

```

**Not Preferred:**

```objc
backgroundRequestEmpty

```

## Prefixing

A three-letter prefix should always be used for all class names, category names, category methods and externs.

**Preferred:**

```objc
WBSLoadingView //class
UIView+UCCFrame //category
ucc_frameMethod //category method
WBSLoggedNotification //extern

```

**Not Preferred:**

```objc
LoadingView //class
UIView+Frame //category
frameMethod //category name
LoggedNotification //extern

```

## Parentheses

There should be no spaces between parentheses and their contents.

**Preferred:**

```objc
if(count == 1)
{
}

```

**Not Preferred:**

```objc
if( count == 1 )
{
}

```

## Properties

Properties should be camel-case with the leading word being lowercase. Use auto-synthesis for properties rather than manual @synthesize statements unless you have a good reason.

**Preferred:**

```objc
@property (nonatomic, strong) NSString *postName;

```

**Not Preferred:**

```objc
@property (nonatomic, strong) NSString *PostName;

```

Attributes on a property should always be explicitly listed.

Properties with mutable counterparts (e.g. NSString) should prefer `copy` instead of `strong`.

**Preferred:**

```objc
@property (nonatomic, copy) NSString *postName;

```

**Not Preferred:**

```objc
@property (nonatomic, strong) NSString *postName;

```

The ordering of a property declaration should follow:

**Preferred:**

```objc
@property (nonatomic, assign, getter=isPostRead) BOOL postRead;
@property (nonatomic, strong, readonly) BOOL postName;
@property (nonatomic, strong, readwrite) BOOL postStatus;

```

**Not Preferred:**

```objc
@property (assign, getter=isPostRead, nonatomic) BOOL *postRead;
@property (nonatomic, readonly, strong) BOOL postName;
@property (nonatomic, strong, readwrite) BOOL postStatus;

```

If you need to use @synthesize then ensure that you use an underscore in front of the instance variable declaration.

@synthesize declarations should appear directly below the @implementation statement.

**Preferred:**

```objc
@synthesize post = _post;

```

**Not Preferred:**

```objc
@synthesize post = iPost;

```

Properties in the header should **always** be immutable.

If the property should only be initialised in the container class, then it should be exposed as **readonly** and overridden in the class extension to allow read-write access.

## Instance variables

Instance variables should only ever be accessed within a custom getter/setter of the property or the init method of the class. When outside of these scopes the instance variable's property should be used.

**Preferred:**

```objc
- (void)jamFound
{
	self.jamSearchStatus = @"Jam found!";
}

```

**Not Preferred:**

```objc
- (void)jamFound
{
	_jamSearchStatus = @"Jam found!";
}

```

## Methods

In method signatures, there should be a space after the method type (-/+ symbol). There should be a space between the method segments (matching Apple's style). Always include a keyword and be descriptive with the word before the argument which describes the argument.

The usage of the word "and" is reserved. It should not be used for multiple parameters, as illustrated in the `initWithWidth:height:` example below.

**Preferred:**

```objc
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

```

**Not Preferred:**

```objc
-(void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth: (CGFloat)width andHeight: (CGFloat)height;
- (instancetype)initWith:(int) width and:(int) height;

```

All methods should be declared either in the header of the class or in the class extension.

Each method in the implementation of the class should be separated by a new line space between other methods, pragma marks, etc.

Unless in exceptional circumstances, a method should only have one return statement.

When calling a method that accepts parameters, there should be no space between the ":" and the parameter passed in.

**Preferred:**

```objc
[self sendAction:action];

```

**Not Preferred:**

```objc
[self sendAction: action];

```

## Variables

Variables should be named as descriptively as possible. Single-letter variable names should be avoided.

Asterisks indicating pointers belong with the variable, e.g., `NSString *text`, not `NSString* text` or `NSString * text`, except in the case of constants.

**Preferred:**

```objc
for(NSUInteger index = 0, index < [self.items count]; index++)
{
}

```

**Not Preferred:**

```objc
for(NSUInteger i = 0, i < [self.items count]; i++)
{
}

```

There should be no spaces between parentheses and their contents.

## Protocols

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

Protocols which reference a behaviour type should end with a gerund (-ing).  
Protocols which describe a set of actions should describe the functional property of these collective actions.  
Protocols which are a delegate should end with the word Delegate.

```objc
@protocol WBSScrolling; // Gerund; behavior type is "this object scrolls"
@protocol WBSFocusable; // Action set; describes actions related to "focusing" and "WBSFocusing" seems inappropriate ("this object focuses" vs. "this object performs actions related to focusing")
@protocol TiScrollViewDelegate; // Delegate

```

When relating to only one class, protocols should be defined above the implementation of the class, in the class's header.

When used by more than one class, the protocol should be split out and defined within its own class.

Any methods that are optional within a protocol should be marked as such using the @optional keyword. Any class that implements a protocol **must** implement all non-optional methods.

When calling an optional method on a protocol's implementation, a check should always be performed to ensure that the method is implemented.

```objc
if([self.delegate respondsToSelector:@selector(allHeaderFields)])
{
}

```

When a method is non-optional, the above check should **not** be performed; it is preferable for the app to crash and immediately inform the developer of their error.

If a method is moved between optional and non-optional, it is the developer who made that decision responsibly to ensure that all classes that implement this protocol are updated.

## Dot-Notation Syntax

Dot syntax is purely a convenient wrapper around accessor method calls. When you use dot syntax, the property is still accessed or changed using getter and setter methods. Read more [here](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html?ref=williamboles.com)

Dot-notation should **always** be used for accessing and mutating properties, as it makes code more concise. Bracket notation is preferred in all other instances.

**Preferred:**

```objc
NSInteger arrayCount = [self.array count];
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;

```

**Not Preferred:**

```objc
NSInteger arrayCount = self.array.count;
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;

```

## Literals

`NSString`, `NSDictionary`, `NSArray`, and `NSNumber` literals should be used whenever creating immutable instances of those objects. Pay special care that `nil` values can not be passed into `NSArray` and `NSDictionary` literals, as this will cause a crash.

The items for a `NSDictionary` should each be on a new line.

**Preferred:**

```objc
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{
    @"iPhone": @"Kate",
    @"iPad": @"Kamal",
    @"Mobile Web": @"Bill"
  };
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingStreetNumber = @10018;

```

**Not Preferred:**

```objc
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingStreetNumber = [NSNumber numberWithInteger:10018];

```

## Constants

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 be declared as `static` constants and not `##define`s unless explicitly being used as a macro.  
This behaviour applies to literals or numbers which are used more than once in a class; single occurrences are best used in line.

**Preferred:**

```objc
static NSString * const kKeyForImage = @"imageKey";

static CGFloat const kImageThumbnailHeight = 50.0f;

```

**Not Preferred:**

```objc
##define kKeyForImage @"imageKey"

##define thumbnailHeight 50.0

```

If a const will be present in the header file, it **must** be an extern (externs don't use the "k" prefix but rather use the project's three-character prefix, e.g. "WBSKeyForImage").

## Enumerated Types

When using `enums, 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: `NS\_ENUM()\`

**For Example:**

```objc
typedef NS_ENUM(NSInteger, WBSLeftMenuTopItemType)
{
  WBSLeftMenuTopItemTypeMain,
  WBSLeftMenuTopItemTypeShows,
  WBSLeftMenuTopItemTypeSchedule
};

```

You can also make explicit value assignments:

```objc
typedef NS_ENUM(NSInteger, WBSGlobalConstants)
{
  WBSGlobalConstantsPinSizeMin = 1,
  WBSGlobalConstantsPinSizeMax = 5,
  WBSGlobalConstantsPinCountMin = 100,
  WBSGlobalConstantsPinCountMax = 500,
};

```

Older k-style constant definitions should be **avoided** unless writing CoreFoundation C code (unlikely).

**Not Preferred:**

```objc
enum GlobalConstants
{
  kMaxPinSize = 5,
  kMaxPinCount = 500,
};

```

## Case Statements

Braces are required for case statements, unless enforced by the complier.

**Preferred:**

```objc
switch (condition)
{
  case 1:
  {
    // ...
    break;  
  }
  case 2:
  {
  	// ...
    break;
  }
  default:
  {
    break;
  }
}

```

**Not Preferred:**

```objc
switch (condition)
{
  case 1:
    // ...
    break;
  case 2:
    // ...
    break;
  default:
    // ...
    break;
}

```

There are times when the same code can be used for multiple cases, and a fall-through should be used. A fall-through is the removal of the 'break' statement for a case, thus allowing the flow of execution to pass to the next case value. A fall-through should be commented for coding clarity.

```objc
switch (condition)
{
  case 1:
    // ** fall-through! **
  case 2:
  {
    // code executed for values 1 and 2
    break;
  }
  default:
  {
    // ...
    break;
  }
}

```

When using an enumerated type for a switch, 'default' is not needed. For example:

```objc
switch (menuType) {
  case WBSLeftMenuTopItemMain:
  {
    // ...
    break;
  }
  case WBSLeftMenuTopItemShows:
  {
    // ...
    break;
  }
  case WBSLeftMenuTopItemSchedule:
  {
    // ...
    break;
  }
}

```

## Private Properties

Private properties should be declared in class extensions (anonymous categories) in the implementation file of a class. Named categories (such as `WBSPrivate` or `private`) should never be used unless extending another class. The Anonymous category can be shared/exposed for testing using the `<headerfile>+Private.h` file naming convention.

**For Example:**

```objc
@interface WBSDetailViewController ()

@property (nonatomic, strong) GADBannerView *googleAdView;
@property (nonatomic, strong) ADBannerView *iAdView;
@property (nonatomic, strong) UIWebView *adXWebView;

@end

```

## Booleans

Objective-C uses `YES` and `NO`. Therefore, `true` and `false` should only be used for CoreFoundation, C or C++ code. Since `nil` resolves to `NO` it is unnecessary to compare it in conditions. Never compare something directly to `YES`, because `YES` is defined to 1 and a `BOOL` can be up to 8 bits.

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

**Preferred:**

```objc
if (post)
if (![comment boolValue])

```

**Not Preferred:**

```objc
if (post == nil)
if ([comment boolValue] == NO)
if (self.isAwesome == YES)
if (self.isAwesome == true)

```

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

```objc
@property (assign, getter=isEditable) BOOL editable;

```

## 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](http://programmers.stackexchange.com/a/16530?ref=williamboles.com) may happen where the line "inside" 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.

**Preferred:**

```objc
if (!error)
{
  return success;
}

```

**Not Preferred:**

```objc
if (!error)
  return success;

```

or

```objc
if (!error) return success;

```

Where an if statement contains more than one element under evaluation, each element should occupy its own line with the operator between elements on the trailing line.

**Preferred:**

```objc
if ([self.items count] > 0 &&
    self.opened)
{
  return success;
}

```

**Not Preferred:**

```objc
if ([self.items count] > 0 && self.opened)
{
  return success;
}

```

## 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. In general, the best use of the ternary operator is during the assignment of a variable and deciding which value to use.

Non-boolean variables should be compared against something, and parentheses are added for improved readability. If the variable being compared is a boolean type, then no parentheses are needed.

**Preferred:**

```objc
NSInteger value = 5;
result = (value != 0) ? x : y;

BOOL isHorizontal = YES;
result = isHorizontal ? x : y;

```

**Not Preferred:**

```objc
result = a > b ? x = c > d ? c : d : y;

```

## Init Methods

Each class should have one designated initialiser that all other initialisers funnel into

```objc
- (instancetype)init
{
  self = [super init];

  if (self)
  {

  }

  return self;
}

```

## Class Constructor Methods

Where class constructor methods are used, these should always return type of 'instancetype' and never 'id'. This ensures the compiler correctly infers the result type.

These methods should always be the first methods in your class, below any class methods.

```objc
@interface Airplane
+ (instancetype)airplaneWithType:(WBSAirplaneType)type;
@end

```

## Class Cleanup Methods

You should always implement 'dealloc' and 'didRecieveMemoryWarnings' methods in classes whenever necessary, especially when using KVO and notifications.

These methods should be at the end of the class, with `dealloc` being the final method.

## Happy Path

When coding with conditionals, the first branch should always be the happy path, with the unhappy path explicitly defined in an `else` branch.  
**Preferred:**

```objc
- (void)postUpdated
{
  if ([post boolValue])
  {
	//Happy
  }
  else
  {
  	//Unhappy
  }

}

```

**Not Preferred:**

```objc
- (void)postUpdated
{
  if (![post boolValue])
  {
    //Unhappy
  }

  //Continue
}

```

One exception to this rule is the declarations of properties where we will only use the unhappy path.

```objc
- (NSObject *)feedLatestUpdate
{
    if (!_feedLatestUpdate)
    {
        _feedLatestUpdate = [NSObject alloc] init;
    }

    return _feedLatestUpdate;
}

```

## Error handling

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

**Preferred:**

```objc
NSError *error;
if (![self postWithError:&error])
{
  // Handle Error
}

```

**Not Preferred:**

```objc
NSError *error;
[self postWithError:&error];

if (error)
{
  // Handle Error
}

```

## Singletons

Singleton objects should use a thread-safe pattern for creating their shared instance.

```objc
+ (instancetype)sharedInstance
{
  static id sharedInstance = nil;

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^
  {
    sharedInstance = [[self alloc] init];
  });

  return sharedInstance;
}

```

## Line Breaks

Where a method contains more than one parameter, the second parameter should be shown on its own line

**Preferred:**

```objc
self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers
                                                                      prices:prices];

```

**Not Preferred:**

```objc
self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers prices:prices];

```

## Magic strings

Where possible, avoid the use of magic strings because while XCode should find and update them during a refactor, it doesn't always do so, and we can end up with bugs that only surface during run-time.

**Preferred:**

```objc
[self post:NSStringFromClass[WBSLoadingView class]];

```

**Not Preferred:**

```objc
[self post:@"WBSLoadingView"];

```

## Warnings

Compiler-generated warnings should **not** be present in our code (if a warning is generated in a 3rd party library and you can fix it - do so, and submit the fix to that 3rd party project). A check must always be made to ensure that all warnings are resolved before committing your changes.

The only exception to this is developer-generated warnings where the keyword ##warning has been explicitly used to highlight an issue with the current implementation. Developer-generated warnings are intended to be short-lived and need to be addressed within a reasonable timescale. After each sprint, any existing warnings in the app need to be discussed in the sprint planning meeting.

It's important to note that building the app against different configurations can result in different warnings; it's your responsibility to ensure that your commit is warning-free in all configurations.

## Xcode project

The physical files should be kept in sync with the Xcode project files to avoid file sprawl. Any Xcode groups created should be reflected by folders in the filesystem. Code should be grouped not only by type, but also by feature for greater clarity.

## Autolayout vs Frames

Dynamic positioning is preferred to static values, i.e check the superview's / screen's width rather than writing `320`. Autolayout is encouraged where possible, but is frequently not appropriate.

## Button Action

Button actions should have the structure \[buttonName\]Pressed.

**Preferred:**

```objc
- (void)searchButtonPressed:(UIButton *)sender;

```

**Not Preferred:**

```objc
- (void) searchButtonAction: (UIButton *) sender;

- (void) searchButtonClicked: (UIButton *) sender;

```

## Predicate Format

The format for the predicate string should use spaces between all elements and equality comparisons.

**Preferred:**

```objc
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"feed.feedID == %@ && order != %@", self.feedID, self.pageOrder];

```

**Not Preferred:**

```objc
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"feed.feedID==%@ && order!=%@", self.feedID, self.pageOrder];

```

## Relationship Inverse

If the relationship is bidirectional and was set up as inverse in the Data Model, then we should set the value only on only one of the sides.

**Preferred:**

```objc
[user addListsIsMemberObject:list];

```

**Not Preferred:**

```objc
[user addListsIsMemberObject:list];
[list addMembersObject:user];

```

## Parentheses in mathematical operations

To avoid possible problems if someone does not know the rule, it is better to add parentheses to encapsulate every operation. With this rule, we will prevent problems and improve readability.

**Preferred:**

```objc
NSInteger *integer = ((4 * 8) / 2) + 2;

```

**Not Preferred:**

```objc
NSInteger *integer = 4 * 8 / 2 + 2;

```