I use:
#import <Foundation/Foundation.h>
@interface iCode_Framework : NSObject
@property (readonly, nonatomic) unsigned int iBufCapacity;
@property (readonly, nonatomic) unsigned int iPort;
@property (readonly, nonatomic) NSString * urlStr;
@end
#import "iCode_Framework.h"
static iCode_Framework * instance;
@implementation iCode_Framework
@dynamic iBufCapacity;
@dynamic iPort;
@dynamic urlStr;
- (unsigned int)iBufCapacity
{
    return 1024u;
};
- (unsigned int)iPort
{
    return 1978u;
};
- (NSString *)urlStr
{
    return @"localhost";
};
+ (void)initialize
{
    if (!instance) {
        instance = [[super allocWithZone:NULL] init];
    }
}
+ (id)allocWithZone:(NSZone * const)notUsed
{
    return instance;
}
@end
Which is used exactly like a normal class, you call alloc and init! It is often convenient to assign to a variable to give a shorthand, because alloc and init are long to type, e.g.:
#import "iCode_FrameworkTests.h"
#import "iCode_Framework.h"
static iCode_Framework * c;
@implementation iCode_FrameworkTests
+ (void)initialize
{
    c  = [[iCode_Framework alloc] init];
}
- (void)setUp
{
    [super setUp];
    // Set-up code here.
}
- (void)tearDown
{
    // Tear-down code here.
    [super tearDown];
}
- (void)testSingletonNotNil
{
    STAssertNotNil(c, nil);
}
- (void)testSingletonProperty
{
    STAssertEqualObjects(c, [iCode_Framework alloc], nil);
}
- (void)testIBufCapacity
{
    STAssertEquals(c.iBufCapacity, 1024u, nil);
}
@end
The advantage of this approach is it is used exactly like any other class and can therefore be mocked for testing.