Make Better Things



I like to make better things.

Singleton Design Pattern for Objective-C

Well first of all what is a singleton design pattern -

A singleton class in an object-oriented application always returns the same instance of itself. It provides a global access point for the resources provided by the object of the class. A design pattern that is related to these kinds of designs is called the Singleton pattern.

When Would You Use the Singleton Pattern?

  • There must be exactly one instance of a class with which it must be accessible from a well-known access point.
  • The sole instance can be extended only by subclassing, and it won’t break client code with the extended object.

The Singleton pattern provides a well-known access point to client classes that want to create a unique instance of and access to a shared resource. Although a static global object reference or a class method can provide a global access point, the global object cannot prevent the class getting instantiated more than once, and the class method lacks the flexibility of decoupling.

A static global variable holds a single reference to an instance of a class. Another class or a method that can access that global variable is, in fact, sharing the same copy with other classes or methods that use the same variable. That sounds like what we are after in this chapter. Everything seems fine if we use only the same global variable throughout the whole application. So, in fact, we don’t need the Singleton pattern. But hey, wait a minute; what if there is somebody in your team or a consultant who has defined the same type of static global variable as yours? Then there will be two copies of the same global object type living in the same application—so a global variable doesn’t really solve the problem.

A class method provides shared services without creating an object of it. A single instance of the resource is maintained within the class method. However, this approach lacks the flexibility if the class needs to be subclassed to provide better services.

A singleton class can guarantee a single, consistent, and well-known access point to create and access a single object of the class. The pattern provides the flexibility such that any of its subclasses can override the instance method and have total control over object creation of itself without changing code in the client. Or even better, the instance implementation in the parent class can handle dynamic object creation. The actual type of a class can be determined to make sure the correct object is created at runtime. This technique will be discussed later in the chapter.

Implementing a Singleton in Objective-C -

MySingleton.h
#import <Foundation/Foundation.h>

@interface MySingleton : NSObject {

}

+ (MySingleton*) sharedInstance;

@end

MySingleton.m


#import "MySingleton.h"

static MySingleton *_instance;
@implementation MySingleton

#pragma mark -
#pragma mark Singleton Methods

+ (MySingleton*)sharedInstance
{
 @synchronized(self) {

 if (_instance == nil) {

 _instance = [[self alloc] init];

 // Allocate/initialize any member variables of the singleton class here
 // example
 //_instance.member = @"";
 }
 }
 return _instance;
}

+ (id)allocWithZone:(NSZone *)zone

{    
 @synchronized(self) {

 if (_instance == nil) {

 _instance = [super allocWithZone:zone];            
 return _instance;  // assignment and return on first allocation
 }
 }

 return nil; //on subsequent allocation attempts return nil    
}

- (id)copyWithZone:(NSZone *)zone
{
 return self;    
}

- (id)retain
{    
 return self;    
}

- (unsigned)retainCount
{
 return UINT_MAX;  //denotes an object that cannot be released
}

- (void)release
{
 //do nothing
}

- (id)autorelease
{
 return self;    
}

#pragma mark -
#pragma mark Custom Methods

// Add your custom methods here

@end

Visit Apple doc's this page for more info on Singleton Design Pattern -
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html

How to prevent apps to being installed on wrong or incapable devices

There may be cases when your app does not run because the device does not have front camera (or any such feature which is required to run the app). You can always check the device capabilities before using the special feature (check my this post if you don’t know how), But if you app absolutely depends on the feature you should prevent users from installing your app. The real question here is how can you prevent users from installing the app. The answer is UIRequiredDeviceCapabilities key in your info.plist file.

UIRequiredDeviceCapabilities (Array or Dictionary – iOS) lets iTunes and the App Store know which device-related features an application requires in order to run. iTunes and the mobile App Store use this list to prevent customers from installing applications on a device that does not support the listed capabilities.
If you use an array, the presence of a given key indicates the corresponding feature is required. If you use a dictionary, you must specify a Boolean value for each key. If the value of this key is true, the feature is required. If the value of the key is false, the feature must not be present on the device. In both cases, omitting a key indicates that the feature is not required but that the application is able to run if the feature is present.
You should include keys only for the features that your application absolutely requires. If your application can accommodate missing features by avoiding the code paths that use those features, do not include the corresponding key.
Here is a list of all the keys and their meaning -

telephony
Include this key if your application requires (or specifically prohibits) the presence of the Phone application. You might require this feature if your application opens URLs with the tel scheme.

wifi
Include this key if your application requires (or specifically prohibits) access to the networking features of the device.

sms
Include this key if your application requires (or specifically prohibits) the presence of the Messages application. You might require this feature if your application opens URLs with the sms scheme.

still-camera
Include this key if your application requires (or specifically prohibits) the presence of a camera on the device. Applications use the UIImagePickerController interface to capture images from the device’s still camera.

auto-focus-camera
Include this key if your application requires (or specifically prohibits) auto-focus capabilities in the device’s still camera. Although most developers should not need to include this key, you might include it if your application supports macro photography or requires sharper images in order to do some sort of image processing.

front-facing-camera
Include this key if your application requires (or specifically prohibits) the presence of a forward-facing camera. Applications use the UIImagePickerController interface to capture video from the device’s camera.

camera-flash
Include this key if your application requires (or specifically prohibits) the presence of a camera flash for taking pictures or shooting video. Applications use the UIImagePickerController interface to control the enabling of this feature.

video-camera
Include this key if your application requires (or specifically prohibits) the presence of a camera with video capabilities on the device. Applications use the UIImagePickerController interface to capture video from the device’s camera.

accelerometer
Include this key if your application requires (or specifically prohibits) the presence of accelerometers on the device. Applications use the classes of the Core Motion framework to receive accelerometer events. You do not need to include this key if your application detects only device orientation changes.

gyroscope
Include this key if your application requires (or specifically prohibits) the presence of a gyroscope on the device. Applications use the Core Motion framework to retrieve information from gyroscope hardware.

location-services
Include this key if your application requires (or specifically prohibits) the ability to retrieve the device’s current location using the Core Location framework. (This key refers to the general location services feature. If you specifically need GPS-level accuracy, you should also include the gps key.)

gps
Include this key if your application requires (or specifically prohibits) the presence of GPS (or AGPS) hardware for greater accuracy when tracking locations. If you include this key, you should also include the location-services key. You should require GPS only if your application needs more accurate location data than the cell or Wi-fi radios might otherwise allow.

magnetometer
Include this key if your application requires (or specifically prohibits) the presence of magnetometer hardware. Applications use this hardware to receive heading-related events through the Core Location framework.

gamekit
Include this key if your application requires (or specifically prohibits) Game Center (iOS 4.1 and later.)

microphone
Include this key if your application uses the built-in microphone or supports accessories that provide a microphone.

opengles-1
Include this key if your application requires (or specifically prohibits) the presence of the OpenGL ES 1.1 interfaces.

opengles-2
Include this key if your application requires (or specifically prohibits) the presence of the OpenGL ES 2.0 interfaces.

armv6
Include this key if your application is compiled only for the armv6 instruction set. (iOS v3.1 and later.)

armv7
Include this key if your application is compiled only for the armv7 instruction set. (iOS v3.1 and later.)

peer-peer
Include this key if your application requires (or specifically prohibits) peer-to-peer connectivity over Bluetooth. (iOS v3.1 and later.)

How to remove gloss/shine effect from iPhone app icon

By default, when building an application with Xcode, your icon will have a round beveling of the corners and a shine added over the top of the icon.
You can override this default by adding this following key in your info.plist file.

<key>UIPrerenderedIcon</key>
<true/>

How to use custom fonts in iPhone

Your designer has given you a artistic font which is not available on iPhone?

Well now in iOS sdk 4 you can use any font you wish.
You just need to drag the font’s ttf file in your resource folder and do this following entry in your info.plist file –

<key>UIAppFonts</key>
<array>
        <string>CloisterBlack.ttf</string>
</array>

UIAppFonts key accept a array so you can pass multiple fonts in it.

Now wherever you want to use the font in your application you can call:

[UIFont fontWithName:@"Cloister Black" size:64.0]

Just make sure you give the real font name in above code. The font file name and its “real font name” can be different, so just open the font in FontBook app and there you can see the real name of the font.

Hope it will save someone’s time.