How to create a pure swift module

How to create a pure swift module

From scratch, Swift is an innovative programming language for iOS, OS X, watchOS, and tvOS apps that forms on the best of C and Objective-C, without the constraints of C compatibility. Swift adopts safe programming templates and adds modern features to make programming easier. Moreover, programming with Swift becomes more flexible and fun. Swift’s clean slate, backed by the mature and regularly preferred Cocoa and Cocoa Touch frameworks, is a great chance to reimagine how software development works.


If you are already in touch with Swift, you probably assumed that including third party libraries into your project would be useful. Railsware.com Mobile Developers and Alex Denisov, iOS Engineer and a huge Open Source fan, are ready to talk about it.

Making a custom framework that includes both ObjC and Swift code is very easy because Apple provides a mechanism to distribute code via frameworks (eventually, for iOS too). Next step into proper development is a creation of a pure Swift module, like Apple does with Swift’ std lib and Cocoa/Cocoa Touch bridge.

Basically, we are generating a simple module call Logger that will contain only one method: log.
You need at least three files to form a Swift module, so we should get all of them as an output:
Logger.swiftmodule – public interface/definitions
Logger.swiftdoc – docs (surprisingly)
libLogger.a – built library (there also might be a dylib, it depends on your task)
We can start with creating an unserviceable Logger library:

The class just takes some prefix and logs it before actual object:

Now it’s time to make a libLogger.a. The code will look like this:

xcrun swift -emit-library -emit-object Logger.swift -sdk $(xcrun --show-sdk-path --sdk macosx) -module-name Logger
ar rcs libLogger.a Logger.o

-emit-library generates dynamically linked shared library, while -emit-object generates object file and includes main function, so you will have linker errors due to duplicated symbols.
The solution is simple: include both flags -emit-object and -emit-library, as is depicted above.

The next step is generating Logger.swiftdoc and Logger.swiftmodule:

xcrun swift -emit-module Logger.swift -sdk $(xcrun --show-sdk-path --sdk macosx) -module-name Logger

Now that you have a complete module, it is about time to integrate it into a real project. Create a simple Swift project and add the files:

Then setup “Import paths” for Swift:

You can now check out if your project works properly:

Voila!

Dealing with documentation is rather simple, as well. To add documentation to module you need to comment it using ///, e.g.:

You will see documentation on the right after its integration:

Note: to make it work after integrating, you have to restart Xcode.
This approach might not be applied for a regular iOS/OSX developer; it requires creating and supporting Make/CMake file, which complicates the process of generation. However, it may be useful if you want to create a pure module that does not include ObjC at all.

This is a guest post by Alex Denisov