How We Build SDKs Developers Love

Visual Studio App Center

We—the Visual Studio App Center development team—have released SDKs for Android, iOS, React Native, UWP and Xamarin, with more in the works. As we build new tools, we do so knowing that many are successors to popular SDKs, like HockeyApp, that developers already use and love (for good reason).

When we started working on App Center, we knew we had to not only build new, exciting features, but take the existing SDKs’ hard-earned developer satisfaction into account. We’ve learned a lot along the way (and continue to learn!), and we’re sharing our story today to help you build your own amazing SDKs that your team, friends, and developers around the world will love to use.

So, how are we making our SDKs better than ever, so it’s easier for you, and all developers, to ship great apps?  

Step 0: Step Back

With years of customer feedback from the existing SDKs , it was tempting to start coding. But, we’re not ones to succumb to temptation; we began with a pause, and this was possibly the most productive part of the process.

Here’s why:

  • Some of us hadn’t worked together before. Spending time discussing perspectives and working through a few “arguments” helped us build a team.
  • We gave ourselves an opportunity to take a step back, reevaluating and fleshing out our spec (before we got too deep in development).
  • We established core values that have guided us throughout the whole process of designing and coding our SDKs. Read our post on code review for more info.

Champions of open-source: Linux Foundation Executive Director Jim Zemlin, Microsoft EVP Scott Guthrie and GitHub CEO Chris Wanstrath at Microsoft Connect(); 2016

Step 1: Work in the Open

We wanted to open-source our SDKs and work in public as much as possible. With full support from our leadership team (in 2016, Microsoft was named the #1 contributor on GitHub), we made our SDK public the day we entered public preview. We do pull requests in the open, and our users contribute their code, file issues, and ask for features in our public repos.

Was working in public a little terrifying at first? Yes, but it’s also very rewarding. Other developers see what we’re working on, support is much more transparent, and we foster a greater sense of trust, since anyone can verify that things work “as advertised.” There are no black boxes, just coding, learning, and iterating.

Head over to GitHub to join the discussion, fork your own code, and see what we’re up to.

Step 2: Delight Developers

As developers who use SDKs ourselves,user experience is extremely important to us. We want to create SDKs that are accessible to any developer (inexperienced to expert), easy and quick to use, and just generally delightful.

But what’s a “delightful” SDK experience? We use four guiding principles:  

  1. Stay Transparent: We weighed two fundamental approaches to setup, start and customization: configuration in code vs. configuration through a configuration file. Initially, the file-based approach sounded appealing; developers would add a dependency to App Center in their apps, download a configuration file, and be ready to go. But ultimately, we opted for a code-based solution, because:  

    • Less Complexity: A configuration file makes it easy to get up and running with an SDK, but sophisticated functionality (e.g. adding APIs to allow configuration at runtime) often results in complex scenarios that require configuration files and code. This makes it harder for to keep track of what, where, and when you’ve made changes – which is exactly what we were trying to avoid.
    • Avoiding the “Black Box”: Configuration files get messy. As multiple developers modify a project, they end up with a file containing configurations and variables that they’ve never seen before. On top of that, they need to be human readable, so they are either JSON or XML. While both are definitely human-readable, they are not fun to look at.
    • Ultimate Developer Control: There’s something appealing about being able to start, stop, enable, configure and customize an SDK to your needs. With code-based solutions, no additional config file can override what you’ve done in your setup code – and, with our SDK, developers explicitly enable each App Center feature.
    • Simplified Support: As explained, it’s very likely to end up with configuration and setup done in code and the configuration file. On the flip side, with code-based solutions, you configure SDKs in one place (code), so you – and your QA team – easily verify and debug issues. In addition, it’s a lot easier for us and our support team to understand what’s going on in case where something doesn’t work right for you.

     

  2. Keep it Simple, Within Reason: Simplicity is key. We know developers are more likely to use something, and continue to use it, if it’s dead simple. With this as our guiding principle, we made sure our two-step integration was just:  

    1. Add the dependency to App Center (using your target platform’s preferred method to manage dependencies).
    2. Add one line of code.

      Like all developers, we’re always balancing functionality tradeoffs and we avoid adding complexity whenever possible – but we’re flexible. For example: initially, we planned to limit ourselves to a single API to start the SDK, but conversations with our customers helped us realize that we needed to offer more customization options. In the end, we chose to make it possible to setup and start the SDKs with just one line of code, but we provide various APIs to allow for custom behaviors. This adds complexity but helps us achieve our mission and fit into any developer’s workflow.

    Still, we say “no” more than we say “yes” (or, at least to adding a new API or making any changes that complicate the product).

  3.  

  4. Tread Lightly: Ease-of-use is irrelevant if your product or service causes compiler warnings, slowdowns, or (worst) crashes. We’ve structured our team and our development processes to uphold utmost quality and minimize overhead with two key mandates:  

    • Reduce Performance Impact: Our SDKs are modular, so our users only integrate what they need. We want you to use all of our amazing features, but you might have other plans or existing tools. We require one very small binary that includes shared code, (e.g., for network i/o), and each App Center service is its own module. While our total footprint–even with every service active–is minimal, we want to provide the most optimized experience we can, so if you’re not using a service, you can pare down your app size even more. That said, even if include all of our services, the App Center SDKs are very small.
    • Reduce Human Error: As Lukas’ shared in How We Do Code Review, we all review team members’ pull requests. We set up continuous integration and continuous deployment to prevent errors in the first place and help us detect errors as soon as possible. Lastly, we perform integration tests and end-to-end UI tests on a huge variety of devices and OS versions. We not only build App Center, we use App Center and are huge advocates of CI/CD, automation, and eliminating repetitive, error-prone manual processes.
  5.  

  6. Be Consistent: Each mobile platform and toolchain has its own APIs, programming languages, history, and conventions. To be “delightful,” our SDKs need to respect each environment’s conventions, and our APIs need to feel natural and familiar.At the same time, we want to be as consistent as possible across all of our SDKs, simplifying life for multi-platform developers (…and our team!).

    It’s a balancing act, but we’ve found the solution that works for us and for our customers: regardless of language or framework, just one line of code to configure and start the App Center SDK. Here are some examples from the Java, Swift, and C# (Xamarin) implementations:

    AppCenter.start(getApplication(), "{Your App Secret}", Analytics.class, Crashes.class);

    MSAppCenter.start("{Your App Secret}", withServices: [MSAnalytics.self, MSCrashes.self])

    AppCenter.Start("{Your App Secret}", typeof(Analytics), typeof(Crashes));

    Each is easily understandable to developers well versed in a development language, but there’s enough consistency across the implementations to make multi-platform development simple.

    Lastly, to make it easier to learn how to use new modules, we’re consistent across all of our SDKs. For example, if you’re using the App Center Analytics, there’s a method to enable or disable it at runtime. When you add App Center Push to your app, you can (rightfully) assume that there’s a method with the same signature to enable or disable at runtime, too.

Here’s to the Future

No process is perfect (continuous innovation FTW!), but these principles allow us to focus on our mission, yet are flexible and applicable to a wide range of circumstances.

We’re excited to use them as our guide in our next phase of development, and further refine them as we tackle and ship the many features on our roadmap.

We’re on a mission to develop SDKs, tools, and services that developers love, so you focus on delivering apps that users love. Get started for free with App Center to explore our SDKs and developer-friendly APIs and services, and let us know what you think!

0 comments

Discussion is closed.

Feedback usabilla icon