If you want to learn Cocoa…
…be prepared to write a lot more code than in your typical “scripting” language. Three examples (I am using Ruby for comparison because it is the scripting language I am most familiar with; things would look very much the same with Python or PHP):
1. Declare a small hash/dictionary of key-value pairs
Ruby:
person = { :name => "John Appleseed", :age => 30, :favorite_fruit => [ "apple", "banana", "kiwi" ] }
Cocoa:
NSDictionary *person = [NSDictionary dictionaryWithObjectsAndKeys: @"John Appleseed", @"name", [NSNumber numberWithInteger:30], @"age", [NSArray arrayWithObjects:@"apple", @"banana", @"kiwi", nil], @"favoriteFruit", nil];
Now which of these is easier to read?
2. What day of the month is today?
Ruby:
today = Date.today # => #<Date: 4910525/2,0,2299161> puts "Day of the month: %d" % today.day # => Day of the month: 7
Cocoa:
NSDate *today = [NSDate date]; // => 2010-03-07 15:15:26 +0100 NSCalendar *calendar = [NSCalendar currentCalendar]; // => <__NSCFCalendar: 0x100400160> NSDateComponents *components = [calendar components:NSDayCalendarUnit fromDate:today]; NSLog(@"Day of the month: %d", [components day]); // => Day of the month: 7
3. Fetch something from the data store
Ruby on Rails (Active Record):
result = Person.find(:all, :conditions => { :first_name => "John" }, :order => "created_at DESC")
Cocoa (Core Data):
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstName == %@", @"John"]; [fetchRequest setPredicate:predicate]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO]; [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release]; NSError *fetchError = nil; NSArray *fetchResult = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; [fetchRequest release];
Now I know this is not a fair comparison, Objective-C/Cocoa has many advantages over Ruby et al., you can’t compare Core Data to Active Record, etc. Still, I find the differences very striking, especially regarding the readability of the code.
Porting RRGlossCausticShader to the iPhone
In September 2008, Matt Gallagher published Drawing gloss gradients in CoreGraphics, a very nice piece of code “that will draw a ‘gloss’ gradient in a single statement. All colors in the gradient are calculated from the single color parameter.”
Roy Ratcliffe later complemented Matt’s article with a generalized Objective-C class called RRGlossCausticShader that exposes a number of parameters to modify the gloss effect to your liking. Roy’s code also includes a nice OS X sample application that helps visualizing the effects of parameter changes on the final result.
Unfortunately, neither Matt’s original version nor Roy’s refactoring work on the iPhone out of the box, mainly because they rely on NSColor, which is only available on the Mac platform. I recently ported Roy’s code to the iPhone and also wrote a little iPhone sample app for it.
Porting was fairly easy:
- Use conditional compilation (
#if TARGET_OS_IPHONE) to substitute UIColor for NSColor. - Add some functionality that NSColor has but UIColor lacks, namely getting individual color component values and converting colors between RGB and HSB.
For the iPhone sample app, I wanted to do a little more than just copy the existing OS X app, so I added a button to print the shader’s current settings to the debugger console. That way, you can play with the sliders until you find a shading you like and then just copy and paste the code from the console to your project to configure the shader with the correct settings. The app will also save the current settings to the user defaults on exit.

You can print the gloss caustic shader's current settings to the debugger console and copy and paste them into your code from there.
Here are a few example shadings that can be created with RRGlossCausticShader:

The code is available on my GitHub account. I will also contact Roy and ask him to incorporate my modifications into his repository. Both his code and mine are released under the liberal MIT license.
Book Review: Coders at Work
In 2007, Jessica Livingston wrote a book called Founders at Work, in which she interviewed a number of tech entrepeneurs about their experiences in the early days of their startups. I enjoyed that book very much, and so I was quite excited to see that Peter Seibel recently wrote what could be called the second part of what I hope will be a series of interview books. Instead of founders, this time it is all about programmers, and the title of the book is Coders at Work: Reflections on the Craft of Programming (released in late 2009).
Coders at Work consists of extensive interviews (each interview some 40 pages long) with 15 of the best-known programmers of the last 4 decades:
- Jamie Zawinski, author of XEmacs and the Unix version of Netscape Navigator.
- Brad Fitzpatrick, creator of LiveJournal, author of memcached.
- Douglas Crockford, creator of JSON.
- Brendan Eich, inventor of JavaScript.
- Joshua Bloch, author of the Java Collections Framework.
- Joe Armstrong, inventor of Erlang.
- Simon Peyton Jones, Co-creator of Haskell.
- Peter Norvig, Director of Research at Google.
- Guy Steele, Co-designer of Scheme.
- Dan Ingalls, principal creator of Smalltalk.
- L. Peter Deutsch, author of Ghostscript and implementor of Smalltalk-80.
- Ken Thompson, creator of Unix.
- Fran Allen, pioneer in optimizing compilers.
- Bernie Cosell, one of the guys who wrote the first routers (Interface Message Processors) for the Arpanet.
- Donald Knuth, über-father and creator of TeX.
The interviews follow the same broad structure: Peter Seibel asks everyone how they got into programming; how they learned it in the first place and how they perfected their skills; which programming languages they like and which they hate; which editors, IDEs and debugging tools they use; how they approach the design of a program, top-down or bottom-up; etc. In addition to the general questions, Seibel digs deep into the projects his subjects are famous for: How did they end up working on these projects? What was it like? How was the project team organized? What did you learn? What were the hardest problems to solve, the fiercest bugs to squash?
To me, the greatest insight came from the interviewees’ reflections on their craft: How do they think about themselves and how do they personally practice programming? Despite having quite different backgrounds, it was interesting to discover that many of them had a common philosophy when it came to approaching programming.
For example, many mentioned their desire to take things apart, to understand how stuff works, as one of the prime impulses that brought them into the field. Also, motivation is a very important factor for learning, and personal side projects were often the ones where they learned the most. On the question whether it made sense to write the umpteenth C compiler or image processing library instead of just taking one that is already available, Joe Armstrong said:
The really good programmers spend a lot of time programming. I haven’t seen very good programmers who don’t spend a lot of time programming. … And you get better at it—you get quicker at it. The side effect of writing all this other stuff [side projects] is that when you get to doing ordinary problems, you can do them very quickly.
The importance of reading and writing
When asked whether they, as a programmer, think of themselves as a scientist or an engineer or an artist or a craftsman, some said they felt most like a writer whose job is to formulate their thoughts so that their audience — which comprises both the computer and readers of the source code — understands them best. You want to become a great programmer? Write a lot of code! Jamie Zawinski:
It feels like you’re writing a story and you’re trying to express a concept to a very dumb person—the computer—who has a limited vocabulary.
Similarly, nearly everyone mentioned that reading code is as important as writing it. Many said that reading other people’s source code (written either by more-experienced co-workers or the code of well-known open source projects) was a formative experience for their development as a programmer. Still, it struck me that these experiences mostly came from accidental exposures to great pieces of code. Almost none of the 15 had made it a personal habit to explicitly grab the source of an interesting piece of software and read over it for both learning and fun. Or, as Joshua Bloch put it, “When was the last time you sat down at night to read a beautiful piece of code?”
Short of attacking monster projects like the Linux kernel, how do we find the good code that is worth reading, the code that makes us better programmers by studying it? I think there is a great opportunity for blogs and other websites here to research and present the truly great pieces of code in open source projects in an easy-to-digest and informative form. Perhaps Peter Seibel’s new project, Gigamonkeys Quarterly, could partly evolve into something like this.
Historical quality
One reviewer of the book on Amazon:
There is also a historical quality to the book. The majority of the people interviewed started programming in the 50s or the early 60s. One of the standard questions was “How did you learn to program?” and I thought it was quite interesting to read about the old computers they used, the punch cards etc. It was almost like little history lessons from the computing field. — Henrik Warne
While this is certainly true and nice, I felt that the book lacked a certain balance between the “old guys” and the young coders of today who learned programming on and for the Web. Brad Fitzpatrick is basically the only representative of the Web generation of programmers. I think including more of his generation could have given readers further insight on the learning and practice of programming today. This is especially so since many of the interviewees, having learned their craft decades ago, lamented the complexity of today’s hardware and software and how much harder it is today to dig deep into how things work at the most basic level. So how do people learn to program these days and how to they cope with the fact that they will never understand how the machine they are writing code for actually works? For instance, I would have liked to see David Heinemeier Hansson included in the book.
Wrap-up
If you want to learn more about Coders at Work, Peter Seibel talked about it on episode #69 of the Stack Overflow podcast. He also held a one-hour long speech at Google where he talks about a few anecdotes and some of the topics he addresses in the book.
I found Coders at Work entertaining and inspiring. Reading the book has provided me with long lists of more books I want to read and programming languages I want to learn. Highly recommended Coders at Work for programmers; not recommended for non-programmers who want to learn more about programmers and programming.
Finally, my favorite quote from the book is by Peter Seibel himself:
Speaking of writing intricate code, I’ve noticed that people who are too smart, in a certain dimension anyway, make the worst code. Because they can actually fit the whole thing in their head they can write these great reams of spaghetti code.
Book Review: Cocoa Design Patterns
Although I pointed out a minor mistake in the book in an earlier post, I highly recommend Erik M. Buck’s and Donald A. Yacktman’s Cocoa Design Patterns (released in late 2009) to every Cocoa programmer who has worked through one or more beginner books to Objective-C and the Cocoa framework.
Many ways to structure a book
Many books about Cocoa introduce the framework’s features by talking about one class (or a group of related classes) per chapter and creating a small sample application to show how a programmer would integrate this class into their own project. An example is Aaron Hillegass’s wildly popular Cocoa Programming for Mac OS X. After a general introduction to some of Cocoa’s key concepts, Hillegass mostly introduces specific features like NSUndoManager, window controllers, NSUserDefaults, table views, event handling etc. by explaining the class interfaces of these features and how to implement them. If a feature requires a further explanation how it works under the hood, this is worked into the flow of the chapter. This practical approach is a great way for programmers to learn how to use a framework like Cocoa (and Cooca Programming for Mac OS X is a very good book, everyone should read it). However, sometimes it can leave you a little in the dark about what is going on under the hood.
How does it work and why did they design it this way?
In contrast, Cocoa Design Patterns is built around the questions, How does it work and why did they design it this way?, with specific applications of the design patterns mentioned in the relevant places. Each chapter of the book is devoted to one specific design pattern and its implementation in Cocoa. This is especially beneficial because in Cocoa, many problems are solved a little differently than in other popular frameworks, partly due to the dynamic nature of Objective-C. The authors spend a great deal explaining the motivation behind both the patterns themselves and their implementation. If you have read the classic “Gang of Four” book on design patterns, you will recognize most of the patterns (even if they often have different names), and this book is a perfect addition.
Here are a few of the patterns discussed in the book that I found most helpful:
- Model-View-Controller as the grand pattern that structures the entire framework.
- Dynamic Creation of objects and the many places throughout the framework this feature of the Objective-C runtime is used, from scripting to unarchiving to plug-in architectures.
- The ever-present Delegate pattern.
- The target-action mechanism.
- Invocations and their role in the undo/redo process.
- The Flyweight pattern and how it is employed by
NSNumberandNSCellto save memory and performance. - Proxies and Forwarding and how this can be used to implement Higher Order Messaging.
The book is a little Mac-centric in that it does not specifically talk about the iPhone and some of the examples mentioned only apply to the Mac. That part is small, though, and I would say Cocoa Design Patterns is equally useful to iPhone developers. Again, highly recommended for intermediate Cocoa developers.
CHDataStructures on the iPhone
With NSArray, NSDictionary, NSSet and their subclasses, the Foundation framework provides a number of basic collection classes. If you need more specialized or advanced collection data structures, there is a good chance that Quinn Taylor’s CHDataStructures framework already has what you need. CHDataStructures is open source under a very liberal license and well-tested. It includes collection classes for different types of trees, specialized dictionaries and sets, linked lists, and many more.
I recently helped Quinn to make the CHDataStructures project iPhone-compatible. You can now grab the latest version from the repository and either build a static library to include in your iPhone projects or add the entire code to your project. The readme file includes detailed installation instructions.
Even though CHDataStructures included virtually no OS X-specific code, we had to tweak the build configuration to make it work on the iPhone as seamlessly as possible:
- Unfortunately, Apple does not support frameworks (so useful!) or dynamic libraries on the iPhone, so we have to build a static libary (or include all the code directly in our iPhone projects). And since we are dealing with two different architectures (ARMv6 on the iPhone and i386 on the iPhone Simulator), we actually need to build different versions of the static library.
- Unit Testing in Xcode means that the tests are run from a script during the build phase and test results show up in Xcode’s Build Results window. This is great if you are developing for the same platform your development system runs on, which is usually the case (or close enough) if you write OS X apps. If you develop for the iPhone, your build runs on an Intel machine but you want your unit tests run against the ARM architecture. To accomplish this, you need a separate iPhone unit testing app that installs on the device, runs all unit tests upon launch, outputs the results to the console, and quits. Apple has a good how-to on this.
I highly recommend CHDataStructures to anyone who needs more than the standard collection classes.
Mutable Properties of Immutable Objects
Objects are called immutable if their state cannot be changed after initialization. While less flexible than their mutable counterparts, immutable objects have a lot of advantages. For instance, callers of a method that takes an immutable object as a parameter need not fear that the method might change the object. Also, thread safety is much easier to ensure if the objects shared by multiple threads are immutable.
For these and other reasons, it is often a good idea to make your own custom classes immutable, too. If you do so, it is important that all properties of your class also return immutable objects. I found an example of what not to do in the otherwise excellent book Cocoa Design Patterns by Erik M. Buck and Donald A. Yacktman: on page 144, they define a class that has a read-only property returning an NSMutableDictionary:
@interface WordInformation : NSObject { // ... NSMutableDictionary *puzzleSpecificAttributes; } // ... @property (readonly, copy) NSMutableDictionary *puzzleSpecificAttributes; @end
This totally defies the purpose of immutability. Even though the property itself is read-only, users of the class are free to modify the mutable dictionary that is returned by the class’s getter. If your class relies internally on the dictionary not being changed, things can get really ugly.
How do we avoid this? The public-facing property must be an NSDictionary:
@property (readonly) NSDictionary *puzzleSpecificAttributes;
But chances are that, internally, you would still like to keep the mutable dictionary. In that case, rename the instance variable so that it does not conflict with the name of the read-only property and, in the implementation of your class, write a custom getter that converts the mutable to an immutable dictionary:
@implementation WordInformation @dynamic puzzleSpecificAttributes; // ... - (NSDictionary *)puzzleSpecificAttributes { // mutablePuzzleSpecificAttributes is the mutable instance variable return [NSDictionary dictionaryWithDictionary:mutablePuzzleSpecificAttributes]; } // ... @end
OBShapedButton: Non-rectangular buttons on the iPhone
UIButton has always been capable of displaying buttons with arbitrary non-rectangular shapes. All you have to do is use PNG images with alpha channels to define the transparent parts of the bounds rectangle.
While a button’s shape may be arbitrary, UIButton always responds to touches within its entire bounds, however. This could cause problems and confusion for the users, especially when multiple non-rectangular buttons are placed close together so that their frames overlap.
OBShapedButton is a replacement for UIButton that solves this issue. Instances of OBShapedButton only respond to touches where the button image is non-transparent. Here’s how to use it:
- Get the code from GitHub.
- Add
OBShapedButton.h,OBShapedButton.m,UIImage+ColorAtPixel.h, andUIImage+ColorAtPixel.mto your Xcode project. - Design your UI in Interface Builder with UIButtons as usual. Set the Button type to Custom and provide transparent PNG images for the different control states as needed.
- In the Identity Inspector in Interface Builder, set the Class of the button to OBShapedButton.
That’s it! Build and run the enclosed demo project to check it out. I am releasing this under the MIT license.
The Apple Symbols font: a great repository for iPhone button icons
For iPhone developers looking for icons to use in buttons, toolbars, navigation bars and tab bars, there are a few good resources available, for example Joseph Wain’s excellent (and free!) collection of 130 icons and Eddie Wilson’s set of 160 iPhone UI icons ($69). These are not only beautifully designed but also already have the right sizes and format for use in toolbars and tab bars.
If you are not afraid of making your own PNGs, there is another free and hidden treasure in every Mac OS X installation: the Apple Symbols font. It contains many of the icons Apple uses in the built-in iPhone apps and makes them readily available for your own buttons.
Background: standard buttons in the iPhone SDK
The set of standard buttons that Apple ships with the iPhone SDK is quite limited in both number and context. For instance, the standard toolbar buttons can only be used inside a UIBarButtonItem on a toolbar or navigation bar. Now, this is a good thing, I hear you say, because it enforces consistent UIs. And I agree to a point. Specifically, I urge you to follow Apple’s Human Interface Guidelines and use the system-provided buttons for (and only for) their documented meanings or you risk the rejection of your app.
Icons for buttons, toolbars/navigation bars and tab bars shipped with the iPhone SDK
Apple Symbols to the rescue
If the standard buttons do not cover your needs or ff you need to use one of the standard toolbar buttons outside of a toolbar (in a simple UIButton, for example), you are out of luck. But Apple Symbols contains many more standard icons for your icon-making pleasure. Open the OS X Character Viewer in Glyph View, select the Apple Symbols font and scroll down to the very end of the Glyph Catalog:

The Apple Symbols font in Character Viewer
Making a button from one of these glyphs is as simple as inserting it into Photoshop or any other graphics software that can work with fonts, resizing it, and saving it as a transparent PNG. Use about 20⨉20 pixels for toolbar and navbar icons, and about 30⨉30 pixels for tab bar icons and other buttons.
Am I allowed to do this?
I am not a lawyer but I have not found any restrictions that would forbid the use of these glyphs in your apps. This is what the Mac OS X license agreement has to say about fonts:
D. Fonts. Subject to the terms and conditions of this License, you may use the fonts included with the Apple Software to display and print content while running the Apple Software; however, you may only embed fonts in content if that is permitted by the embedding restrictions accompanying the font in question. These embedding restrictions can be found in the Font Book/Preview/Show Font Info panel.
And Font Book lists no license or embedding restrictions for Apple Symbols:

Updated iTunes Connect Financial Reports to HTML script
A user of my iTunes Connect Financial Reports to HTML script notified me that the script did not work on the file format that Apple used for their Financial Reports until January, 2009. The fix was relatively simple so the new version should support both formats.
I used the occasion for a few more changes:
- I renamed the script to
itunesconnect2html.rb. - I moved the HTML template to a separate file (instead of inlining the HTML code in the script), which makes the HTML much easier to customize and the code a lot cleaner. Win-win! ERB connects the two.
- Added a README.txt with some documentation.
- Fixed a bug that caused a crash when calling the script from another folder.
- Moved the whole thing to GitHub.
Please get the updated code from GitHub. I’d appreciate your feedback and/or bug reports.
Managing the Network Activity Indicator
iPhone developers should use the little network activity indicator in the iPhone’s status bar to inform the user when their app accesses the network. Showing or hiding the indicator is simple:
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
Most people probably call this method from their view controllers. This works fine until you have to deal with multiple concurrent tasks that access the network and/or multiple view controllers that are active simultaneously. For example, you might be running a HTTP request to download data from a webservice in the background and using a MKMapView instance that accesses the network whenever the user moves the map to a new location.
If you access the networkActivityIndicatorVisible property directly from multiple methods in these cases, chances are that you hide the indicator when the first task has finished even though your app continues to access the network. You would need to implement a counter to remember how often the network activity indicator has been shown and hidden to manage it correctly. If your code is spread among multiple view controllers, this gets even more cumbersome.
This “problem” is admittedly a small aspect of usability but the solution is so simple and elegant that I think it is worth doing even if you do not deal with multiple concurrent network activity tasks in your app.
Since the network activity indicator is displayed outside of your app’s window, the logical place to manage it is not a view controller but the application delegate. I have written a short method in my app delegate that uses a static variable to keep track of the number of times the activity indicator was asked to show or hide:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - (void)setNetworkActivityIndicatorVisible:(BOOL)setVisible { static NSInteger NumberOfCallsToSetVisible = 0; if (setVisible) NumberOfCallsToSetVisible++; else NumberOfCallsToSetVisible--; // The assertion helps to find programmer errors in activity indicator management. // Since a negative NumberOfCallsToSetVisible is not a fatal error, // it should probably be removed from production code. NSAssert(NumberOfCallsToSetVisible >= 0, @"Network Activity Indicator was asked to hide more often than shown"); // Display the indicator as long as our static counter is > 0. [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:(NumberOfCallsToSetVisible > 0)]; } |
This method alone is then responsible for the actual call to the UIApplication instance to show or hide the indicator. All view controllers call the method on the app delegate instead:
[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] setNetworkActivityIndicatorVisible:YES];

