Here at the Omni Group, we have a long history of writing code in Objective-C.
All of the apps we currently sell are written in Objective-C, and those of you
that follow our public frameworks will
know they’re entirely Objective-C as well.

However, we recently faced a new challenge with our decision to bring
Push-Triggered Sync to OmniFocus on Mac and iOS. Apple’s architecture for
sending push notifications requires that we use a server-side component called a
provider. And while Objective-C was our forte, it was ill-suited for server-side
development, since almost none of Omni’s servers run OS X.

Thus, our attention turned to building a provider that could handle the large
existing OmniFocus customer base, along with the specific traffic patterns the
app generates. (For example, the Omni Sync
Server often sees large traffic spikes early
Monday mornings, as OmniFocus users get started on their work weeks.) What’s
more, we wanted this provider to fit well in our existing server setup, which is
gradually moving towards using FreeBSD.

With these constraints in mind, we settled on the Go
language for implementing a push provider. Go had several
properties that we felt made it a good fit for this feature:

It was explicitly targeted at system-level services, rather than our usual
focus on apps with rich user interfaces. In particular, Go’s multitasking
features (such as first-class functions and goroutines) made it well suited
for building a parallelizable server.

It has a strong standard library, especially around networking and
manipulating arrays of bytes directly — two especially relevant topics for
interacting with Apple’s binary notifications interface across the Internet.

It is a relatively young language, and so is able to take advantage of recent
advancements and best practices in language design. On the flip side, it’s not
too young: with Go 1.4, the language has reached a level of maturity
sufficient to freeze the API, providing a certain amount of stability in Go
projects.

It’s a compiled language with FreeBSD as a “first-class” targeted platform,
giving us confidence that we could deploy a provider binary across our hosting
infrastructure without needing a custom environment or runtime installed up
front.

After settling on Go, we also considered various open-source packages for
speeding up early development. And while we did wind up using a few (for tasks
like MySQL and PostgreSQL database access, as well as logging), existing
frameworks for communicating with Apple’s push service (APNs) didn’t quite look
as fully-formed as we would’ve liked.

With that, the stage was set: in Go, build an internal framework for
communicating with APNs, then use it in a provider daemon that could power push
notifications for the hundreds of thousands of customers that rely on OmniFocus
every day. We’ll discuss more about specific implementation details next.