Monthly Archives: November 2015

NilError

I think that everybody knows how the error handling works when you call Objective-C methods from Swift. If you accidentally missed it, here’s quote from the Using Swift with Cocoa and Objective-C book:

In Cocoa, methods that produce errors take an NSError pointer parameter as their last parameter, which populates its argument with an NSError object if an error occurs. Swift automatically translates Objective-C methods that produce errors into methods that throw an error according to Swift’s native error handling functionality.

Read this book to learn more. I’m going to focus on one corner case only.

Continue reading

Application features

Every application contains huge or small amount of features I would like to enable
or disable based on environment – launched from Xcode, outside of Xcode,

Conditional compilation is evil and I’m trying to avoid it. It’s not black & white
and I agree that there are some cases where you can’t avoid it – like Mac App Store –
static code analysis. But that’s not the case now.

Here’s the part of my application delegate.

func applicationDidFinishLaunching(aNotification: NSNotification) {
if Features.MoveToApplications.enabled {
PFMoveToApplicationsFolderIfNecessary()
}
}

Move application to the /Applications folder if application is located
elsewhere and do it only and only if this particular feature is enabled.

Here’s the snippet where I define application features.

enum Features {
static let MoveToApplications = Feature(name: "MOVETOAPPS", defaultState: true)
}

MOVETOAPPS is part of the feature environment variable name. Full name is
FEATURE_MOVETOAPPS_ENABLED. defaultState says if the feature is enabled
or disabled by default and this state is used as well in case where the environment
variable value can’t be parsed.

The beauty comes with Xcode schemes where I can define environment variables
for different actions.

Disable MOVETOAPPS feature when launched from the Xcode.

Another nice thing is that I can (de)activate this environment variable
with checkbox on the left side of my environment variable.

There are other benefits as well:

  • I can disable / enable feature via environment variables in schemes.
  • I’m not forced to touch code and recompile.
  • No accidental commits of disabled features.
  • I’m 100% sure that when I release the application that the feature will
    be there and working.

Nice, isn’t it? Use this or similar way whenever possible to avoid
evil conditional compilation.

And finally here’s the Feature structure I do use.

public struct Feature {
let name: String
let defaultState: Bool

init(name: String, defaultState: Bool) {
self.name = name
self.defaultState = defaultState
}

var enabled: Bool {
guard let stringValue = NSProcessInfo.processInfo().environment["FEATURE_(name)_ENABLED"],
value = Int(stringValue) else {

// Either variable is not set or we can't convert value to integer, ignore it
return defaultState
}

// Like C - 0 is false everything else is true
return value != 0
}
}