dUsefulStuff library

This library is intended as a container for useful defines and classes which can make life easier when developing iPhone applications. It’s built as a framework, ready to go. Of course you can also use the source code and scripts separately as well.

Installing

  1. Download the latest dmg file. This contains a static framework usable on both iPhones and iPads, scripts, documentation and some sample graphics.
  2. Copy the library contents to a folder somewhere. For example, ~/projects/libs/dUsefulStuff
  3. Drag and drop the dUsefulStuff.framework folder to xcode. This is essentially the same as adding a framework.
  4. Add the header imports you need to your project. As this is a framework, you can now use the framework style syntax. For example
#import <dUsefulStuff/DCUIRating.h>

Dependencies

The following libraries are also required:

DCCommons.h

Import

#import <dUsefulStuff/DCCommon.h>

This header file contains the following useful defines :

Define Description
DC_LOG(template, …) Wraps NSLog and includes only the pre-compiler compiler flag DC_DEBUG is set.
DC_LOG_LAYOUT(UIView) Logs the position and size of the passed UIView instance.
DC_DEALLOC(name) Cleanly releases pointers and set’s them to point at nil. Also will log various info to the log if DC_LOG_DEALLOC is set as a pre-compiler compiler flag.
DC_PRETTY_BOOL(boolean) Outputs either the string “YES” or “NO”. Useful for logging.
DC_DATA_TO_STRING(data) Returns a NSString * from the passed NSData *.
DC_STRING_TO_DATA(string) Returns a NSData * from the passed NSString *.
DC_CONCATINATE(string, string) Returns the concatinated strings. The reason for this macro is that it uses indirection before concantinating. Thi allows things like this:
DC_CONCATINATE(abc, __LINE__) 

Which produces “abc51” if it is on line 51. Normal concatination using ## doesn’t work with __LINE__, but this macros gets around it by using nested macros. Useful for logging.
DC_EQUALS_NOT_FOUND_RANGE(range) Used to compare a passed range to see if it’s equal to the commonly returned {NSNotFound, 0} range. use this in if(…) statements to check for string search functions not finding things.

UI Controls

DCUIRating

This class can be used on iPhone displays to produce a star rating control similar to what you can see in Tunes. It produces a single horizontal bar of 5 images across the display. The user can tap or swipe across the bar to set the rating value they want. In addition, you can create and add a DCUIBubble to it which will display the current value of the rating whenever the users finger is on the display. This is useful for instant feed back because he users finger often obscures the control and therefore the current value.

It’s core features include :

Using DCUIRating

First you need to add some code to your controller. You will need an outlet for each rating controller you want to add to the view and you (optionally need to ensure that the delegate implements the DCUIRatingDelegate protocol. Here’s an example header file:

MyClass.h
#import <UIKit/UIKit.h>
#import <dUsefulStuff/DCUIRating.h>
#import <dUsefulStuff/DCUIRatingDelegate.h>
		
@interface RatingTestController : UIViewController<DCUIRatingDelegate> {
    @private
    DCUIRating * ratingControl;
}
		
@property (retain, nonatomic) IBOutlet DCUIRating * ratingControl;
		
@end

1. And some example code interface your viewDidLoad: method:

MyClassController.m
- (void) viewDidLoad {
    [super viewDidLoad];
			
    // Load the images for the active and inactive rating symbols.
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"star" ofType:@"png"];
    UIImage *myNoRatingImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
		
    imagePath = [[NSBundle mainBundle] pathForResource:@"star-active" ofType:@"png"];
    UIImage *myRatingImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
		
    // Now setup the rating control.
    self.ratingControl.onRatingImage = myRatingImage;
    self.ratingControl.offRatingImage = myNoRatingImage;
    self.ratingControl.scale = DCRatingScaleWhole;
			
    // Not required unless you want to get notified of changes.
    self.ratingControl.delegate = self;

    [myRatingImage release];
    [myNoRatingImage release];
			
    //Now add a bubble.
    imagePath = [[NSBundle mainBundle] pathForResource:@"bubble" ofType:@"png"];
    UIImage *myBubbleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];

    DCUIBubble * bubble = [[DCUIBubble alloc] initWithBackgroundImage:myBubbleImage];
    bubble.textOffsetXPixels = -2;
    bubble.textOffsetYPixels = -9;
    bubble.fontColor = [UIColor redColor];
			
    self.ratingControl.bubble = bubble;

    [bubble release];
    [myBubbleImage release];
}

// Delegate method.
-(void) ratingDidChange:(DCUIRating *) rating {
    DC_LOG(NSString stringWithFormat:@"Value: %f", rating.rating]);
}

The last thing to do is to add the the control to your xib file. Open Interface Builder and the view.

  1. In the Library dialog, click on the Classes button to show all classes in the project.
  2. Scroll down until you find the DCUIRating classes, then drag it onto your view.
  3. Size and position the control. Note you won’t see anything because Interface Builder does not see it
    as a control and therefore does not draw it. Also note that an instance of DCUIRating will resize itself to fit the height and number of icons specified (5 is the default) using the width of the inactive image you have set.
  4. Lastly, make sure that the control is connected to the controllers IBOutlet.

DCUIBubble

This class can be used to display values from another control.
Generally speakng it’s designed to be a popup bubble which appears when the user presses their
finger against a control. Here’s a example of how your control can display a DCUIBubble

- (void) popBubbleAtTouch:(UITouch *)atTouch {
    [self.bubble alignWithTough:atTouch];
    self.bubble.hidden = NO;
}
		
- (void) hideBubble {
    self.bubble.hidden = YES;
}
				
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // From UIResponder
    UITouch *aTouch = [[event touchesForView:self] anyObject];
    [self popBubbleAtTouch:aTouch];
    [super touchesBegan:touches withEvent:event];
}
		
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {     // From UIResponder
    [self hideBubble];
    [super touchesEnded:touches withEvent:event];
}
		
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {     // From UIResponder
    UITouch *aTouch = [[event touchesForView:self] anyObject];
    [self popBubbleAtTouch:aTouch];
}
		
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { // From UIResponder
    [self hideBubble];
    [super touchesCancelled:touches withEvent:event];
}

Setting the bubbles value is simple. here’s an example which sets it to an integer value:

[self.bubble setValue:[NSString stringWithFormat:@"%i", 5];

NSDictionary+dUsefulStuff and NSMutableDictionary+dUsefulStuff

These two are categories which allow you to store and retrieve dictionary entries based on the integer primitive.This saves having to do constant boxing and unboxing of values when you want to index based on a number .

NSObject+dusefulStuff

This category adds the following methods to every object:

Message Description
errorForCode:errorDomain:shortDescription:failureReason: Which provides a convenience method for creating NSError objects correctly populated for Cocoa.

NSString+dUsefulStuff

Adds functionality to strings.

Message Description
readBooleanInto: If the string contains “yes”, “no”, “true” or “false” (case insensitive) then this method will set a passed BOOL reference and return YES to indicate it has set a value. Otherwise it returns false and does not set the value. This is useful when reading boolean values from passed text.

UIColor+dUsefulStuff

This category adds a colour comparison function which can be used to test UIColor instances for equality.

UIView+dUsefulStuff

This category adds a method for drawing rounded rectangles on the view.

DCDialogs

Class of static methods for displaying messages to the user. Just takes some pain out of rewriting code.

DCBusyIndicator

This class provides a semi-transparent overlay with text and an activity indicator. This will slide up from the bottom of the screen. It’s designed to be used when thee is something happening and you want to cover the whole screen. DCBackgroundThread makes use of this automatically if you tell it too.

Scripts

In the scripts directory there are a number of scripts which can be used for building static libraries and documentation from the command line. To see an example how they can be used look at the build.sh file in the source root of this project. Each script is a distinct part or phase of a build process. Here users of Ant or Maven will be familiar with what I am talking about. These scripts are designed to be used either from a command line or from within xcode. Hence they make use of the standard xcode properties.

You will notice that all the sripts make use of variables prefixed with DC_. This is a deliberate thing because it makes it easier to see which variables are being used and there values.

defaults.sh

This script takes in the values previously setup in the build.sh script and uses then as the basis for further settings. Therefore it is important that it is included using the source statement rather than called as a subscript.

common.sh

A script which is included by other scripts to provide some commonly used functions. This script also handles arguments. There are several possible arguments that this build system understands so just do ./build.sh -? to see them.

buildStaticLibrary.sh

This is the main script for building. It will compile both a simulator and device version of the code in your project and then combine them into a single static framework.

createDocumentation.sh

This script will create and install api documentation using appledoc V2 tools. If appledoc is not found then documentation is not created and this step will be skipped.

clean.sh

This is the equivalent of the ant and maven clean tasks. It deletes the projects build directory and the target artifacts and directories.

assembleFramework.sh

This script takes in the compiled static library and creates a framework. This also includes the header files and the framework.plist file. This framework is assembled in the artifact directory.

createDmg.sh

This takes in all the files it finds into the artifact directory and builds a dmg file suitable for uploaded to distribution sites. Also included are any markdown documentation files (such as this one) that are in the project.

Uncrustify.sh

This is a shelle script which can be added to xcode as a script. You can use it to reformat the source code
using the uncrustify code formatter.

Thanks

I’d like to say thanks to several developers for developing the following tools which have helped me tremendously is developing dUsefulStuff: