YAML in Cocoa

The latest version of the YAML Cocoa parser is available from the Syck github.

What is it?

After looking at and trying to edit Cocoa's XML output files or plists I decided there must be a better solution. ...and there is. YAML. YAML, in general, is far more readable and consise than XML is. It is used extensively in scripting languages like Ruby. Here are two examples:

YAML (Look Ma' no markup):
Author    : William Shakespeare
Lines     : 
  - It is a tale told by an idiot,
  - Full of sound and fury, signifying nothing.
Birthdate : 1564
XML plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="1.0">
    <string>William Shakespeare</string>
        <string>It is a tale told by an idiot,</string>
        <string>Full of sound and fury, signifying nothing.</string>

Now you tell me which is more readable.

How to use it

Wouldn't it be great to use this in your Cocoa apps? Well now you can. Here's how you do it:

id  data = yaml_parse(yamlString);

And that's it. You can repeatedly call getDocument: to get the remaining documents in the file. At the moment all YAML scalars are read in as strings, which works happily because your code still simply calls floatValue: or intValue: .You can save documents to YAML like this:

[data yamlDescription];
The really neat bits

The stuff you can't do in xml. Anchors and references. In YAML you can do something like this:

  - Mark McGwire
  # Following node labeled SS
  - &SS Sammy Sosa
  - *SS # Subsequent occurance
  - Ken Griffey

and... you can define your own tags real easy. These combined make YAML really powerful. Tags are defined like this:

- !!NSColor {r: 1, g: 0.5, b: 0}

And here's the ObjC implementation:

@implementation NSColor (YAMLCocoaAdditions)

+(id) objectWithYAML:(id)data
  float	r=0, g=0, b=0, a=0;
  if([data isKindOfClass:[NSDictionary class]])
    if([data objectForKey:@"r"]) r = [[data objectForKey:@"r"] floatValue];
    if([data objectForKey:@"g"]) g = [[data objectForKey:@"g"] floatValue];
    if([data objectForKey:@"b"]) b = [[data objectForKey:@"b"] floatValue];
    if([data objectForKey:@"a"]) a = [[data objectForKey:@"a"] floatValue];
  return [NSColor colorWithDeviceRed:r green:g blue:b alpha:a];

-(id) toYAML
  return [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithFloat:[self redComponent]],	@"r",
    [NSNumber numberWithFloat:[self greenComponent]],	@"g",
    [NSNumber numberWithFloat:[self blueComponent]],	@"b",
    [NSNumber numberWithFloat:[self alphaComponent]],	@"a", NULL];

Now start those cogs turning

Think what you could do with all this Power!

- !!MyCircle
  center: &ORIGIN {x: 73, y: 129}
  radius: 7
- !!MyLine
  start: *ORIGIN
  finish: { x: 89, y: 102 }
- !!MyLable
  color: !cocoa/NSColor {r: 1, g: 0.9, b: 0.8, a: 0.2}
  value: Pretty vector drawing.
  start: *ORIGIN

Read it in and you will have an array of three graphical objects all linked to a particular point. The code for these classes needs to be implemented, and of course in proper tradition that is left as an exercise. But this shows how easy it is to use YAML for readable and yet complex data files.


Contact me will@thimbleby.net if anything doesn't work that you need, and especially if you have bug fixes or code to contribute.

OK, Let me at it

The latest version of the YAML Cocoa parser is available form the Syck github.