Until I joined my current team at Rakuten I hadn't really thought much about the SDKs (aka libraries) that I had been adding to my mobile apps. Adding 3rd party code or an SDK was just a way to get a UI feature or functionality added (e.g. crash reporting) in a shorter time and with - in theory - lower risk.
However, in the last few years at Rakuten I've thought a lot about how to build SDKs - and so I should, because it is our team's mission to deliver high quality mobile SDKs.😅
Most teams in companies that provide in-house SDKs seem to either provide a general SDK covering everything or maybe an authentication SDK and a function x SDK. Also, based on chats I've had when interviewing, what they call SDKs are often just separate modules in the same source repo with no proper deployment. There's absolutely nothing wrong with that but it's hard to scale.
In the MTSD SDK team we have a mix of long-term and newer products that add up to a significant number - to give you an idea, a major focus during the last year was trying to reduce our supported products from the current 16 to fewer than 10.
Many of our SDKs are stable long-term products that don't have a regular delivery schedule but our team still needs to be able to maintain and release new versions of those products when required, sometimes at relatively short notice. Our team is fairly small (2-3 devs per iOS/Android) so other than urgent maintenance/bug-fixing tasks we try to focus on active development of a couple of products at any particular time. But due to 💩 happens we need to be responsive to changes in priority.
In this post I want to focus on how we (mostly I think) achieve building and delivering high quality mobile SDKs at Rakuten scale.
We have recently open sourced our mobile SDK development guidelines on GitHub - we use these in our team to maintain quality, to help onboard new engineers, and to share our approach with other Rakuten teams who ask for our input when building their own SDKs.
The guidelines are a bit (ok, very) dry so here's an image I made for an internal Tech Community presentation to highlight the (often hidden) team effort and the various aspects that go into continuous delivery of multiple SDKs - while keeping high quality and with minimal overhead.
Let's explore what's hidden below the iceberg's surface 🤿
To give app developers a great experience with our products we strive for our SDKs to be:
- High quality
- Peer reviewed code
- Automated unit tests that are run by CI on every PR/merge
- Easy to use
- Simple, fluent APIs
- Excellent user documentation
- Responsive developer support
- Easily integrated
- CocoaPods/Gradle dependency
- Configured in zero-to-a-few lines of code
- Deployed by automation
- Minimize effort
- Minimize risk of human error
- Limit dependencies
- Only expose what must be exposed
- Components loosely coupled
- Robust and secure
- Properly versioned
- Following semantic versioning
- Consistent between platforms
- Same API interface
- Same high-level architecture
- Maintainable long term
- Stable after reaching v1.0
- At least 6 months notice of end of life
Our team mindset is one of continual improvement. Due to the nature of SDK development we can't always move as fast as app teams. This is mostly a benefit in my opinion and allows us to come up with technical and process improvements that are sustainable.
I think our team has reached a good maturity level but there will always be aspects we can improve. For example, in Q2/Q3 last year we undertook a PoC with bitrise CI (which is specifically designed for mobile teams). The PoC was successful and during Q4 we migrated all SDK iOS pull request CI from Jenkins/travis to bitrise.
We could (and intend to) also improve the documentation of our internal SDKs - docs are generated using Doxygen on iOS - they are a bit old-school (though functional) and in need of a revamp. Our open source repos e.g. In-App Messaging have much nicer docs generated by Jazzy and hosted on GitHub Pages.
If you're an iOS developer, a more technical blog post that I read when I was quite new to working on iOS SDKs was https://academy.realm.io/posts/altconf-conrad-kramer-writing-iOS-sdk/. I think the advice is still highly relevant - a key difference now is that it's likely preferable to build your iOS SDKs using Swift because of its safety, conciseness and readability benefits over Objective-C and, crucially, it has gained module and ABI stability for compatibility between different Swift versions.
While ABI Stability allows programs written with different versions of Swift to exist in a shared runtime, Module Stability allows you to use frameworks compiled with
different versions of Swift in a project that might use yet another version of Swift.
I hope you found the above post interesting and perhaps useful. Please comment or reach out if you'd like to discuss anything about building mobile SDKs.