% XeLaTeX can use any Mac OS X font. See the setromanfont command below.
% Input to XeLaTeX is full Unicode, so Unicode characters can be typed directly into the source.

% The next lines tell TeXShop to typeset with xelatex, and to open and save the source with Unicode encoding.

%!TEX TS-program = xelatex
%!TEX encoding = UTF-8 Unicode


% Apple Documentation Style - Latex Template
% https://github.com/izydor86/AppleDocumentationStyleLatexTemplate
% Wojciech Nagrodzki 2013


\documentclass[10pt]{extarticle}
\usepackage[margin=2cm]{geometry}       % See geometry.pdf to learn the layout options. There are lots.
\geometry{a4paper}                      % ... or a4paper or a5paper or ... 
\usepackage[parfill]{parskip}           % Activate to begin paragraphs with an empty line rather than an indent
\usepackage{titlesec}
\usepackage{color}
\usepackage{hyperref}
\usepackage{verbatim}
\usepackage[framemethod=TikZ]{mdframed}
\usepackage{hyperref}
\usepackage{tabto}


% Define section, subsection and subsubsection font size and color
\definecolor{AllportsColor}{HTML}{0769AE}
\definecolor{VeniceBlue}{HTML}{045078}

\titleformat*{\section}
{\huge}

\titleformat*{\subsection}
{\color{AllportsColor}\LARGE}

\titleformat*{\subsubsection}
{\color{VeniceBlue}\large\bfseries}


% Define the colors of table of contents
% This is helpful to understand http://tex.stackexchange.com/questions/110253/what-the-first-argument-for-lsubsection-actually-is
\definecolor{LochmaraColor}{HTML}{0C88CC}

\makeatletter

\renewcommand{\l@section}[2]{\vspace{14pt}\@dottedtocline{2}{0pt}{0pt}{\bfseries\textcolor{LochmaraColor}{#1}}{#2}} 
\renewcommand{\l@subsection}[2]{\@dottedtocline{2}{0pt}{0pt}{\textcolor{LochmaraColor}{#1}}{#2}}
\renewcommand{\l@subsubsection}[2]{\@dottedtocline{2}{20pt}{0pt}{\textcolor{LochmaraColor}{#1}}{#2}}

\renewcommand{\@dotsep}{10000}

\makeatother


% Insert 22pt white space before roc title. \titlespacing at line 65 changes it by -22 later on.
\renewcommand*\contentsname{\hspace{22pt}Contents}


% Remove numbers before sections, it does not remove a spacing from the left side of section
% Look below to see how I remove them
\renewcommand\thesection{}
\renewcommand\thesubsection{}
\renewcommand\thesubsubsection{}


% Define a spacing for section, subsection and subsubsection
% http://tex.stackexchange.com/questions/108684/spacing-before-and-after-section-titles
\titlespacing*{\section}
{-22pt}{0pt plus 0pt minus 0pt}{40pt plus 0pt minus 0pt}
\titlespacing*{\subsection}
{-18pt}{42pt plus 64pt minus 0pt}{0pt}
\titlespacing*{\subsubsection}
{-13pt}{12pt plus 0pt minus 0pt}{0pt}


% Section begins on new page
\newcommand{\sectionbreak}{\clearpage}


% Line spacing
\linespread{1.3}


% Lists a code inside of a blue border
\definecolor{BaliHaiColor}{HTML}{7CA1B3}
\newenvironment{codelisting}
{\footnotesize\mdframed[middlelinewidth=0.5pt, middlelinecolor=BaliHaiColor, skipabove=15pt]\verbatim}
{\endverbatim\endmdframed\vspace{12pt}\normalsize}


% Lists text inside yellow border
\definecolor{GoldenDreamColor}{HTML}{F2D138}
\newenvironment{tiplisting}
{\small\mdframed[middlelinewidth=0.5pt, middlelinecolor=GoldenDreamColor, skipabove=15pt]{\textbf{Tip:}}}
{\endmdframed\vspace{12pt}\normalsize}


% Lists text inside a blue border
\definecolor{MatisseColor}{HTML}{236AB2}
\newenvironment{importantlisting}
{\mdframed[middlelinewidth=0.5pt, middlelinecolor=MatisseColor, skipabove=15pt]{\textbf{Important:}}}
{\endmdframed\vspace{12pt}}


% Hyperlinks
\hypersetup{
    colorlinks = true,
    allcolors = {LochmaraColor},
}


% Will Robertson's fontspec.sty can be used to simplify font choices.
% To experiment, open /Applications/Font Book to examine the fonts provided on Mac OS X,
% and change "Hoefler Text" to any of these choices.

\usepackage{fontspec,xltxtra,xunicode}
\defaultfontfeatures{Mapping=tex-text}
\setromanfont[Mapping=tex-text]{Lucida Grande}
\setsansfont[Scale=MatchLowercase,Mapping=tex-text]{Gill Sans}
\setmonofont[Scale=MatchLowercase]{Menlo Regular}


\begin{document}

\tableofcontents

\section{Code Appearance}


Hardly any software is maintained for its whole life by the original author. Writing code in unified way helps engineers to understand it more quickly.


\subsection{Class names are not prefixed usually}

Prefixes are used only for classes that are to be shared between applications.


\subsection{Protocol names indicates behavior}
Most protocols group related methods that aren’t associated with any class in particular. This type of protocol should be named so that the protocol won’t be confused with a class. A common convention is to use a gerund (“...ing”) form:

\begin{itemize}
\item NSLocking	\tabto{3cm} Good
\item NSLock \tabto{3cm} Poor (seems like a name for a class)
\end{itemize}

Some protocols group a number of unrelated methods (rather than create several separate small protocols). These protocols tend to be associated with a class that is the principal expression of the protocol. In these cases, the convention is to give the protocol the same name as the class. An example of this sort of protocol is the NSObject protocol.


\subsection{Header file follows a structure}

Header should be kept as simple as possible. Declarations appears in it in the following order:

\begin{enumerate}
\item Imports
\item Forward class declarations
\item Enumeration types
\item Constants
\item Notification names and its user info dictionary keys
\item Delegate protocol
\item Data source protocol
\item Class interface
\end{enumerate}

The class interface has a fixed structure as well:

\begin{enumerate}
\item Properties
\item Data source property
\item Delegate property
\item Class methods
\item Instance methods
\end{enumerate}

Please pay attention to number of separating lines, it is also a rule.

\begin{codelisting}
#import <Foundation/Foundation.h>

@class ExampleClass;


typedef NS_ENUM(NSInteger, Enumeration) {
    EnumerationInvalid,
    EnumerationA,
};

extern CGFloat const ExampleClassDefaultHeight;

extern NSString * const ExampleClassWillPerformActionNotification;
extern NSString * const ExampleClassDidPerformActionNotification;
extern NSString * const ExampleClassActionNameKey;


@protocol ExampleClassDelegate <NSObject>

- (void)exampleClass:(ExampleClass *)exampleClass didPerformAction:(Action *)action;

@optional

- (void)exampleClass:(ExampleClass *)exampleClass willPerformAction:(Action *)action;

@end


@protocol ExampleClassDataSource <NSObject>

- (NSInteger)exampleClassNumberOfActions:(ExampleClass *)exampleClass;

@end


@interface ExampleClass : NSObject

@property (strong, nonatomic) NSURL * initialProperty;
@property (weak, nonatomic) id<ExampleClassDataSource> dataSource;
@property (weak, nonatomic) id<ExampleClassDelegate> delegate;

+ (id)exampleClassWithInitialProperty:(NSURL *)initialProperty;
- (id)initWithInitialProperty:(NSURL *)initialProperty;
- (void)performAction;

@end
\end{codelisting}


\subsection{Implementation file is divided by pragma marks}

Methods in implementation file appear in the same order they are declared in the header. They are grouped by pragma marks similar to following:

\begin{codelisting}
#pragma mark - Public Properties
#pragma mark - Public Class Methods
#pragma mark - Public Instance Methods
#pragma mark - IBActions
#pragma mark - Overridden
#pragma mark - Private Properties
#pragma mark - Private Class Methods
#pragma mark - Private Instance Methods
#pragma mark - Protocols
#pragma mark - Notifications
\end{codelisting}

When greater granularity is needed:

\begin{codelisting}
#pragma mark - Overridden (UIView)
#pragma mark - Overridden (UIContainerViewControllerCallbacks)
#pragma mark - Overridden (UIViewControllerRotation)
\end{codelisting}

\begin{tiplisting}
Create a code snipped to help you use the same pragma marks through all implementation files.
\end{tiplisting}

\subsection{Property attributes are kept in order}
Attributes are kept in the same order through all property declarations.

\begin{codelisting}
[assign | weak | strong | copy] + [nonatomic | atomic] + [readonly | readwrite] + [getter = ]
\end{codelisting}

None of the attributes can be omitted with the exception of readwrite.

\begin{codelisting}
@property (assign, nonatomic) CGFloat height;
@property (strong, nonatomic) UIColor * color;
@property (copy, nonatomic) NSString * name;
@property (weak, nonatomic) id <UITableViewDelegate> delegate;
\end{codelisting}

Getters for boolean properties should be renamed as follows.

\begin{codelisting}
@property (assign, nonatomic, getter = isVisible) BOOL visible;
\end{codelisting}


\subsection{Protocols and constants are prefixed with class name}

Protocols, notification names, enumeration types and other constants that refer to particular class are prefixed with the name of that class.

\begin{codelisting}
typedef NS_ENUM(NSInteger, UITableViewStyle) {
    UITableViewStylePlain,
    UITableViewStyleGrouped
};

UIKIT_EXTERN NSString *const UITableViewIndexSearch;

UIKIT_EXTERN const CGFloat UITableViewAutomaticDimension;

UIKIT_EXTERN NSString *const UITableViewSelectionDidChangeNotification;

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
...
\end{codelisting}

\subsection{IBOutlets are declared privately}

Outlets are defined as weak properties at the top of class extension, divided by one line from other properties.

\begin{codelisting}
@interface PanelViewController ()

@property (weak, nonatomic) IBOutlet UIButton * infoButton;
@property (weak, nonatomic) IBOutlet UIButton * closeButton;
@property (weak, nonatomic) IBOutlet UILabel * descriptionLabel;

@property (weak, nonatomic) UIView * overlayView;

@end
\end{codelisting}


\subsection{Classes may have additional header file for subclasses}

Private methods and properties are never exposed. To provide subclass access to them, they have to be declared in ForSubclassEyesOnly category. It should be placed in separate header file, named in the following manner: [Class Name] + Subclass.h. 

\begin{tiplisting}
UIGestureRecognizerSubclass.h is a good example of that approach.
\end{tiplisting}


\subsection{Method returns early, returns often}

Nesting makes code harder to read.

\begin{codelisting}
- (BOOL)loginUser:(NSString *)user withPassword:(NSString *)password
{
    if (user.length >= 6) {
        if ((password.length >= 8) {
            // actual logging code
        }
    }
    return NO;
}
\end{codelisting}

Getting invalid cases out of he way first will keep the working code with one level of indentation, and ensure that all parameters are valid. This paradigm is called The Golden Path.

\begin{codelisting}
- (BOOL)loginUser:(NSString *)user withPassword:(NSString *)password
{
    if (user.length < 6) return NO;
    if (password.length < 8) return NO;
    
    // actual logging code
}
\end{codelisting}

This approach has one more advantage, it is easier to add error handling later on.

\begin{codelisting}
- (BOOL)loginUser:(NSString *)user withPassword:(NSString *)password error:(NSError **)error
{
    if (user.length < 6) {
        if (error != NULL)
            *error = [NSError errorWithDomain:ExampleDomain
                                         code:1001
                                     userInfo:@{NSLocalizedDescriptionKey: @"User name must have..."}];
        return NO;
    }
    
    if (password.length < 8) {
        if (error != NULL)
            *error = [NSError errorWithDomain:ExampleDomain
                                         code:1002
                                     userInfo:@{NSLocalizedDescriptionKey: @"Password must have..."}];
        return NO;
    }
    
    // logging in code
}
\end{codelisting}

\subsection{Method is not bisected with conditionals.}

Following method structure is not acceptable.

\begin{codelisting}
- (void)method
{
    if (self.valueX == 10) {
        // perform some actions
    }
    else {
        // perform some other actions
    }
}
\end{codelisting}

Bisection can be removed by returning in the if statement.

\begin{codelisting}
- (void)method
{
    if (self.valueX == 10) {
        // perform some actions
        return;
    }
    
    // perform some other actions
}
\end{codelisting}

In one case bisection is allowed.

\begin{codelisting}
- (void)method
{
    if (self.valueX == 10) {
        // perform some actions
    }
    else {
        // perform some other actions
    }
    
    // perform some actions no matter what
}
\end{codelisting}


\section{General rules}

\subsection{Header file is imported only if necessary}

Importing a header files is allowed:

\begin{itemize}
\item if class needs to conform to a protocol (header with protocol declaration)
\item if class is inheriting from another class (header with superclass declaration)
\item if class uses enums in its interface (header with enums declarations)
\end{itemize}

In any other cases forward declaration should be applied.


\subsection{Delegate method always passes the sender}

Delegation method passes sender as first parameter. It is a good practice to use will/did paradigm.

\begin{codelisting}
- (NSInteger)exampleClassNumberOfActions:(ExampleClass *)exampleClass
- (void)exampleClass:(ExampleClass *)exampleClass willPerformAction:(Action *)action;
- (void)exampleClass:(ExampleClass *)exampleClass didPerformAction:(Action *)action;
\end{codelisting}


%\subsection{Lallal}
%
%a
%
%\begin{codelisting}
%@property (nonatomic) CGGradientRef tileGradient; // default: a lovely blue
%@property (nonatomic) NSInteger selectionBorderWidth; // default: 5 pixels
%@property (nonatomic) CGGradientRef selectionGradient; // default: a subtle white to grey gradient
%\end{codelisting}


\subsection{Init method takes only mandatory parameters}

All settings required to proper initialization are passed as initializer parameters. They are accessible later through readonly properties.

\begin{codelisting}
@property (strong, nonatomic, readonly) DownloaderMode downloaderMode;

- (id)initWithDownloaderMode:(DownloaderMode)downloaderMode;
\end{codelisting}

\begin{tiplisting}
If you need a convenience method to create instances, consider creating factory methods.
\end{tiplisting}


\subsection{Accessors are not used in init and dealloc}

Instance subclasses may be in an inconsistent state during init and dealloc method execution, hence code in those methods must avoid invoking accessors.

\begin{codelisting}
- (id)init
{
    self = [super init];
    if (self) {
        _foo = [NSMutableSet set];
    }
    return self;
}

- (void)dealloc
{
    [_titleLabel removeObserver:self forKeyPath:@"text"];
}
\end{codelisting}


\subsection{Abstract class can be faked with assertion}

Creating instances of abstract classes can be thwarted with following assertion.

\begin{codelisting}
- (id)init
{
    self = [super init];
    if (self) {
        NSAssert1([self isMemberOfClass:[MyAbstractClass class]] == NO,
                  @"%@ is an abstract class. Please do not create instances of it.", [self class]);
    }
    return self;
}
\end{codelisting}


\subsection{Abstract method raises exception}

Forcing subclass to provide implementation of a method is accomplished by raising exception.

\begin{codelisting}
- (void)abstractMethod
{
    [NSException raise:NSInternalInconsistencyException 
                format:@"It's template method. Implementation must be provided in subclass."];
}
\end{codelisting}


\subsection{Enumeration type contains invalid value}

Enumeration type equal to zero is considered as invalid. It protects instance variables from being initialized with meaningful value.

\begin{codelisting}
typedef NS_ENUM(NSInteger, Enumeration) {
    EnumerationInvalid,
    EnumerationA,
    EnumerationB,
    EnumerationC,
};
\end{codelisting}

It also shields from false positives, when comparing against values returned by methods sent to nil pointer. Let's assume EnumerationInvalid does not exist.

\begin{codelisting}
@interface MyObject : NSObject

@property (assign, nonatomic) Enumeration enumeration;

@end
\end{codelisting}

If myObject pointer is nil, performActionA method is called, and it may not be expected.

\begin{codelisting}
MyObject * myObject = ...

if (myObject.enumeration == EnumerationA)
    [self performActionA];
else if (myObject.enumeration == EnumerationB)
    [self performActionB];
else
    [self performActionC];
\end{codelisting}


\subsection{The highest level of abstraction is used by default}

Lower levels are used only when more control is needed. For example, instead using GCD:

\begin{codelisting}
dispatch_sync(dispatch_get_main_queue(), ^{
    // code
}
\end{codelisting}

Use operation queue.

\begin{codelisting}
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    // code
}];
\end{codelisting}


\subsection{Exception is not used to control flow}

The general pattern is that exceptions are reserved for programming or unexpected runtime errors such as out-of-bounds collection access, attempts to mutate immutable objects, sending an invalid message, and losing the connection to the window server. The program catching such an exception should quit soon afterwards. Exceptions must not be used to control flow in favor of NSError objects.
When developing a class or a framework exceptions are thrown to indicate that class or framework is being misused:

\begin{codelisting}
- (void)abstractMethod
{
    [NSException raise:NSInternalInconsistencyException 
                format:@"It's template method, you need to implement it in your subclass"];
}
\end{codelisting}


\subsection{Lazy loading reduces memory footprint}

Creating object on demand reduces initialization  time of containing class.

\begin{codelisting}
- (NSMutableDictionary *)cacheDictionary
{
    if (_cacheDictionary == nil) {
        _cacheDictionary = [NSMutableDictionary dictionary];
    }
    return _cacheDictionary;
}
\end{codelisting}


\subsection{Object does not register other objects as observers}

Object registers itself as an observer.

\begin{codelisting}
[obj addObserver:self forKeyPath:@"isExecuting" options:NSKeyValueObservingOptionNew context:NULL];
\end{codelisting}

Unregistering follows the same rule.

\begin{codelisting}
[obj removeObserver:self forKeyPath:@"isExecuting" context:NULL];
\end{codelisting}


\subsection{Method does not return NSError object}

Success or failure is indicated by the return value of the method: nil or NO.

\begin{codelisting}
- (id)initWithContentsOfURL:(NSURL *)aURL;
- (BOOL)writeToURL:(NSURL *)aURL atomically:(BOOL)atomically;
\end{codelisting}

NSError object is used only for providing additional information about the failure.

\begin{codelisting}
- (id)initWithContentsOfURL:(NSURL *)aURL options:(NSDataReadingOptions)mask error:(NSError **)errorPtr;
- (BOOL)writeToURL:(NSURL *)aURL options:(NSDataWritingOptions)mask error:(NSError **)errorPtr
\end{codelisting}

Therefore you should always check that the return value is nil or NO before attempting to do anything with the NSError object. Similarly you ought to check error domain before checking error code.


\subsection{Custom error belongs to error domain}

Custom errors have error domain and error code defined.

\begin{codelisting}
extern NSString *const MyErrorDomain;

typedef NS_ENUM(NSInteger, MyErrorCode) {
    MyInvalidErrorCode
    MyErrorCode1,
    MyErrorCode2,
    MyUnknownErrorCode,
};
\end{codelisting}

Both parameters and localized description are used upon error initialization.

\begin{codelisting}
if (error != NULL) {
    if(error_situation_1) {
        error* = [NSError errorWithDomain:MyErrorDomain 
                                     code:MyErrorCode1
                                 userInfo:@{NSLocalizedDescriptionKey: @"Description of error 1"}];
    }
    else if (error_situation_2) {
        error* = [NSError errorWithDomain:MyErrorDomain 
                                     code:MyErrorCode2
                                 userInfo:@{NSLocalizedDescriptionKey: @"Description of error 2"}];
    }
    else {
        error* = [NSError errorWithDomain:MyErrorDomain 
                                     code:MyUnknownErrorCode
                                 userInfo:@{NSLocalizedDescriptionKey: @"Unknown error"}];
    }
}

\end{codelisting}


\subsection{Property in category is realized by associated object}

New property is added to existing class by using associated objects. Please pay attention to the way the key is defined.

\begin{codelisting}
static void * const navigationItemKey = (void *)&navigationItemKey;

- (void)setNavigationItem:(UINavigationItem *)navigationItem
{
    objc_setAssociatedObject(self, 
                             navigationItemKey, 
                             navigationItem, 
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UINavigationItem *)navigationItem
{
    UINavigationItem * navigationItem = objc_getAssociatedObject(self, navigationItemKey);
    if (navigationItem == nil) {
        navigationItem = [[UINavigationItem alloc] init];
        self.navigationItem = navigationItem;
    }
    return navigationItem;
}
\end{codelisting}


\section{Concurrency}

Recommended reading  \href{http://www.objc.io/issue-2/}{Concurrent Programming - objc.io}

\begin{importantlisting}
To avoid priority inversion problems with Grand Central Dispatch use default queue priority DISPATCH\_QUEUE\_PRIORITY\_DEFAULT in almost all cases.
\end{importantlisting}


\subsection{Multiple readers one writer}

Concurrent isolation queue is used to synchronize access to a property.

\begin{codelisting}
NSString * queueLabel = [NSString stringWithFormat:@"%@.isolation.%p", [self class], self];
self.isolationQueue = dispatch_queue_create([queueLabel UTF8String], DISPATCH_QUEUE_CONCURRENT);
\end{codelisting}

Dispatch barrier async runs the block after all previously scheduled blocks are completed and before any following blocks are run.

\begin{codelisting}
- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey
{
    aKey = [aKey copyWithZone:NULL];
    dispatch_barrier_async(self.isolationQueue, ^{
        [self.mutableDictionary setObject:anObject forKey:aKey];
    });
}

- (id)objectForKey:(id)aKey
{
    __block id object;
    dispatch_sync(self.isolationQueue, ^{
        object = [self.mutableDictionary objectForKey:aKey];
    });
    return object;
}
\end{codelisting}


\subsection{NSOperation can be cancelled before it begins execution}

Main method checks if operation is cancelled at the very beginning and interrupts execution if condition is true.

\begin{codelisting}
- (void)main
{
    if (self.isCancelled) return;
    
    // code
}
\end{codelisting}


\section{UIView}

\subsection{View is usually initialized in two ways}

By calling initWithFrame, or initWithCoder method when it is unarchived form nib file. Both situations are covered.

\begin{codelisting}
@interface ExampleView ()

@property (strong, nonatomic) UITextField * textField;

@end

@implementation ExampleView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initialize];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initialize];
    }
    return self;
}

- (void)initialize
{
    _textField = [[UITextField alloc] init];
    _textField.translatesAutoresizingMaskIntoConstraints = NO;
    [self addSubview:_textField];
    
    NSDictionary * views = NSDictionaryOfVariableBindings(_textField);
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-8-[_textField]-8-|"
                                                                 options:0
                                                                 metrics:nil
                                                                   views:views]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[_textField]-8-|"
                                                                 options:0
                                                                 metrics:nil
                                                                   views:views]];
}
\end{codelisting}

Note that we do not implement -encodeWithCoder: method. UIViews and UIViewControllers does not follow normal serialization process, their state is persisted in model.


\subsection{Interface of generic view}

View exposes minimal set of properties and methods that are required for its configuration.
Property is not backed up by instance variable, but by view's or subview's property, if possible.

\begin{codelisting}
- (NSString *)name
{
    return self.nameLabel.text;
}

- (void)setName:(NSString *)name
{
    self.nameLabel.text = name;
}
\end{codelisting}

View is independent of model. Mapping between view's and model's properties is kept in a category on that view. This way view controller is kept cleaner.

\begin{codelisting}
@implementation UITableViewCell (Person)

- (void)configureWithPerson:(Person *)person
{
    self.imageView.image = person.photo;
    self.textLabel.text = person.name;
}
\end{codelisting}


\subsection{Interface of specific view}

Specific view is tightly coupled with model. It exposes one method that takes a model object and configures the view.

\begin{codelisting}
@interface PersonTableViewCell : UITableViewCell

- (void)configureWithPerson:(Person *)person

@end
\end{codelisting}


\section{UIViewController}

\subsection{Properties affecting user interface}

It is a common practise to have properties on view controller that influence its view. Putting view adjusting code in the setter is not enough, as view may be not loaded. After it is loaded, view controller should adjust it according to the property. In result it is convenient to create a separate method for adjusting the view as it will be called from the setter and -viewDidLoad as well.

\begin{codelisting}
- (void)setClient:(Client *)client
{
    _client = client;
    [self adjustUserInterfaceForClient:client];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self adjustUserInterfaceForClient:self.client];
}

- (void)adjustUserInterfaceForClient:(Client *)client
{
    if (self.isViewLoaded == NO) return;
    // code adjusting interface
}
\end{codelisting}


\subsection{View controller containment}


\subsubsection{Container specific item is provided by property}


If the container requires the child to have specific properties, it delivers category on UIViewController that provides an item which encapsulates all of them.

\begin{codelisting}
- (UINavigationItem *)navigationItem
{
    UINavigationItem * navigationItem = objc_getAssociatedObject(self, kNavigationItemKey);
    if (navigationItem == nil) {
        navigationItem = [[UINavigationItem alloc] init];
        self.navigationItem = navigationItem;
    }
    return navigationItem;
}
\end{codelisting}

Whenever container needs to stay in sync with child's properties it uses Key Value Observing.


\subsubsection{Container is accessible from contained view controllers}

Child view controller can access the container through a property.

\begin{codelisting}
@interface UIViewController (UINavigationControllerItem)

@property(nonatomic,readonly,retain) UINavigationController *navigationController;

@end
\end{codelisting}

Example getter implementation traverses view controller hierarchy and returns the closest parent view controller of the container class.

\begin{codelisting}
- (UINavigationController *)navigationController
{
    UIViewController * controller = self.parentViewController;
    while (controller != nil && [controller class] != [UINavigationController class]) {
        controller = controller.parentViewController;
    }
    return (UINavigationController *)controller;
}
\end{codelisting}


\end{document}
