Hello and G’day, Mike and Rob here*. We’re long-time developers and, in our current roles as Microsoft Global Black Belts, we help our customers set up CI/CD processes and create apps that use the latest technology and services, from Fortune 500 companies building dozens of apps to mobile-first organizations where apps are their business.
This keeps us busy, but our team still makes time for fun. A few Microsoft teams recently hosted the Intelligent Cloud Competition, an internal hackathon where four teams competed to build the best cloud-connected, open-source app with real world applicability (no “Hello World” entries allowed). Mike and I were up to the challenge, and we spent the better part of August and September working on Hunt.
Our goals? First, showcase the best features of Microsoft’s mobile development tools and services, powered by the latest Azure capabilities. Second, create a fun and interactive way to kick off hackathons, presentations, and speaking engagements, scrapping slides and getting hands-on straightaway.
…and we won!
Fear not—you don’t have to wait until you catch us at a local event to get your hands on Hunt. To help you get up and running, we’ll walk you through how we set up Hunt’s architecture, backend services (including critical mobile capabilities and intelligent APIs), and automated our CI/CD pipeline with Visual Studio App Center, so you can start hacking on your own.
*Mike is from Australia and Rob is from Colorado, so if you recognise any s’ where z’s “should” be, now you know why.
Hunt is a virtual riddle-based team scavenger hunt, where a Coordinator creates hints and players snap photos of the answer, after which Hunt analyzes the photo and suggests tags for acceptable answers. To invite players, the Coordinator shares Hunt’s auto-generated QR code, and starts the Hunt.
Players have a set time to photograph the answer, and they’re awarded full points if it's correct. The first team to accurately identify and photograph all treasures wins.
See Hunt in action in the video here.
Breaking Down the Backend: Azure Wins!
Since a game of Hunt can be played inside of an office floor or across the globe, we used tons of Azure features, creating a scalable, reliable, and engaging experience, like:
- Application Insights: We track handled and unhandled exceptions, as well as function execution time telemetry. This helps us better understand app performance, quality, and health (“health” varies based on your project and the services you use, but for Hunt, we define health as execution duration, memory and CPU consumption, etc.).
- Blob Storage: Stores all collected game images, then globally distributed via CDN. Note: Blob Storage also allows you to store metadata.
- CDN: Just like the non-binary data benefits from locally available edge points, images collected during the game are distributed globally (reducing latency) and cached for subsequent requests. Using Azure CDN is simple: just swap out URLs for images or whatever data your apps need to access.
- Cognitive Services Computer Vision API: This is the brains of Hunt, recognizing photo objects and helping coordinators identify tags and analyzing players’ submissions to determine if they’ve successfully solved the riddle. The Computer Vision API provides data feedback (tags, confidence ratings, and more) on any images you provide via URL. Cognitive Services includes dozens of intelligent APIs broken into five categories: Vision, Speech, Language, Speech, and Search. Whatever you’re building, there’s a Cognitive Service for you!
- CosmosDB with Geo-Replication using DocumentDB: All non-binary data, like game, player, and state data is stored in DocumentDB. You can even use a familiar SQL-like syntax to query data using either REST or the SDK.
- Functions with Horizontal Scaling: All of our REST endpoints are hosted functions, triggered by an HTTP request, and provide the glue that ties in all the other services.
- Notification Hubs: We call a refresh whenever users receive push notifications, so devices are always up to date with the latest game data.
- Service Bus: When players’ time runs out, we use a ServiceBus message (with a time delay equal to game duration) to call an “end game” function.
A Quick Note on the Frontend
Even with the highest quality backend, an app is only as good as its frontend. We’re C# developers, so we used Xamarin.Forms to build Hunt; not only do we share ~97% code across Android and iOS, we didn’t need to use any Android or iOS custom renderers. We stuck to the MVVM pattern pretty closely, enforcing a strict VM-per-Page rule (we threw in a few interesting patterns too, which we’ve documented in the repo ReadMe).
Last, But Not Least
But, building a high quality UI on top of a high quality, intelligent backend doesn’t guarantee you’ll win hackathons or users’ long-term loyalty. To round it out, you need to set up consistent, automated development processes. This sets you up to iterate quickly and add value, without introducing unneeded risk or quality issues; you’ll be free to improve your apps, not think about your toolchain.
Continuous builds triggered by repository commits are a great place to start, ensuring compile-time quality, and testing regularly on real devices means minimal runtime errors. Read: better quality apps that work well when they’re in users’ hands. Once it’s in the wild, crash reporting and analytics help you identify what’s working well and what’s not, so you fix bugs fast and spend time coding features your users want.
Enter Visual Studio App Center, an all-in-one stop for your DevOps and app quality needs, including:
- Hosted continuous builds triggered by code commits
- Automated UI testing on thousands of real devices and configurations
- Automated distribution to beta groups, or enterprise and public app stores
- Detailed crash reporting
- User and app analytics and event tracking
- Targeted push notifications
As we built Hunt, we used Visual Studio App Center to automatically build our app with every code commit, from both GitHub and Visual Studio Team Services. We signed each build and configured the settings to compile against a device, which uses a completely different CPU architecture and build configuration. From there, we easily ran each build against a real, non-rooted standard device to verify our apps didn’t crash on launch (App Center’s Launch Test feature), giving us an additional sense of confidence. Since we checked in code up to 10 times a day, this peace of mind was even more important.
Automated UI Testing
We’re big fans of automated testing, and we knew it would help us submit an awesome (winning) app. We authored tests with C# and Xamarin.UITest, running them against real Android and iOS devices with App Center Test service. We ran against a standard device set (versus selecting specific device manufacturers, operating systems, or platforms). After our tests executed, we dove into the results; with the reports, we’d see if UI elements were displaying properly, and when test steps failed we could view:
- Stack traces of issues that might have crashed the app
- Device logs of what happened on that specific device at that point in time (actions leading up to the crash)
- Test runner servers performing remote commands
Detailed logs made it easy to home in on issues, identify the cause, and ship a fix. We also had instances where our app wasn’t crashing, but the UI was off. To help solve these visual-related problems, we relied on App Center Test reports, too, getting a bird’s eye view of how our app looked on all device screens. Anything that doesn’t render correctly stands out like a sore thumb.
Automated Beta Distribution
After verifying that our apps behaved as expected and we had a successful build, we’d distribute new versions to our beta audiences with just a few clicks, and we could choose to upload a local binary. Just complete your release notes, select an audience, and boom—you’re open for business.
Detailed Crash Reporting and Analytics
Just like you, we want to distribute the highest quality apps. While we rarely introduce bugs, it can happen (we kid). So, we rely on App Center Crashes and Analytics service. With one line of code, you’ve integrated automated crash reporting; whenever crashes occur, you’ll see crash details in App Center.
This is great for identifying issues, but that’s not all. App Center segments crash and analytics data into geography, demographic, and technical groups (like operating system, version, etc). Out-of-the-box, you track user behavior, like average session length, country of origin, and language, and you can choose to implement event tracking with metadata to pull even more information about your users.
Now, Over to You
We continuously developed, deployed, improved, and distributed to our stakeholders within hours of modifying our code thanks to Azure, Visual Studio Team Services, and App Center, and you can do the same!
Whether you’re starting from scratch or have existing tools and services, the CLI + REST-first approach makes it easy to get started or integrate into existing CI/CD systems.
More About the Intelligent Cloud Competition
Interested developers were given three months to develop mobile apps with the following criteria:
- Solve business need or fulfill a real requirement
- Must connect and leverage Azure services (the more the better)
- Adhere to DevOps best practices
- Open source
In mid-October, our peers judged submissions based on technical architecture and real-world applicability. We were honored to win, but we’d also encourage you to explore all Intelligent Cloud projects and make them your own.