Skip to content
This repository has been archived by the owner on Sep 26, 2022. It is now read-only.

This repo provides public information on Domain's iOS development practices

Notifications You must be signed in to change notification settings

DomainGroupOSS/ios-resources

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 

Repository files navigation

Domain Objective-C styleguide

Status

This style guide is no longer being maintained.

Brace style

Egyptian braces are to be used

Incorrect

-(void)myMethodName
{

 if (myCondition)
 {
   
 }
}

###Correct

-(void)myMethodName{

 if (myCondition){
   
 }
}

Else and If Else statements follow on the same line as the previous statement's closing brace.

Incorrect

if (myCondition) {

}
else if (myOtherCondition) {

}
else {

}

###Correct

if (myCondition) {

} else if (myOtherCondition) {

} else {

}

Assignment alignment

Align all assignment operators if possible.

###Incorrect

myObjectWithLongName = 16
myVarWithShortName = anotherObject
superShort = @"wicked"

###Correct

myObjectWithLongName   = 16
myVarWithShortName     = anotherObject
superShort             = @"wicked"

Tabs or spaces

Always use the Xcode default of 4 spaces.

Method naming

Avoid "and" or “with” for multiple method parameters.

###Incorrect

[self goDoSomethingWithThing:myThing andStuff:myStuff];

###Correct

[self goDoSomethingWithThing:myThing stuff:myStuff];

Make the word before the argument describe the argument.

###Incorrect

[self withThingDoSomething:myThing andStuff:myStuff];

###Correct

[self goDoSomethingWithThing:myThing stuff:myStuff];

Setters set, getters don’t get.

###Incorrect

-(void)size:(CGSize)size;
-(CGSize)getSize;

###Correct

-(void)setSize:(CGSize)size;
-(CGSize)size;

Boolean naming should contain "can", "will", "should" or "is”.

###Incorrect

-(BOOL)doesDisplay;

###Correct

-(BOOL)canDisplay;
-(BOOL)willDisplay;
-(BOOL)shouldDisplay;
-(BOOL)isDisplaying;

Acronyms are capitalized (not just methods). "Id" is not an acronym.

###Incorrect

-(void)makeRequestWithUrl;

###Correct

-(void)makeRequestWithURL;

iVars and properties

  • Private iVars belong in a blank category in the implementation file NOT the header.
  • Protected iVars belong in the header with @protected keyword. (so it doesn’t look like private iVars placed incorectly)
  • Use protected iVars for subclass use. NOT properties.

Use a leading underscore for all iVars

###Incorrect

UIView* myView;

###Correct

UIView* _myView;

Access properties by iVar backer in implementation file. The dot accessor is for external use only.

###Incorrect

self.myView = [[UIView alloc] init];

###Correct

_myView = [[UIView alloc] init];

Enums

NS_ENUM should be used instead of enum.

###Incorrect

typedef enum {
    ExampleStyle_None,
    ExampleStyle_Short,
} ExampleStyle;

###Correct

typedef NS_ENUM(NSInteger, ExampleStyle) {
    ExampleStyle_None,
    ExampleStyle_Short,
};

  • Enums should be typed using typedef
  • Each enum item name should be prefixed with the type name followed by an underscore

###Incorrect

typedef NS_ENUM(NSInteger, CellHeight) {
    Default,
    Short,
    Tall,
};

###Correct

typedef NS_ENUM(NSInteger, CellHeight) {
    CellHeight_Default,
    CellHeight_Short,
    CellHeight_Tall,
};

Boolean comparisons

Don’t compare against YES or NO.

###Incorrect

if (myBOOL == YES)
if (myBOOL == NO)

###Correct

if (myBOOL)
if (!myBOOL)

Dot notation

Dot notation is to be used at all available opportunities unless explicitly frowned-upon by this styleguide.

Import/Include

  • Import Objective-C
  • Include C/C++

    Golden Trails

    Fail early instead of forcing an obscure trail of logic.

    ###Incorrect

    if (condition1){
           if (condition2){
               if (condition3){
                   //only logic
               }
           }
       }

    ###Correct

    if (!condition1) return;

    NSError handling

    Any method that takes an NSError by reference should also return a Boolean. Evaluate the error if the method returned false.

    ###Incorrect

    NSError *error;
    [self trySomethingWithError:&error];
    if (error) {
       // Handle Error
    }
    

    ###Correct

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

    Blocks

    Type your blocks whenever possible.

    ###Incorrect

    - (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))myBlockParamName {...}

    ###Correct

    typedef returnType (^myBlockTypeName)(parameterTypes);
    - (void)someMethodThatTakesABlock:(myBlockTypeName)myBlockParamName;

    Methods requiring a super call

    Always mark the method with the required super attribute.

    ###Incorrect

    - (void)someMethodThatBreaksIfSuperIsNotCalled;

    ###Correct

    - (void)someMethodThatBreaksIfSuperIsNotCalled __attribute__((objc_requires_super));

    Deprecating Methods

    Always mark the method with the deprecated attribute or a deprecation method.

    ###Incorrect

    - (void)someDeprecatedMethod;

    ###Correct

    - (void)someDeprecatedMethod __attribute__((deprecated));

    Custom constructor

    Always use instancetype, not id, as the return type.

    ###Incorrect

    - (id)init;

    ###Correct

    - (instancetype)init;

    Literals

    Always use literals.

    ###Incorrect

    [myArray objectAtIndex:4];

    ###Correct

    myArray[4];

    Array first and last object

    Always use firstObject / lastObject to avoid out of bounds for an empty array.

    ###Incorrect

    myArray[0]

    ###Correct

    [myArray firstObject]

    constants

    Always use a leading 'k' in your constant variable name.

    ###Incorrect

    static const NSInteger myAwesomeConstant = 17;

    ###Correct

    static const NSInteger kMyAwesomeConstant = 17;

    Turnery operators

    Wrap the conditional in parentheses and leave a space on either side of all operators.

    ###Incorrect

    label.text = isAwesome? @"awesome": @"lame";

    ###Correct

    label.text = (isAwesome) ? @"awesome" : @"lame";

    Scalars

    Don't use platform or bit-size specific scalars unless explicitly needed.

    ###Incorrect

    int myInt      = 16;
    float myFloat  = 1.0f;

    ###Correct

    NSInteger myInt  = 16;
    CGFloat myFloat  = 1.0f;

    ###Correct

    UInt8 mySmallInt = 4; // I really need an 8-bit integer here for the following reasons...

    The 'new' constructor

    Do not use the new constructor.

    ###Incorrect

    NSObject* myObject = [NSObject new];

    ###Correct

    NSObject* myObject = [[NSObject alloc] init];

    Class names

    • Use the correct design pattern use name in the class name. Do not use the word 'manager'.
    • Include the correct Domain prefix. If working on any other project include the brand/project prefix in the class name.

    ###Incorrect

    UserBehaviourManager

    ###Correct

    DMUserBehaviourController

    ###Correct

    DMABCUserBehaviourModel

    Commenting

    Use double leading asterisks for block comments. Block comments should be used to clarify the intent of a method.

    ###Incorrect

    -(void)myMethod{
    /* this method does ... */
    
    }

    ###Correct

    /** this method does ... */ 
    -(void)myMethod{
    
    }

    Use inline comments for clarifying the use of obscure methods/functions or to explain why you've used a non-standard technique. Inline comments should fall above their subject on their own line.

    ###Incorrect

    // this method does ...
    -(void)myMethod{
     [self doSomethingElse]; //go and do something else
    
    }

    ###Correct

    -(void)myMethod{
    //normally technique A should be used here but 
    //because of [reason] technique B must be used. 
    
    //getting the square root of PI
    sqrtf(M_PI);
    }

    Use pipes to identify symbols within a comment.

    ###Incorrect

    -(void)myMethod{
     //myInt is used to calculate the meaning of life.
     NSInteger myInt = 42;
    }

    ###Correct

    -(void)myMethod{
     //|myInt| is used to calculate the meaning of life.
     NSInteger myInt = 42;
    }

    Delegate methods

    When creating a component that uses delegation include a reference to that component through it’s delegate methods. Try to use the component name, excluding the prefix, at the start of each delegate method whenever possible. The component will be called “DMPickerView” for this example.

    ###Incorrect

    -(void)didPressItemAtIndex:(NSUInteger)itemIndex;

    ###Correct

    -(void)pickerView:(DMPickerView *)pickerView  didPressItemAtIndex:(NSUInteger)itemIndex;

    Delegate method names should contain "did", "should" or "will”.

    ###Incorrect

    -(void)pickerMayStartBehaviour:(DMPickerView *)pickerView;

    ###Correct

    -(void)pickerDidStartBehaviour:(DMPickerView *)pickerView;

    Localizable strings key format

    Localizable strings keys should provide usage context without using the value.

    ###Incorrect

    "CONTACT_TABLE_DISMISS_CONFIRM_BUTTON_TOTALLY" = "Totally"

    ###Incorrect

    "CONTACT_TABLE_DISMISS_CONFIRM_BUTTON" = "Totally"

    ###Correct

    "contact-table.dismiss-confirm-button" = "Totally"

    Component thread safety

    When creating components that use blocks or protocols that use multi-threading, always return them on the main thread unless otherwise specified. This is to ensure that the user of the component will always know what thread the blocks or protocols will return on (main) and to ensure that the component itself is responsible for it’s own thread management.

    ###Incorrect

    -(void)myMethod {
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
           
           id data = [self someLargeCalculations];
           [_delegate myProtocolMethod:data];
       });
    }
    
    -(void)anotherMethod:(MyBlockType)myBlock {
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
           
       id data = [self someLargeCalculations];        
       myBlock(data);
       });
    }

    ###Correct

    -(void)myMethod {
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
           
           id data = [self someLargeCalculations];
    
           dispatch_async(dispatch_get_main_queue(), ^{
               
               [_delegate myProtocolMethod:data];
           });
       });
    }
    
    -(void)anotherMethod:(MyBlockType)myBlock {
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
           
       id data = [self someLargeCalculations];  
    
           dispatch_async(dispatch_get_main_queue(), ^{      
    
              	    myBlock(data);
           });
       });
    }
  • About

    This repo provides public information on Domain's iOS development practices

    Resources

    Stars

    Watchers

    Forks

    Releases

    No releases published

    Packages

    No packages published