SPM-ifying YapDatabase
Converting an existing Objective-C/Swift framework to Swift Package Manager
I’m a big fan of the database library YapDatabase, which is a collection/key/value store for macOS, iOS, tvOS & watchOS. It comes with many high level features and is built atop sqlite.
In the last 5 years, I have used this successfully for many of my projects. It is written in Objective-C and comes with a bunch of Swift files for more Swifty use. Since I recently announced to go all-in with Swift, I want to convert all my dependencies to the Swift Package Management system. I have never been a fan of CocoaPods or Carthage as I found them too invasive.
As this point of time though, YapDatabase is not Swift Package Manager (SPM) compatible and all approaches to do this using the current source layout did fail. So I had a fresh look at it and decided to do it slightly differently: If you don’t have to work with the constraints of an existing tree layout, the process is relatively straightforward. Read on to find out what I did.
Prerequisites
- Use
swift package initto create a package named YapDatabase. - Edit
Package.swiftto make the package create two libraries with associated targetsObjCYapDatabaseis going to hold the Objective-C part inSources/ObjCYapDatabase,SwiftYapDatabaseis going to hold the Swift parts inSources/SwiftYapDatabase.
I couldn’t name the Objective-C library simply YapDatabase, since this would have required to rename the (then umbrella) header file YapDatabase.h, which I didn’t want to.
Swift vs. Objective-C
At the moment, SPM is not capable of handling mixed language targets, i.e., you either have only Swift files or no Swift files at all in your target – therefore I split the repository accordingly and moved Swift files below Sources/SwiftYapDatabase.
Source and Header file locations
SPM is pretty rigid when it comes to the location of source and header files. This is the reason why I unfortunately could not deliver this work on top of the original source repository.
Fortunately though, the source repository was very well structured. To layout the files in a way that makes SPM happy, I
- Created two header file directory,
includefor public headers,privateIncludefor private headers. - Moved all header files from
Internaldirectories and those withprivatein their name to theprivateIncludedirectory. - Moved the remaining header files to the public
includedirectory.
Swift
The aforementioned steps were enough to make SPM compile the ObjCYapDatabase. To make the Swift part compile, I had to
- Edit all Swift files to import
ObjCYapDatabaseinstead ofFoundationviased -i -e s,Foundation,ObjCYapDatabase,g *.swift.
This made the SwiftYapDatabase compile.
What’s Next
There are some parts missing: I didn’t include the example programs, the tests, and the Xcode project.
I don’t know Robbie Hanson’s (creator of YapDatabase) plans. As it stands, this shuffling around was merely a proof-of-concept to find out whether such an approach is sufficient to SPM-ify YapDatabase or whether to there are more problems to consider. I will incorporate this in one of my projects to put it through a real world test.
I have published the repository as SwiftYapDatabase and will report this work via the YapDatabase issue tracker. Let’s see what happens next.