Evernote Tech Blog

The Care and Feeding of Elephants

Building apps, Metro style

A bit over a year ago we started working on Evernote for Windows Phone 7. The first task was to get our C# SDK working in Silverlight so that we could access the Evernote API. Our API is built on Apache Thrift, and the Thrift code generator and runtime for C# used .NET’s synchronous HTTP stack. Silverlight, however, only supports asynchronous networking, so our lead Windows Phone 7 engineer Damian spent some time monkeying around and getting everything to work. The result, which he documented in a detailed blog post, is a C# code generator and runtime for Thrift that support both networking models. You can find this code in our C# SDK.

Fast-forward a year and we’re working on Windows 8 Metro style JavaScript apps that will access the Evernote API from managed C# code. Once again, we’re facing incompatibilities, this time between the “.NET APIs for Metro style apps” and the Thrift runtime and generated code. I thought that I’d share what we did to get it all working, if only so that I can remember when it breaks someday.

We started by creating a Visual Studio Metro style class library project for the Evernote API wrappers and Thrift runtime classes, then resolving compiler errors. First, our code was using the asynchronous networking patterns if SILVERLIGHT was defined at compile time. For Metro, we added NETFX_CORE:

Next, the I/O classes in the .NET API for Metro style apps no longer define Close() methods (omitted as “members that cause confusion”). Microsoft was nice enough to tell us exactly what to do in this case:

Microsoft also suggests that we replace our two-stage network operations (Begin* and End*) with the new ReadAsync and the await operator, but the old patterns still seem to work, so we’ll keep it simple and not make that change right now.

Evernote clients all send a custom HTTP User-Agent header when making API calls, making it easy for us to identify calling apps in our server logs. The property that we use to set the User-Agent for Silverlight, HttpWebRequest.UserAgent, has been removed in the .NET APIs for Metro style apps. The new HttpClient API does allow us to set a custom User-Agent, but using HttpClient would require us to switch to the new await model, and as we said above, we’re not ready to make that level of change quite yet. For now, we’ll leave out the User-Agent and deal with a degraded ability to identify who’s making API requests. Since the await model is apparently the way of the future, we’ll likely build a third networking implementation using the await model eventually, and get User-Agent back when we do.

Having made these three changes, we now have a compiling class library. However, class libraries can only be consumed by Metro apps developed in a managed language. Our API will be consumed by a JavaScript app, so we need to expose the libraries though a WinMD file. Try switching your project’s output from Class Library to WinMD File and you’ll find that WinMD files carry some serious limitations:

Luckily, the restrictions on WinMD Files are only in the interface that they present to the consuming code. Instead of trying to expose our full client API to the application, we simply added a layer of indirection – a wrapper project that built as a WinMD file, rolled up the business logic for specific API operations, and presented a simple API to the consuming app.

With this app-wrapper-library model, we’ve got a working Metro style app that is capable of exercising the full Evernote API with minimal changes to existing code. We’re excited to see where Windows 8 and Metro go, how they’re received by users, and whether we can ever stop saying “Metro style” when we refer to apps built for Metro.

A Visual Studio 11 solution containing our modified SDK and a Hello World app is up on GitHub. Try it out and let us know what you build!

One Comment

  1. Thanks for making the code available and nice solution!

    – Robert


Leave a Comment

* Required fields