Fundamental iOS design patterns: SharedInstance (Singleton in Objective C)

Brief introduction

Singleton is one of the (if not THE) most commonly used/abused design pattern adopted in software development.
Basically it’s used to restrict the instantiation of a class to one object only that can be used safely across application architecture. Its implementation is pretty simple compared to other patterns and it’s very similar for the most of programming languages, but in Objective C it has a slightly different approach due to the lack of “normal constructor” that are instead replaced by alloc/init paradigm.

How it works in Objective C

In Objective C, we can speak more appropriately about the SharedInstance pattern rather than traditional Singleton.
This one is often used in Apple frameworks and differently from its twin brother, it does not explicitly forbid the instantiation of multiple class instances, but it simply provide a class method that will return a shared instance. During the first call to that method the instance will be allocated and the next calls will return the previously object created. So this is a sort of hybrid approach.
A common class that use this pattern is UIApplication which implements a sharedApplication method (which returns the current running application). Differently from Singleton which use getInstance(), in Objective C the corresponding method has not a fixed name but it should start with “shared” followed by the “type” of class (so for UIApplication is “sharedApplication” for MYAmazingManager will be “sharedManager“). Anyway there are several exceptions, for example NSFileManager has a “defaultManager” acting as a sharedInstance accessor that could be renamed “sharedManager“.

Pattern implementation

In my singleton implementations I simply call the accessor “sharedInstance“, in this way I can use a simple pre-compiler macro that automatically synthesize this methods for me.
Even implementation of this pattern may vary and personally I adopted one which is thread-safe and rely on CGD (Grand Central Dispatch), which is an affective C level API provided by Apple in order to handle concurrency.

The implementation of my sharedInstance method is the following (comments explain how it works):

+ (id)sharedInstance 
	// structure used to test whether the block has completed or not
	static dispatch_once_t p = 0;
	// initialize sharedObject as nil (first call only)
	__strong static id _sharedObject = nil;
	// executes a block object once and only once for the lifetime of an application
	dispatch_once(&p, ^{
		_sharedObject = [[self alloc] init];
	// returns the same object each time
	return _sharedObject;

Pattern in action!

SharedInstance pattern is IMO the best way to share data across multiple viewControllers in iOS applications.
One practical example is a data manager to share Core Data stuff such managed object context. I realized my own manager so that I can access this objects anywhere with ease like:

[[MYDataManager sharedInstance] managedObjectContext];

Quick iOS tip: where is the right place to add and remove observers in UIViewControllers?

While I was debugging my iPhone app I noticed (thanks to my verbose logs) that certain methods were called multiple times… apparently like if they were in a loop. I lost several time trying to figure out why and then I realized that the problem was related to defining them in the wrong place! (technically not wrong at all, but definitely wrong in my app context).
I was adding listeners in viewDidLoad and removing them in viewDidUnload.
This is acceptable only if you have simple UIViewControllers that don’t work in composite controllers hierarchy (they are not contained in UINavigationController or UITabBarController).
viewDidLoad is called after the view controller’s view has been released, but in a controllers hierarchy this does not happen since controllers are retained by the container! This leads to multiple messages dispatched to registered observers, so if you have a UINavigationController containing a sequence of 5 viewController, handlers will be triggered 5 times (one for each controller).
The safely approach to add and remove listeners is instead in viewWillAppear: and viewWillDisappear:

- (void)viewWillAppear:(BOOL)animated
   [super viewWillAppear:animated];
   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:UIKeyboardDidShowNotification object:nil];

- (void)viewWillDisappear:(BOOL)animated
   [super viewWillDisappear:animated];
   [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];

Generate beautiful code documentation with a simple shortcut using AppleDoc, Xcode custom behaviors and AppleScript!

This time I realized something really great and I’m truly satisfied about it!
Few days ago I discovered a fantastic open source project from GentleBytes called AppleDoc by reading a post on Cocoanetics.
This is a tool that generate an Apple-like HTML documentation from source files (by using the proper comment style) and it also generates installable docsets and Atom feeds for the download from a remote host.
After a couple of tests and document generations my big question was: “how can I automatize the process without launching a script every time and for each project I want to document?”.
The first obvious answer was “add a Run Script in the build phases!”… but it’s not a smart idea to launch a similar long script for every build, because it takes several seconds and potentially minutes depending on the amount of classes to analyze, and it’s often unnecessary to update a documentation if method signatures remain the same. So I searched for an alternative way to execute scripts from Xcode only when desired, by focusing my efforts on its “Behaviors” (Xcode > Behaviors > Edit Behaviors > +). Behaviors can be triggered by events (only default behaviors), using menu or with a custom shortcut and a behavior can perform several actions like running a script…
and here I started to waste a lot of time in order to realize what I had in mind (create a single auto-runnable script to generate code documentation for each project without hard-coding paths and names), because the environment variables I was using in Xcode build phases as a test can’t be used in external scripts (since they are not attached to the Xcode process as far I understood).
So the problem was: “how can I retrieve this variables dynamically from our beloved ide? is it possible?”… it’s been an hard google search plus a couple of questions asked on StackOverflow (Did I tell you how much I love that site? I really love it!) in order to clear my dubs… and yes, it’s possible thanks to AppleScript! Xcode exposes several objects that can be queried by this funny script language, so in this way I first realized an AppleScript to retrieve the variables I need (project name, project path and company) and then I invoked my old and refactored bash script passing them.
In conclusion I’m now able to launch document generation for each project I’m working on, by simply press ALT+CMD+D (a custom shortcut of my choice), I also configured a submarine sound effect and the display of a bezel alert… really wonderful!

This is the AppleScript used for the behavior that invoke the bash script by sending it the necessary arguments:


tell application "Xcode"
	tell first project
		-- variables to export
		set projectName to (get name)
		set projectDir to (get project directory)
		set company to (get organization name)

		-- invoke script passing extracted variables
		do shell script ("sh /PATH_TO_SCRIPT/ " & projectName & " " & projectDir & " " & company)
	end tell
end tell

Of course you have to replace “/PATH_TO_SCRIPT/” according to your path.
If you decide to create your own AppleScript script using the default editor (/Applications/Utilities/Apple Script Editor), remember to save it as a plain text and to include the proper header declaration (#!/usr/bin/osascript), otherwise Xcode will throw an exception trying to run it!

…and this is Sparta the bash (I added a couple of say commands in order to debug the process… remove comments to hear your mac speak!):

#! /bin/sh

# Input arguments: 
# $1 -> project name
# $2 -> project path
# $3 -> company name

# dynamic variables

#say "project is: $1";
#say "path is: $2";
#say "company is: $3";
#say "project path is: ${projectsPath}";

# create AppleDocOutput folder if not exists
if [ ! -d $docsPath ];
	#say "create output folder";
	mkdir "${docsPath}";

#say "run appledoc";

#invoke appledoc passing computed arguments
/usr/bin/appledoc \
--project-name "$1" \
--output "${docsPath}/$1/" \
--docset-feed-url "${docsURL}/%DOCSETATOMFILENAME" \
--docset-package-url "${docsURL}/%DOCSETPACKAGEFILENAME" \
--docset-fallback-url "${docsURL}/$1Doc/" \
--ignore "$1Tests" \
"$2" > "${docsPath}/AppleDoc.log"

the bash invokes AppleDoc by assuming its location on /usr/bin/appledoc, the arguments passed are few since I use the GlobalSettings.plist for the main setting and I override only certain options (read GentleBytes reference for more info).
I also redirect the output of the command to a log file for an easy debug.
Remember to make both scripts executable (chmod +x) in order to use them!

…that’s all! If you want more info leave a comment (it’s free)