In 2016 we launched an iOS app to test whether customers would respond well to automation. It turns out they do! In fact, that minimal viable product now generates hundreds of thousands in revenue (also thanks to our fantastic growth marketing team).
As a minimum viable product, we racked up a bit of technical debt, and as the app was written in Objective-C we made the decision to re-build in Swift in preparation for a host of new products, new features, the introduction of an exciting list of data science components, and a much better architecture that will help us scale up faster.
At the same time, we’ve rebuilt our platform using a microservices architecture, primarily written in Go and started work on our Android app.
You’ll be glad to hear that we believe in building native apps, in-house, for the best customer experience.
We never outsource development because attention to detail is paramount at Popsa; this means beautifully smooth animations, optimised loading times, and features built to stand the test of time. We work really closely cross-team to achieve this; everyone here is responsible for the growth of the company, and that includes getting involved in a bit of QA to catch issues before our customers do.
We use a few interesting technologies:
On our most complicated views, we use Texture (formerly AsyncDisplayKit) instead of AutoLayout. It lets us do the most complicated layouts off the main thread, keeping the app buttery smooth. There’s definitely a learning curve but it’s definitely worth it for the perceived performance benefits.
Protocol Buffers were a new concept to us when we started the project in 2017, but they have been a fundamental improvement in our network stack. In fact, we’ve reduced API transmission overhead by 70%. Win.
Rest of Stack
Other than that, we’re using Realm for a persistence layer and AlamoFire for networking (as you might expect). Both are nicely abstracted away behind a repository layer.
The app's overall architecture implements the Coordinator pattern which has really simplified several navigation-based complexities.
In terms of libraries/SDKs, we're using SnapKit, MixPanel, Facebook, Dropbox, Stripe, Pusher, Fabric/Crashlytics, TwitterKit, IGListKit, AppsFlyer and CardIO.
As I write this, we’re building out a CI pipeline to automate unit testing and build deployment. We’re always trying to get better at testing; being pragmatic, not dogmatic, about code-coverage; so we aspire to practice more TDD, especially when building critical features.
This year we’ll be moving into a new phase for the business as we start bringing some of our data science and machine learning initiatives through to production environments.
In that light it is incredibly important to us that client-side engineers integrate with and are interested in the automation technology too. We’re aiming to do as much data-analysis and machine learning on-device as possible — this has the dual benefit of keeping customer data private and enabling low-latency features (that don’t need the network for results).
We really fortunate to have hundreds of thousands of users — this means we can quickly test out ideas that improve conversion and retention, then watch the results come in quickly.
This “growth experiment” culture is also really important to us, and so we’ll be looking for people with the dedication and enthusiasm to keep iterating and get results. Here’s just one example of of a small change in our iOS app that had a big impact on revenue:
Growth Hack: How we boosted first-time orders by 1000% virtually overnight.