Archive for May, 2009

May not respond warning!

May not respond warning

The “May not respond” warning is a common one amongst new and rushing developers alike but never fear it is the absolute easiest warning to fix. The may not respond warning arises when the compiler comes across a method call that is not explicitly defined in the class header file.

Examples

A lot of people seem to be experiencing warnings like Warning: MyViewController may not respond to ‘-parseXMLFileAtURL’ or similar (where MyViewContoller is your class and parseXMLFileAtURL is a method name)

So to fix this error all we have to do is name this function (this happens to be a xml parser delegate method) in the classes .h file. So in MyViewController.h we simply add the parseXMLFileAtURL method definition,

- (void) parseXMLFileAtURL:(NSString *) myUrl;

This should get rid of that pesky warning!

Variable arguments in Cocoa

Variable Arguments

If you’ve been using Cocoa for more than five minutes you’ve almost certainly come across a function which takes variable arguments and you might not have even realised it. Variable arguments are used in two very common function calls within Cocoa namely stringWithFormat and arrayWithObjects.

These two function also demonstrate the two manners in which to take variable arguments, Format strings and Nil terminated lists. 

Format Strings

NSString *aString = [NSString stringWithFormat:@"string: %@ , number %d, @"string", 123];

The stringWithFormat method is then declared as follows:

+ (id)stringWithFormat:(NSString *)format, ...;

Nil terminated lists

NSArray *myArray = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];

The last object of the list in these calls must be nil.

How to implement Variable Arguments

So that’s great and all but how do we accept variable arguments in our functions you ask. The simplest method always being the best the answer here requires using the standard c va_* syntax and a handy Cocoa macro named NS_REQUIRES_NIL_TERMINATION whch tells the compiler that invocations of this method must include a nil-terminated list of arguments.

So the va_* syntax gives us

  • va_list - A pointer to a list of arguments.
  • va_arg - Retrieves the next argument, must supply type in order to recieve the correct number of bytes
  • va_start - Initializes the va_list pointer to point the first argument (after the specified argument).
  • va_end - Releases memory held by the va_list structure.

So our function will look something like this,

- (void)appendStringsToString:(NSString *)stringArg, ...{
        NSMutableString *newString = [NSMutableString string];

//create the pointer to the list of args
        va_list args;

//set the starting point
        va_start(args, stringArg);

//loop over the args appending them to the string
//note we are specifying NSString * in the call to va_arg
        for (NSString *arg = firstArg; arg != nil; arg = va_arg(args, NSString*)){
                [newString appendString:arg];

        }

//be good and clean up
        va_end(args);

        [contents autorelease];
        contents = [newContentString retain];
}

And the declaration will look something like this

(void)setContentByAppendingStrings:(NSString *)firstString, ... NS_REQUIRES_NIL_TERMINATION;

And there we have it you can now go ahead and build your functions to take argument lists a handy utility.

Bombs Away Out Now!

Finally!

After a week or so of waiting Bombs Away is relased to the app store! You can go ahead and buy it now if you fancy!

Bombs Away Splash Page

Bombs Away Splash Page

That is all really…so enjoy the rest of your day. I will post some details and stats and things when I have some nice data.

Playing sound clips

Audio clip playback on iPhone

While building my first iPhone app, Bombs Away, I wanted to play a sounds as an audio feedback to any of the bombs exploding. Simple right! Wrong. I also wanted to keep my app as relevant as possible to the majority of iPhone OS users. Initial I was using the AudioPlayer methods in order to play sound but there were not included in earlier incarnations in the iPhone OS.

Realising this I went in search of a method of playing audio on the iPhone SDK version 2.2 and up. I figured this gave me the majority of iPhone and iPod touch users without being too troublesome since I could use the same code from 2.2 and up. Below is an example of the sort of code I use in order to play sound clips,

Example Code


int randomNumber = arc4random() % 4;
randomNumber++;

NSString *tmpFileName = [[NSString alloc] initWithFormat:@"sound%d", randomNumber];
NSString *fileName = [[NSBundle mainBundle] pathForResource:tmpFileName ofType:@"wav"];
NSURL *aFileURL = [NSURL fileURLWithPath:fileName isDirectory:NO];

NSLog(fileName);
SystemSoundID aSoundID;
SystemSoundID _soundID;

OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)aFileURL, &aSoundID);
if (error == kAudioServicesNoError) {
        // success
        _soundID = aSoundID;
} else {
        NSLog(@"Error %d loading sound at path: %@", error, fileName);
}

AudioServicesPlaySystemSound(_soundID);

[tmpFileName release];