ObjectBox Swift Binding Open Sourced

Today’s 0.9 release is not just a step closer to 1.0, but also an important milestone for us: for the first time, all Swift binding source code is available on GitHub. We’ve also improved performance (again) and added useful features like type converters.

ObjectBox’ lightning-fast database offers a cross-platform C API for language-specific bindings. These bindings provide a thin and nimble wrapper around the C calls and expose ObjectBox functionality in the way that feels most natural to the host language (i.e. Swift).

An open-source binding allows you to make changes to ObjectBox and build it on your own, backport it to older OS or Swift versions, and contribute your changes back to us if you feel so inclined.

Is this the binding I’ve been using all this time?

Although it’s one of our newer language bindings, our Swift binding already has a storied and colorful history. The first Swift binding actually predates our C library and was built directly against the core C++ codebase. As such, it used Objective-C to bridge Swift and C++.

Once we had the C library, we set about eliminating the intermediary and started rewriting the central Objective-C portions as pure Swift on top of the C API. The immediate result when we released ObjectBox for Swift 0.8, was a significant speed-up in write operations due to Swift’s new native UTF-8 strings, and struct support.

But for the open source release, we completed this rewrite, and ObjectBox Swift got even faster:

Not having to bridge to Objective-C meant we could take advantage of Swift’s associated types to resolve class/entity associations instead of a runtime look-up, and eliminate a few duplicated classes necessitated by adding Swift features to Objective-C classes. This in turn allowed removing some unnecessary data copying, which translated directly to increased speed.

While we enjoy a good performance increase as much as the next database developer, we also added new features and fixes, like more query comparison operators for scalar types, and improved behavior when adding properties to an entity.

Property Converters

One major new feature of this release is support for converting simple user-defined types into types the database understands. For example, you can mark any RawRepresentable enum with an annotation to tell ObjectBox how to serialize it. Let’s say we have an enum like

enum OlympicRanking: Int { case unset = 0 case first = 100 case second = 200 case third = 300 } 1 2 3 4 5 6 enum OlympicRanking : Int { case unset = 0 case first = 100 case second = 200 case third = 300 }

In your class, you simply add the following annotation:

class Olympian: Entity { var id: Id<Olympian> = 0 // objectbox: convert = { "dbType": "Int", "default": ".unset" } var ranking: OlympicRanking ... } 1 2 3 4 5 6 7 class Olympian : Entity { var id : Id < Olympian > = 0 // objectbox: convert = { "dbType": "Int", "default": ".unset" } var ranking : OlympicRanking . . . }

But of course we also let you work with your own types, or system types. Let’s say you wanted to save a window’s dimensions into your database. You do this using a converter class that implements convert() methods that convert your custom type into one of ObjectBox’s built-in types, and back:

class RectConverter { static func convert(_ box: CGRect) -＞ String { return NSCoder.string(for: box) } static func convert(_ boxString: String?) -＞ CGRect { guard let boxString = boxString else { return .zero } return NSCoder.cgRect(for: boxString) } } 1 2 3 4 5 6 7 8 9 class RectConverter { static func convert ( _ box : CGRect ) - ＞ String { return NSCoder . string ( for : box ) } static func convert ( _ boxString : String ? ) - ＞ CGRect { guard let boxString = boxString else { return . zero } return NSCoder . cgRect ( for : boxString ) } }

And then you tell ObjectBox to use that converter using an annotation:

class InspectorWindow: Entity { var id: Id<InspectorWindow> = 0 // objectbox: convert = { "dbType": "String", "converter": "RectConverter" } var frame: CGRect ... } 1 2 3 4 5 6 7 class InspectorWindow : Entity { var id : Id < InspectorWindow > = 0 // objectbox: convert = { "dbType": "String", "converter": "RectConverter" } var frame : CGRect . . . }

That’s it.

And that’s just a selection of the changes you’ll find in the new open-source release. It contains the entire binding, but also the fork of Sourcery that does its duties as our code generator, and a performance test app. It is faster, more feature-full, and we’ve also squashed some bugs in the binding.

To take a look and get started, simply go to our ObjectBox Swift Git repository, where, in addition to our example application, you can now also find the binding’s source code. Or pull version 0.9 via CocoaPods.

We can’t wait for you to try it out and let us know what you think.