Desdemona 0.4.1
October 9, 2007
I’ve released a new version of Desdemona, my Reversi game. From the release note:
Fixed a nasty bug in the AI which could lead it to make strange (and terrible) moves near the end of the game. Also fixed an error in the search optimisation code that caused the AI to perform much weaker than it should be.
Given the latter fix I also took the opportunity to overhaul the difficulty levels. There was too little difference between them. The same range of levels from 1-10 is available, but they now represent a wider range of ability in the AI.
Difficulty level 1 is about the same as it was before. However, at level 10 it will now take about 22 seconds to search for a move, up from about 10 seconds previously. (Because of the bugfixes, however, the prior version would have to use about 5 minutes or more to perform as well!)
Cocoa JSON Framework v0.2—now with pretty-printing!
September 29, 2007
You can now produce human-readable JSON! There is a new method that takes options to control the formatting.
The public methods were renamed to jive better with existing Cocoa conventions. The affected methods are as follows:
- -JSONString was renamed -JSONRepresentation
- -JSONStringFragment was renamed -JSONFragment
- -objectFromJSON was renamed -JSONValue
- -objectFromJSONFragment was renamed -JSONFragmentValue
See the website for up-to-date documentation.
I released version 1 a little while ago.
Cocoa JSON Framework v0.1
September 23, 2007
I’m proud to release version 0.1 of my JSON framework for Cocoa! Other people have released code to work with JSON in Cocoa, but this would appear to be the first project to provide an stand-alone framework (an embedded one at that).
From the website:
This framework contains a collection of categories on existing Cocoa classes that together provide full JSON support. Importing the
<JSON/JSON.h>header provides the following main methods:-[NSArray JSONString]; -[NSDictionary JSONString]; -[NSString objectFromJSON];Strictly speaking JSON has to have at least one top-level container (array or object/dictionary). Nulls, numbers, booleans and strings cannot be represented in strict JSON on their own. It can be quite convenient to pretend that such JSON fragments are valid JSON and the following methods will let you do so:
-[NSNull JSONStringFragment]; -[NSNumber JSONStringFragment]; -[NSString JSONStringFragment]; -[NSString objectFromJSONFragment];
Edited for clarity after original posting.
Updated: I’ve released version 0.2 now.
I released version 1 a little while ago.
Embedding Cocoa Frameworks
September 22, 2007
Cocoa has a really neat feature that allows you to embed a framework inside your application bundle. Why would you want to do this? Not all frameworks are available everywhere. Instead of forcing your users to install lots of frameworks before they can start using your app, simply bundle them inside your app.
You cannot simply embed any framework; it has to be built specifically for embedding. A framework is a dynamically linked library. These have the path they are installed at hardcoded inside them. (For security reasons, or some such; it’s damn inconvenient at any rate.) Normally these paths are of the form `/Library/Frameworks/`. For an embedded framework, however, we have to use something else. The special path `@executable_path` refers to the path of the executable inside your application bundle. You can then refer to the `Frameworks` directory in your application bundle by setting the installation path of your framework to be `@executable_path/../Frameworks`.
If you want to embed a framework inside another framework you’ll need the even more special `@loader_path`, which is only available in OS X 10.4 Tiger and later. I find this useful, so that’s what I used in the example above. Now add the framework to your application the way you’d add any other existing framework:

Add a “copy files” build phase and chose destination `Frameworks`. Drag the embedded framework you added into it.

Voilá!
Jonathan “Wolf” Rentzsch has a screencast that shows you in more detail how to embed frameworks. It is for a rather older version of Xcode than what is available now, but it is still good. The Cocoa developer guide to embedding a framework is also good.
Objective-C JSON again
September 13, 2007
As I mentioned in my previous post I’m currently writing an Objective-C JSON framework. Now, I’ve run into an issue that I’m not sure how to handle: JSON only supports strings as dictionary keys, but Objective-C supports other types as well, for example numbers. The bit I’m stuck on is this:
When encoding a dictionary, should I throw an error as soon as I encounter a non-string dictionary key? Or should I try to mangle it into a string?
Mangling numbers into strings will probably work reasonably well. Converting back from JSON will give you an NSString instead of an NSNumber instance back, but given that you can often treat strings as numbers this will probably work reasonably well. However. However. In Objective-C you can use nulls, dictionaries, or arrays as dictionary keys. (It might not necessarily be a good idea, however.) You simply cannot encode such structures into JSON and get something meaningful back.
Teddy-bear debugging strikes again. By taking time to formulate my predicament as a plea for help to the metaphorical teddy-bear that is the interweb things have become clearer in my mind and I have managed to reach a decision all on my own. I shall make my JSON library throw a hissy fit if it encounters a non-string dictionary key.
Playing with JSON and NSScanner
September 12, 2007
I’ve been playing around trying to parse and generate JSON from Objective-C the last few days. The core of the parser takes the form of a category on NSScanner, and I’m really chuffed with how neat and clear the code turned out. A tip of the hat to the designers of Objective-C and NSScanner!
A category—though originally conceived as a way to split large classes into multiple files (at least this is my understanding)—can be used to extend classes at run-time. This is a feature that is most commonly associated with interpreted languages. Used soberly it can be used to great effect to add functionality to a class without having to subclass it. You can add methods, and even override existing ones, but not add any instance variables.
The JSON Framework I’m working on provides no public classes on its own. Instead it adds a method to NSString that returns an object structure representing the JSON string. To emit JSON for a complex structure I’ve added a method to NSObject that will do the right thing for nulls, booleans, numbers, arrays, dictionaries and strings.
Please be aware that the code at point is the result of just one night and 2 days of coding. There are no docs. There are no options. There are no limits, so if you feed it carefully crafted JSON you can make my parser run out of C stack space. There is working proof-of-concept code, copyright statements, and tests.
Update 24/9/07: I’ve released version 0.1 of my JSON framework now.
Goodbye GPL, hello BSD?
September 2, 2007
Here’s a question that’s been on my mind lately:
Should I switch away from using the GPLv2 for my software?
So far I’ve been using the GPLv2, but now that it has been superseded by version 3 I’m a bit at a loss at what to use for new projects. Do I stick with using version 2? Do I read and try to understand version 3 enough that I’m comfortable using it? Or do I use something else entirely?
It’s important to me that I’m able to fully comprehend the license I put on my own software. The BSD license wins hands down in this category: it is short and written in very simple language. For comparison here’s the number of words in the BSD, GPLv2 and GPLv3 licenses:
| License | Number of words | Number of lines |
|---|---|---|
| BSD | 223 | 26 |
| GPL2 | 2968 | 340 |
| GPL3 | 5644 | 674 |
A strong argument in favour of the BSD license there, but the length of each license is not the full story. Lowering the barrier of entry is also important. You can use BSD-licensed code in any closed-source applications—be it a commercial application or binary-only freeware. (Maybe you’re too embarrassed of the code to release it?)
More users means increased likelyhood of receiving feedback—in the form of code, bug reports or otherwise—that benefit all users. Thus I’d rather have a larger pool of “free” and “non-free” users than a smaller pool of “free” users of my software, even if the “non-free” ones use it in a commercial application and don’t directly contribute code back.
At this point I’ve pretty much made up my mind. Unless someone hits me over the head and points out a glaring flaw in my arguments upcoming releases of my software (at least the libraries) will be released under the revised BSD license.
Desdemona 0.3
May 6, 2007
I’ve released a new version of my Reversi game. In addition to numerous behind-the-scenes changes, user-visible changes in this release are:
- Cleaned up the interface and hid some of the clutter in a preferences pane.
- Added a progress indicator to indicate that things are going on in the background.
- Added a “Check for updates” menu item, which uses the wonderful
Sparkle framework to
check for updates. You also have the option to automatically check
for new versions on startup.
Desdemona continues to use the wonderful graphics from Gnome Iagno. It sorely needs a logo though.
Download Desdemona 0.3.1 (0.25 MB disk image). Visit the homepage.
Update, 7th May: I just fixed a bug that caused the default values for the preferences not to be registered. This could cause the AI level and board size to be used uninitialised, and could lead to crashes. I have uploaded 0.3.1, and fixed the above link to point to the good version.
Phage 0.2.1
April 30, 2007
I just fixed a bug that caused Phage to be confused about whether you or the AI had won the game. This would sometimes cause Phage to declare that the AI won the game, when in fact you had. Pesky cheating AIs. At least I get to test whether auto-updating with Sparkle works then, which I introduced in the last release.
Download Phage 0.2.1 (0.5 MB disk image). Visit the homepage.
Phage 0.2
April 26, 2007
There’s not a lot of changes in here, but one of them should make incremental releases much more manageable. I also gave the website a little face lift, so hopefully it shouldn’t scare off people now.
The changes in this release are:
- Added a progress indicator for things that go on in the background.
- Added a “Move hint” menu item. Selecting this makes the AI give
you a hint for a move. - Added a “Check for updates” menu item to check if new versions
are available, using the wonderful Sparkle framework.
You also have the option to automatically check for new
versions on startup.
Download Phage (0.5 MB disk image). Visit the homepage.