Class- (or struct-) based namespaces in Swift

When Apple announced Swift in June 2014 namespaces was one of the things that caught my attention as I missed the ability to easily modularise code in ways similar to C++ namespaces and Java packages.

However it turned out that namespaces are implicit, and based on the name of the module in which types are included. For example if you create a Swift framework called MyCoolThing which contains a class called WidgetX a user of your framework need only use the name WidgetX in their code and the compiler will know what to do.

Naming Collisions

Imagine you have a project MyAwesomeApp which contains two frameworks MyCoolThing and SomeOtherCoolThing, what if all three contain a WidgetX? Well, you should probably have a word with yourself to start with.

While that may be a somewhat contrived example, it could happen, and they anticipated it…

Framework All The Things!?

Creating a framework for each desired namespace seems like it might be a lot of work and added complexity, especially if you’re not planning on distributing / using the frameworks outside of the project. Fortunately Swift also brought nested types to the table, allowing us to achieve namespaces a different way.

Nesting Swift

By using nested types, and extensions, you can create namespaces to as many levels as you desire (e.g. MyAwesomeLibrary.SuperNetworking.HTTP).

An example project for how this is achieved is available on GitHub at https://github.com/NxSoftware/Namespacing and I’ll give a quick walkthrough of what’s going on.

The root class SteveWilford is defined in it’s own file and, for no particular reason, contains no other code (though it would be fine to put constants or methods in this class). From now on, I’ll refer to this as the top level namespace.

Top level class/namespace

In another file I have defined a SteveWilford extension which contains a Networking class which represents the Networking namespace.

Networking namespace

Followed by the definition of HTTP and FTP classes within the SteveWilford.Networking namespace.

Networking classes

Finally, in their own files, the HTTP and FTP classes are populated with methods.

During the process of writing this post I’m started to think that it might be easier to follow if the HTTP / FTP classes were fully implemented in their own file instead of being defined at the Networking namespace level.

Usage is then as simple as referencing each nested type as normal, using the standard dot notation.

Usage

goto fail

Gotcha! Unfortunately, for some reason that I cannot fathom this implementation fails to compile.

Fail

Essentially the HTTP extension in SWHTTP.swift works just fine, but the FTP extension in SWFTP.swift doesn’t.

It will work however if the code shown above is moved to the same file where the HTTP and FTP classes are defined. This smells like a compiler bug and I have therefore filed rdar://20337822 and unless you can figure out if I’ve done something completely stupid please duplicate the Radar.

Real World Usage

Would you want to use this in a real-world, production codebase? To be honest, I’m not sure. As I alluded to earlier I’m not 100% sold on the current structure and, so far, has been nothing more than a technical exercise.

Leave a Reply

Your email address will not be published. Required fields are marked *