First examination of the iPhone SDK
This weekend I dove deep into the iPhone SDK and tried (after some initial tests) to develop a full-scale realworld application from scratch. Since I'm sorta good at Cocoa and Objective-C, it wasn't too difficult to grasp the concept behind it and build a simple application in little to no time. I spend my friday evening reading the documentation and playing around with some code, and I spend about 4 hours on Saturday to actually write the application I had in mind. So far my verdict is, that this is an absolutely awesome API for mobile devices. It's far far ahead of any of the other Development Kits for mobile usage out there (save Android, but that's actually not really out yet). I really like the concepts behind it, and it allows to do create magnificient applications really quickly. Apart from that, the (free!) development environment with XCode, Debugger and Instruments is superb, too. My main criticism is currently, that I can't test my application on my real iPhone, since the 2.0 Beta isn't only available to select developers. However, the Aspen simulator is a valid substitute. Users who are new to Cocoa and Objective-C could have some problems though, since the current documentation is, let's call it, "quite buggy". There were many small difficulties in there which could really hinder a non-experienced user from coming to the oh-so-necessary "success-experience". I'll try to adress those that I stumbled upon here:
Play a Sound File: In order to simply play a sound, one needs to call AudioServicesCreateSystemSoundID (fileURL, soundID). The Documentation notes, that fileURL is a CFURLRef, and soundID is UInt32. There're two caveats here though: In order to get a CFURL one can use the NSURL class, which is toll-free bridged with CFURLRef, however: In order for the compiler to not warn, one has to cast NSURL to CFURLRef. The other, and far more annoying, problem here is, that this function doesn't expect UInt32 (as mentioned in the documentation) for the second parameter, but a pointer to UInt32. So a real call would look like this: UInt32 soundId = 1024; AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath: @"kick.wav"], &soundId);
Get a value from a UI Element: The UISlider class for example is really nice and simple to use, as it allows (just like all the other objects) to set a method which will be called, every time someone changes the slider. In this method, one gets the actual Slider-Object as an argument, so one can for example retrieve the current value, or modify the slider. In order to get the current value of the slider, there exists a so-called "value" property. The difficulty is now to retrieve this value. Since it is a property, retrieving the value cannot be not done via a "getValue" method (as one might expect) but via key/value coding: [Slider valueForKey:@"value"] Now, the documentation lists the return value of UISlider.value as float. That's actually not correct. The value is float, however not a c-float type but a Cocoa NSNumber object with a float value. Once again, this is something which is common in Cocoa, but I guess many new users will still wonder about this.
Set frame for a UI Element: In order to define, where in your view an UI Element can be placed, one needs to define a "frame" which sets the position and width/height. Most Elements offer a init method, which let the user define such a frame: i.E. [[UILabel alloc] initWithFrame:labelFrame]; However, there're situations, when one can't use the initWithFrame method. How do you set the frame then? Quite simple: the frame is a property and can be set with the new . operator: UILabel *label = [[UILabel alloc] init]; label.frame = CGRectMake(0,0, 60, 24);
I hope I could help some of the early adopters, and will write more soon.