Refer to the following articles for general style guidlines:
- http://www.cocoadevcentral.com/articles/000082.php
- http://www.cocoadevcentral.com/articles/000083.php
If something is not addressed in this guide, defer to the guidance in these.
Structure the Project with the following groups:
- Source (or "App Name")
- Application
- Model
- UI
- Tests
- Dependencies
- Frameworks
- Place the app delegate, info plist, global.h/.m and any other application level files within the Application Folder (functions, macros, analytics).
- Place all model classes (models, model controllers, network controllers) within the Model folder. Group according to function.
- Network classes can optionally be placed in a network folder.
- Place all view controllers, story boards, nibs, asset collections and view classes within the UI group. Group according to View Controller.
- Place any non application specific external classes within this group.
- Map the top level Xcode groups to finder folders (Source, Tests, Dependencies). Do not make subfolders for other groups, since modifying project structure will require you to move the finder files as well and creates unneeded overhead.
Each header file should contain the following in this order:
- Class/Header imports
@class
declarations- External constants (e.g. NSNotification constants)
- Function Declarations
- Structs / Enums
- Class Delegate Protocols Declarations
- Class Interface
- Class Categories
- Class Delegate Protocols
-
Header Imports Only import classes/headers for the following reasons:
- Headers that contains immediate superclass of the defined class.
- Header that contains a protocol that the defined class must conform to.
-
@class Declarations Any other classes that are referenced in the header file but do not under the above reasons.
-
Class Interface Do not use ivars - use properties only Methods / properties should be and grouped by functionality.
Each implementation file should contain the following in this order:
- Class/Header Imports
- Constants (e.g. NSNotification constants)
- Function Implementations
- Anonymous Class Category
- Class Implementation
- Class Categories
-
Header Imports Import all other classes referenced in the implementaion but were not imported in the .h file.
-
Anonymous Class Category Declare all private properties here instead of the header file. Do not forward declare private methods.
-
Class Implementation
- Dealloc Method
Should always be the first method within the
@implementation
block. - Pragma Marks Should be used to separate methods based on class inheritance / protocols / functionality
- Dealloc Method
Should always be the first method within the
e.g.
#pragma NSObject
#pragma CLLocationDelegate
#pragma Class Setup
- MyClass
- CCMyClass
instanceVariable
propertyName
methodWithNoArgument
methodWithOneArgument:(NSString*)anArgument
Always reference ivars by there property unless within the dealloc method.
-
Public place in interface of .h file
-
Private Place in class extension in the .m file
- Create a property for all instance variables.
- Place public properties in the interface.
- Place private properties in the anonymous interface category.
Always reference ivars by there property unless within the dealloc method. (yes, I repeated it, it is important)
For objects:
- Use retain attribute by default.
- Use copy for NSStrings, Collection Classes (Note: remember collection copies are shallow).
- Delegates should use the assign attribute.
For instance variables that need to be externally readonly, but internally readwrite:
You can achieve this result by defining the property as readonly in the class interface and redefining the property as readwrite in the anonymous class category. You should use this pattern frequently.
Be descriptive, really descriptive. A good reference is here.
place in interface of h file.
Place in class extension in the .m file Should be pre-peneded by an underscore, e.g - (void)_myPrivateMethod;
Unless a good reason is given all protocols should conform to the NSObject
protocol, i.e MyProtocol <NSObject>
Unless a good reason is given, all protocol methods should be @required
. Single method protocols are always @required
.
Enums should have the form:
typedef enum {
bq. MyCustomEnumNone,
MyCustomEnumOne,
MyCustomEnumTwo
}MyCustomEnumType;
Notice that the first enumerated value is "none". This is usually needed for checking whether a value has been set explicitly, so even if you think you don't need it, include it.
Add the following line:
#import Global.h
Do not make any further changes to the Prefix File ever. Instead make additions to the Global.h file or somewhere else if appropriate.
Contains global constants, and global functions Imports all categories referenced within the application (so you do not have to import them specifically within any class files.
Responsible for loading and management of high level view controllers such as tab controllers and/or navigation controllers.
Loads application level modal view controllers such as splash screens, login screens, or wizards.
Application specific code/behavior belongs here.
Other objects should NEVER reference the app delegate directly. The app delegate should only respond to NSNotifications or KVO if appropriate. In other words, consider ALL App Delegate methods private. If you are using this line of code anywhere:
[[UIApplication sharedApplication] delegate]
You are wrong.
Generally in the form:
- XxxController.h/m
- XxxManager.h/m Examples:
- ModelController
- AccountController
- NetworkManager
It is ok for these high level controller objects to be singletons, but be careful to not go crazy. Dependency injection is still perferred.
This Model instance controls the setup and behavior of model objects. If you must reference UIKit classes or headers in this file, you are doing something wrong (most likely that code should be in the app delegate).
##Singletons Singleton instance - (Model*)sharedInstance.
Please add the .md suffix to the filename.