Simple Cocoa Configuration Using Swift Structures
You might save yourself a lot of hassle
Apple’s introduction of Swift to the Cocoa development toolbox has created a buzz amongst Cocoaheads. The language is flexible and lends itself to new patterns which traditionally Objective-C programmers are excited about. I got excited about a pattern that emerged while working on a new version of the Dead Man’s Snitch iOS app: using Swift structs to store application configuration data.
Every technology ecosystem has a de-facto way of storing application configuration. Rubyists use readable YAML. Full-stack JavaScript engineers use the clear JSON format. And Java developers have tons of XML. But for Cocoa developers, there are several choices. YAML, JSON and plists just to name a few. But I for one am not a fan of these. I would argue that Swift’s structures are a clear winner over these other options.
Here is an example of a configuration file:
// Simple Configuration Example
struct Config {
static let apiKey = "1234ABCD"
static let googleAnalyticsToken = "12321-312-1238388"
static let maxConnections = 10
}
Config.apiKey //=> "1234ABCD"
Config.googleAnalyticsToken //=> "12321-312-1238388"
Config.maxConnections //=> 10
</code>
This is much more preferable to say, using a YAML or PLIST file for configuration. To do that we’d have to create code to read in that file. And if we mis-type a key name, the application crashes with a runtime error since a value doesn’t exist for that key. With this Swift example, there’s no code which reads in a file, it just gets loaded when the application loads. As a bonus, if we don’t remember key names, XCode’s completion will remind us: simply type “Config-TAB” and we get a list of all possible options.
If you like to be organized, this format can be structured hierarchically in much the same way YAML or JSON can:
// Nested Configuration Example
struct Config {
static let maxConnections = 10
struct faceBook {
static let secret = "12341234"
static let key = "ABCD"
}
struct twitter {
static let secret = "9887"
static let key = "9723"
}
}
Config.maxConnections // 10
Config.faceBook.secret // "12341234"
Config.faceBook.key // "ABCD"
Config.twitter.secret // "9887"
Config.twitter.key // "9723"
</code>
The greatest benefit of this code-as-configuration is that the values can be any object, not just numbers and strings. Additionally there is no intermediate step between the configuration file and our code to de-serialize the configuration value into an object. Here’s an example from the Dead Man’s Snitch iOS app:
// Example: A theme file used to share common styles across obejcts
import UIKit
struct Theme {
static let debugBackground = UIColor.purpleColor()
// Buttons
static let buttonDisabled = UIColor(red:0.2431, green:0.5216, blue:0.6196, alpha:0.25)
static let buttonNormal = UIColor(red:0.2431, green:0.5216, blue:0.6196, alpha:1.0)
static let buttonSelected = UIColor(red:0.2431, green:0.5216, blue:0.6196, alpha:0.75)
static let backgroundPattern = UIColor(patternImage: UIImage(named: "pattern"))
// Typeface
static let defaultFont = UIFont(name: "ProximaNova-Regular", size:18.0)
static let navBarFont = UIFont(name: "ProximaNova-Regular", size:16.0)
}
</code>
By using a theme file rather than building up UIColors and UIFonts when they are needed, a developer doesn’t have to find every instance of say, UIColor(red:0.2431, green:0.5216, blue:0.6196, alpha:0.25)
in order to update that color throughout the application. Changes can happen in one central place, and propagate through the app.
So in your next Cocoa app, give Swift structs a try. You might save yourself a ton of hassle.
Comments
Great Article, I absolutely despise plists because I feel like I’m using a modified version of an excel worksheet. This is a great use of a struct and is far easier to maintain and find what your looking for compared to the alternatives.
Nice… Quick question;
Can you create a reference be added to change the Bundle display name in the plist file? or any other field in the plist?