As a software developer, there’s often times I have to have files to store data, share data, or to help configure an application. The last case is a common one, because sometimes it’s easier to create a file that holds various settings, then a simple change in the data file is all you have to do to get some new behavior. Very useful for reusable code modules.
As a Mac and iOS developer, it’s natural to gravitate to Property Lists (plist). Property lists allow developers to structure fundamental data types like strings, numbers, dates, booleans, arrays, and dictionaries (and blobs of data) into data structures that can be consumed and manipulated by your app. What makes them work so well is these types map directly to object classes used in Mac and iOS development, like strings are represented by NSString objects. And plist support is quite integral to the (Core) Foundation (Kit) classes, so it works so nice and natural in Mac and iOS development; you find support and framework use of plists everywhere.
Naturally, it’s useful and logical to turn to plists when you need support. It’s simple, it’s directly supported by the OS frameworks, it’s built-in, and because you can work with plists in an XML format, it’s fairly readable and easy to edit. But XML is just a common file format today. The Property List file format has actually changed a few times over the years, and today you’ll actually find it more typically stored in a proprietary binary format. This binary plist format is great for built-apps that just have to consume (or maybe read/write) the plist files, because they will be faster to work with and generally take up less disk space. However, reading a binary file isn’t fun for editing, if you’re going to use it as say some sort of app-config file. But that’s why XML remains around, and why tools such as Xcode provide GUI editors that mask away the gory details.
But is the plist the right format for you?
Certainly can be. If I was making a Mac or iOS only app, I’d have no qualms about going for plists because it’s got first-class support and meshes well with the development environment.
But in another life, I work in a heterogeneous environment. While iOS may drive the development, Android must have parity. The app has numerous configuration files due to the great many customers supported out of the app framework (every customer wants something different). Furthermore, there’s a server component, and when you have to share things all around, it makes life easier if everyone can consume the same files and talk the same language.
So, plists really don’t work well. Sure, other platforms can support it (XML is XML), but now it’s a greater chore and maintenance hassle for the others to support it.
JSON is a very simple, but very powerful way to express data. Anything you can do with a plist? You can do it in JSON as well. Furthermore, JSON tends to yield more compact data/files than XML, but still can be quite readable (unlike binary). The data structures map naturally onto concepts supported by just about every language and library, so having parser support for JSON is natural. In fact, you’ll find Apple supports JSON natively in the OS with NSJSONSerialization. Now you have a nice way on iOS or Mac OS X to convert your JSON to native Foundation objects, and gee wasn’t that the point of Property Lists? JSON isn’t supported as integrally as Property Lists are, but that the OS provides built-in support for JSON is welcome. You’ll even find that on most other platforms, other languages, other libraries, JSON support is a natural part of things. This makes use of JSON quite nice when you work in a multi-platform situation. Just write the file once, share it, life goes on.
For the most part on that other project, JSON became the file format of choice because everyone can share the files.
But, I didn’t like it.
I have no problem with JSON; in fact, I really like JSON. I think it has a place. But I started to find a place where I just didn’t like it. Sure, all the network communication between mobile app and server uses JSON, and that’s great and works well, in part because I typically don’t have to SEE all the data, but when I do (e.g. debugging) it’s quite nice to have such a readable format. But when I’m usually looking at the data, when most of that data is consumed by my eyes and not my code, JSON just didn’t feel as right. But I reckon it didn’t feel as right because there was one place in the app where we used another format: YAML.
YAML stands for YAML Ain’t Markup Language. It is another way to express data. I had never heard of YAML before this one project, but because part of this project made extensive use of Ruby on Rails, and YAML seems to be popular in the Ruby world, I became exposed to YAML. One of my first tasks on this project was to improve the build system, from a manual effort, to one easily modular, configurable per customer, and using Jenkins to automate the build process. The per-customer-build-configuration file? Wrote it in YAML (someone else made the choice). And while I don’t have to look at that file every hour of every day, I do have to look at those files often enough.
You know what?
YAML is nicer to look at and work with — in this context.
It’s nicer to type and make edits and changes. It’s too easy when typing JSON to omit comma, or overlook a closing brace. Easy enough to fix, but it’s still a round trip and time wasted. I find I don’t have that problem with YAML.
Furthermore, the YAML tends to be more readable for visual configuration files. There are some files on this project that describe how to lay out some GUI, and the structure of YAML is more compact and more readable towards expressing that layout. It’s also easier for non- or semi-technical people to be able to read, understand, and make configurations. My experience has shown the JSON isn’t bad, but the YAML just comes across better to their eyes.
One downside to YAML is it’s more obscure. There is rarely direct support for YAML in libraries and platforms. I found an iOS/Mac OS X library called YAML.framework, which has been helpful, but isn’t as directly iOS friendly (works, if you grok Mac and can make the translations). But it only works on a basic level, converting most everything to strings. Some third parties have created preliminary support for converting to other native objects (e.g. numbers becomes NSNumber, null becomes NSNull, etc.), but it’s rudimentary and not complete nor part of the official distribution. Still, it may be suitable enough for your needs. Other platforms have to work with their own libraries as well.
So it may be a little more work to support YAML, and that extra work may not trade off right and well for you.
So, which is right? Well, it just all depends. I don’t think any one is necessarily more or less better than the other. They are all particular tools, with unique strengths and weaknesses, and a lot of overlap. I still use plists, I still use JSON, but will be adopting YAML more because there are times it just works the best for my needs. Give it a try, get yourself familiar with it, and learn where it can be useful and where it wouldn’t be appropriate. More options can be useful.
But… just say no to XML. 😉