Archive for the ‘Microsoft’ Category

This past week, I had the opportunity to write an app to handle scanning in patients for CoViD testing in our city, Fishers, Indiana. Fishers is one of the top 10 places to raise a family in the United States. Reinforcing that reputation, the city is providing free CoViD testing to all 90,000 residents, free of charge. The process is simple:

  1. Register online via an assessment
  2. Receive a patient ID
  3. Scan in at appointment, assign test, and take test
  4. Receive answers within 3 business days

Seems simple, right? Our city isn’t using the painful “touch the back of your eyeball” technique, either. Instead, it’s at the front of the nasal cavity – simple, painless, and you get results. It also ensures contact tracing where there are infections, so as a community we can help prevent the spread of disease.

But can we do it?

The problem is, roughly a week ago, Step 3 didn’t exist. The patient ID was from a survey with a QR code. The kit didn’t have any identifier whatsoever – it’s just one of many bagged kits in a box. And this data was being manually entered by other entities running similar tests. To give you an idea of how prone to error this process is, consider the patient ID looks like this:

Sample Survey ID

Any chance for typos much? And that doesn’t solve the kit identifier problem – because there isn’t one.

Box of Tests
Figure: A box of test kits.

Solving the Problem

So, last Saturday, I received an email from our City’s IT Director. He wanted to know if I knew anyone who could marry the patients’ ID with the kit ID for proper tracking. If you know me, this type of project is right up my alley. This project screamed MOBILE APP! I said “I’ll do it!” It would be like a weekend hackathon!

Most cities aren’t offering CoViD testing, and not a single state is offering such a service to all residents. Fishers is different – we’re a “vibrant, entrepreneurial city,” as our awesome forward-thinking mayor, Scott Fadness, often exclaims. His team takes novel approaches to addressing community needs, and this was no different.

Where there is testing, as I understand it, it’s with PCs and handheld scanners. What a nightmare it must be to keep such a setup running – with a laptop, with software that’s manually installed, and patients scanned with a handheld that can’t scan through glass. I’ve worked with those setups before – the technology issues are a huge PITA. Let alone deploying updates in any timely fashion!

We decided at the get-go a mobile app would be the right approach. When asked about barcode scanners, I explained “We don’t need one.” The built-in cameras on modern day cell phones are more than capable of scanning any type of barcode, QR code, and so forth. As an added bonus, any cell phone we use will have Internet connectivity, with Wi-Fi as a backup. The beauty of it is one single device, one single app, everything self-contained and easy to use.

The beauty of it is one single device, one single app, everything self-contained and easy to use.

The Requirements

After our initial discussion, and a bit of back and forth, this was the decided-upon workflow:

  1. Scan the Patient QR Code and Kit ID.
  2. Come up with a Kit Scanning Process. We decided on CODE39 barcodes that would be printed beforehand so technology wouldn’t be an issue each day.
  3. Store the Patient ID and Kit ID for later retrieval. This ended up being “uploaded” to the survey itself, ensuring we didn’t need to store any PII, and didn’t have to build a back-end data store. Small favors…

And this was the mockup:

2020-04-25 Fishers CoViD App
Figure: Whiteboarded app.

Draft Napkin
Figure: Rough brain dump with ideas.

Initially, we talked about generating the Kit barcode on the mobile device, then printing it to a wireless printer in the testing bay. This certainly seemed possible. However, the more I thought about it, the more I realized we could simply pre-print the labels and affix them as needed. This would provide some obvious benefits:

  • We wouldn’t have to come up with a mobile printing solution, which can be tricky, and is not a simple problem to solve cross-platform.
  • We’d keep a printer breakdown out of the picture, ensuring technology didn’t “get in our way”

The key is to get the patients in, tested, and out as efficiently as possible. The simpler we kept the process, the less could go wrong. So, on-demand printing was eliminated, and we’d simply pre-print labels instead. They’d be affixed to the test kit and then assigned to a patient.

Common Needs of Mobile Apps

Determining the app dvelopment approach, I took into consideration every mobile app I’ve built generally has had three primary needs that must be addressed:

    1. Where does data come from? Usually this is an API or the user. If an API doesn’t exist, considerable time is necessary to build one.
    2. Where does data go? Also usually an API for some data store. Same API issue.
    3. How does the user interact with data? The app is useless if the user can’t figure it out and, if possible, enjoy the experience. This can have design cost and time impacts.

For Need 1, we knew we had a QR Code. BUT how would we know it’s valid? How would we get the patient data? Well, it just so happened the survey provider had an API. Sweet! We hopped on a call with them and they provided an API  key and documentation. That’s how API access should work! They even provided a RegEx to validate the scanned patient ID, which internally to then was actually just a survey ID.

What about the kits? We decided to use a CODE39 barcode font and print on standard Avery labels. We came up with a standard naming and numbering convention, a RegEx to validate, and would pre-print them – a few hundred per day. This would ensure the labels were verifiable after scanning, and that printing wouldn’t be an issue each day. We’d take care of technology problems beforehand – such as printer issues – so they wouldn’t impact patient processing.

Barcodes on Avery Labels
Figure: A combination of Excel to generate the labels following the naming convention, plus mail merge to insert into on the off-the-shelf labels.

OK, now for Need 2… We can get the data, but we have to store it somewhere. Initially, we thought about building a separate back-end. The survey provider, Qualtrics, explained we could send the data back to their system and store it with the initial survey. Well, that was much better! No new storage API development was needed, as they already had the infrastructure in place. Building a new, solid, secure API in a short period of time would have been no small task.

For Need 3, the user experience, I borrowed my grandfather’s phrase: It must require a PH, D. Push Here, Dummy. I wanted “three taps and a send,” as follows:

  1. Scan the Patient – Once scanned, look the user up and verify they exist, showing confirmation details on the screen.
  2. Scan the Kit – Ensure the barcode matches the expected format.
  3. Confirm & Submit – Prompt to ensure patient details, such as name and postal code, have been verified, then confirm the entry has been saved.

It must require a PH, D. Push Here, Dummy.

That’s it – no chance for typos, and verification at every step, helping things go right. Little animations would show when a step had been completed, and scans could be done in any order.

Picked up 5600 Labels
Figure: Texting back and forth, getting our bases covered.

Xamarin As The Dev Stack

We’re building a mobile app here, and we may need it for multiple platforms. iOS – both iPhone and iPad, Android, and perhaps even Windows. Building each platform separately would take a lot of time to complete – time we didn’t have. It was April 25, we needed to be testing by April 27, and we were going live May 1.

The right choice was Xamarin with Xamarin.Forms – Microsoft’s cross-platform mobile framework. It’s similar to React Native, but you have full access to the underlying platform APIs. That’s because you’re building a real native app, not an interpreted overlay. With a single solution, we could build the iOS, Android, and UWP (Windows) apps, with 90% or more code sharing. I’m a Xamarin certified mobile developer, so this was going to be fun!

Solution Explorer
Figure: The Xamarin app in Visual Studio.

First Draft

Within a few hours, I had an alpha version of the app running. It was rough, and didn’t have the best UI, but it was scanning and talking with the Qualtrics API. Hey, once the base stuff’s working, you can make it look pretty!

The app consisted of a few core components:

  • App Service – Managing any processes the app needed completed, such as retrieving patient survey details, updating a patient survey record, verifying scanned code formatting, and so forth.
  • API Service – Talking back and forth with the Qualtrics API.
  • Analytics Service – Tracking aspects of the application, such as kit scan successes and failures, any exceptions that may occur, and so forth, so we can improve the app over time.

Build 1
Figure: Build 1 of the app. I first tested with my Android device, then rolled out to iOS, testing on both an iPhone and iPad.

I also had to ensure scanning went off without a hitch. After all, that’s what this app is doing – getting all the data quickly, then tying it together. I configured the scanning solution to only scan QR codes when scanning the patient ID, and only CODE39 barcodes when scanning kits. That way, if the codes were next to each other, the tech wouldn’t scan the wrong item and cause confusion. Remember, the technicians are medical techs, not computer techs – any technology problem could stop the patient processing flow. We needed to ensure the technology didn’t get in the way. You do that by testing thoroughly, and keeping the end user in mind.

Testing Scanning
Figure: QR code and CODE39 barcodes for testing.

Final Approach and User Experience

Once the UI was working, I added final touches to the UX to make it friendly and easy to use:

  1. When a technician successfully scanned a patient, the information would appear and a green checkmark would animate in. This would clearly indicate that step was completed. If there was an issue with the verification, they would be prompted to scan again. Optionally, they could manually enter the patient ID, which would follow the same validation steps.
  2. When a kit was scanned, another green checkmark would animate in, signifying that step, too, was complete.
  3. Once both steps had been completed, the technician would clearly understand the two greens meant “good to go” and could submit the patient data. They would be prompted to confirm they had verified all patient data and everything on the screen was correct.
  4. Once patient data was successfully transmitted, a confirmation dialog would appear. Upon dismissal, the UI would animate to the reset state, making it clear it’s OK to proceed to the next patient.

Devices, TestFlight, and Apple, Oh My!

So the app was in a good state. How were we going to get it on devices? This isn’t an app that we want in the App Store. It’s not a general consumer app – at least, not yet. TestFlight to the rescue! We’d push it to Apple’s TestFlight app testing service, then enroll all the iOS devices. That would ensure that, as we tweaked the app, we could quickly push the updates without any messy manual installs.

For those that have deployed iOS apps before, you know this isn’t a fast process. The first version of any app into TestFlight must be reviewed by Apple. I uploaded the first version and waited…

Roughly a day later, Apple rejected the app. BUT WHY? Well, we hadn’t provided any sample QR codes or bar codes to scan, so they rejected it. UGH! Really?? I didn’t even know that was a testing requirement! You learn something new every day… So I sent a URL with some examples to test with, as you can’t upload files to the testing site, and waited. Hours later, thankfully, Apple approved the app for testing!

App Store Test Rejection
Figure: Apple beta review rejection email.

We enrolled the various iPhones and iPads in TestFlight and we were able to start testing. Other than a restriction with SSL over the City’s network, which was quickly resolved, we had our devices ready to go. Not bad for under 48 hours!! 

Note that, once an app is in TestFlight, additional builds go through almost instantly. This ensured we could tweak as needed and not wait 24+ hours to validate each time.

TestFlight Versions
Figure: We could release updates with velocity after the initial approval.

Rolling It Out – Dress Rehearsal

We wanted to make sure the app worked without a hitch. A day before release, we had a “dress rehearsal.” Everyone would be ready for the testing, and we’d introduce the app. It’s a small part, but it ties it all together. Tracy, the I.T. Director, and I had been testing in earnest prior to this time, and we were feeling pretty good about it.

That morning, I walked the users through the app, joking about the PH, D requirement. Prior to my arrival, they had been testing the process on one of our citizens, who must have been quite tired from all the work:

Test Patient

The pressing questions were:

  • Can we scan a QR code through glass, so a citizen doesn’t have to roll down their window? Yes, unless it’s super tinted, which would be illegal anyway.
  • What if we can’t scan the code? This wasn’t an issue, except for a QR code variant issue discussed later, and manual entry was supported just in case.
  • What if Internet access goes down? We had cellular backup on all devices.
  • How will we apply the barcode to the kit? Peel and stick, then scan. We scan after removal from the main sheet so we don’t scan the wrong code. In a later version we added a prompt when the scanned patient had already been through the process.
  • What if the QR code is used more than once? This wasn’t an issue, as the name and appointment time wouldn’t match.

Here are a few photos from that morning – that was a lot of fun!

20200430_09065520200430_09070720200430_090718Box of TestsCheck InP100 MasksPresenting the AppRoad to TestTest CompleteTest Vial

    Day 1!

    Day 1 was here, and real citizens were about to get tested. I slept well the night before, knowing we had tested thoroughly. We only had one hiccup: The QR code in the email was different than the QR code on the confirmation website. This was causing validation errors, as the website QR code’s patient ID couldn’t be found in the system. Not an app issue, but that doesn’t matter.

    Couldn't find Patient ID
    Figure: Ruh-roh! The QR codes weren’t matching between different sources. Yellow alert!

    The survey provider quickly addressed the issue and we were good to go. It wasn’t a big deal – they provided a website to manually enter the patient ID for scanning with a properly generated QR code, and it barely impacted patients. Day 1 was a rousing success!

    2020-04-30 In the Field
    Figure: The app in use!

    Wrapping Up

    Going from no-app to app being used with patients in less than one week was an incredible experience. It feels great to help the community during this period of uncertainty. I’m grateful our city wanted to make the process as seamless as possible, using technology to help things go right, and providing the opportunity me to assist. I’m thankful that, once again, Xamarin was a great solution.

    I’ll probably have a technology walk-through in the near future – I didn’t want to concentrate on the underpinnings of the application for this article. I’ll leave that to a discussion for the Indy Xamarin Meetup.

    Final VersionFigure: The final app, with my info scanned in.

    I recently started in the Fishers Youth Mentoring Initiative, and my mentee is a young man in junior high who really likes lizards. He showed me photos of them on his iPad, photos of his pet lizard, and informed me of many lizard facts. He’s also a talented sketch artist – showcasing many drawings of Pokemon, lizards and more. Oh, yeah, he’s also into computers and loves his iPad.

    Part of the mentoring program is to help with school, being there as they adjust to growing up, and both respecting and encouraging their interests.

    It just so happens that he had a science project coming up. He wasn’t sure what to write about. His pet lizard recently had an attitude shift, and he figured it was because it wasn’t getting as much food week over week. Changing that, he realized its attitude changed. So, he wanted to cover that somehow.

    Seeing his interest in lizards, drawing, and computers I asked if we could combine them. I suggested we build an app, a “Reptile Tracker,” that would help us track reptiles, teach others about them, and show them drawings he did. He loved the idea.


    We only get to meet for 30 minutes each week. So, I gave him some homework. Next time we meet, “show me what the app would look like.” He gleefully agreed.

    One week later, he proudly showed me his vision for the app:

    Reptile Tracker

    I said “Very cool.” I’m now convinced “he’s in” on the project, and taking it seriously.

    I was also surprised to learn that my expectations of “show me what it would look like” were different from what I received from someone both much younger than I and with a different world view. To him, software may simply be visualized as an icon. In my world, it’s mockups and napkin sketches. It definitely made me think about others’ perceptions!

    True to software engineer and sort-of project manager form, I explained our next step was to figure out what the app would do. So, here’s our plan:

    1. Identify if there are reptiles in the photo.
    2. Tell them if it’s safe to pick it up, if it’s venomous, and so forth.
    3. Get one point for every reptile found. We’ll only support Lizards, Snakes, and Turtles in the first version.

    Alright, time for the next assignment. My homework was to figure out how to do it. His homework was to draw up the Lizard, Snake, and Turtle that will be shown in the app.

    Challenge accepted!

    I quickly determined a couple key design and development points:

    • The icon he drew is great, but looks like a drawing on the screen. I think I’ll need to ask him to draw them on my Surface Book, so they have the right look. Looks like an opportunity for him to try Fresh Paint on my Surface Book.
    • Azure Cognitive Services, specifically their Computer Vision solution (API), will work for this task. I found a great article on the Xamarin blog by Mike James. I had to update it a bit for this article, as the calls and packages are a bit different two years later, but it definitely pointed me in the right direction.

    Writing the Code

    The weekend came, and I finally had time. I had been thinking about the app the remainder of the week. I woke up early Saturday and drew up a sketch of the tracking page, then went back to sleep. Later, when it was time to start the day, I headed over to Starbucks…


    I broke out my shiny new MacBook Pro and spun up Visual Studio Mac. Xamarin Forms was the perfect candidate for this project – cross platform, baby! I started a new Tabbed Page project, brought over some code for taking photos with the Xam.Plugin.Media plugin and resizing them, and the beta Xamarin.Essentials plugin for eventual geolocation and settings support. Hey, it’s only the first week Smile

    Side Note: Normally I would use my Surface Book. This was a chance for me to seriously play with MFractor for the first time. Yay, even more learning this weekend!

    Now that I had the basics in there, I created the interface for the Image Recognition Service. I wanted to be able to swap it out later if Azure didn’t cut it, so Dependency Service to the rescue! Here’s the interface:

    using System.IO;
    using System.Threading.Tasks;
    using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
    namespace ReptileTracker.Services
         public interface IImageRecognitionService
             string ApiKey { get; set; }
             Task<ImageAnalysis> AnalyzeImage(Stream imageStream);

    Now it was time to check out Mike’s article. It made sense, and was close to what I wanted. However, the packages he referenced were for Microsoft’s Project Oxford. In 2018, those capabilities have been rolled into Azure as Azure Cognitive Services. Once I found the updated NuGet package – Microsoft.Azure.CognitiveServices.Vision.ComputerVision – and made some code tweaks, I ended up with working code.

    A few developer notes for those playing with Azure Cognitive Services:

    • Hold on to that API key, you’ll need it
    • Pay close attention to the Endpoint on the Overview page – you must provide it, otherwise you’ll get a 403 Forbidden


    And here’s the implementation. Note the implementation must have a parameter-less constructor, otherwise Dependency Service won’t resolve it.

    using Microsoft.Azure.CognitiveServices.Vision.ComputerVision;
    using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Threading.Tasks;
    using ReptileTracker.Services;
    using Xamarin.Forms;
    [assembly: Dependency(typeof(ImageRecognitionService))]
    namespace ReptileTracker.Services
        public class ImageRecognitionService : IImageRecognitionService
            /// <summary>
            /// The Azure Cognitive Services Computer Vision API key.
            /// </summary>
            public string ApiKey { get; set; }
            /// <summary>
            /// Parameterless constructor so Dependency Service can create an instance.
            /// </summary>
            public ImageRecognitionService()
            /// <summary>
            /// Initializes a new instance of the <see cref="T:ReptileTracker.Services.ImageRecognitionService"/> class.
            /// </summary>
            /// <param name="apiKey">API key.</param>
            public ImageRecognitionService(string apiKey)
                ApiKey = apiKey;
            /// <summary>
            /// Analyzes the image.
            /// </summary>
            /// <returns>The image.</returns>
            /// <param name="imageStream">Image stream.</param>
            public async Task<ImageAnalysis> AnalyzeImage(Stream imageStream)
                const string funcName = nameof(AnalyzeImage);
                if (string.IsNullOrWhiteSpace(ApiKey))
                    throw new ArgumentException("API Key must be provided.");
                var features = new List<VisualFeatureTypes> {
                var credentials = new ApiKeyServiceClientCredentials(ApiKey);
                var handler = new System.Net.Http.DelegatingHandler[] { };
                using (var visionClient = new ComputerVisionClient(credentials, handler))
                        imageStream.Position = 0;
                        visionClient.Endpoint = "";
                        var result = await visionClient.AnalyzeImageInStreamAsync(imageStream, features);
                        return result;
                    catch (Exception ex)
                        Debug.WriteLine($"{funcName}: {ex.GetBaseException().Message}");
                        return null;

    And here’s how I referenced it from my content page:

    pleaseWait.IsVisible = true;
    pleaseWait.IsRunning = true;
    var imageRecognizer = DependencyService.Get<IImageRecognitionService>();
    imageRecognizer.ApiKey = AppSettings.ApiKey_Azure_ImageRecognitionService;
    var details = await imageRecognizer.AnalyzeImage(new MemoryStream(ReptilePhotoBytes));
    pleaseWait.IsRunning = false;
    pleaseWait.IsVisible = false;
    var tagsReturned = details?.Tags != null 
                       && details?.Description?.Captions != null 
                       && details.Tags.Any() 
                       && details.Description.Captions.Any();
    lblTags.IsVisible = true; 
    lblDescription.IsVisible = true; 
    // Determine if reptiles were found. 
    var reptilesToDetect = AppResources.DetectionTags.Split(','); 
    var reptilesFound = details.Tags.Any(t => reptilesToDetect.Contains(t.Name.ToLower()));  
    // Show animations and graphics to make things look cool, even though we already have plenty of info. 
    await RotateImageAndShowSuccess(reptilesFound, "lizard", details, imgLizard);
    await RotateImageAndShowSuccess(reptilesFound, "turtle", details, imgTurtle);
    await RotateImageAndShowSuccess(reptilesFound, "snake", details, imgSnake);
    await RotateImageAndShowSuccess(reptilesFound, "question", details, imgQuestion);

    That worked like a champ, with a few gotchas:

    • I would receive a 400 Bad Request if I sent an image that was too large. 1024 x 768 worked, but 2000 x 2000 didn’t. The documentation says the image must be less than 4MB, and at least 50×50.
    • That API endpoint must be initialized. Examples don’t always make this clear. There’s no constructor that takes an endpoint address, so it’s easy to miss.
    • It can take a moment for recognition to occur. Make sure you’re using async/await so you don’t block the UI Thread!

    Prettying It Up

    Before I get into the results, I wanted to point out I spent significant time prettying things up. I added animations, different font sizes, better icons from The Noun Project, and more. While the image recognizer only took about an hour, the UX took a lot more. Funny how that works.

    Mixed Results

    So I was getting results. I added a few labels to my view to see what was coming back. Some of them were funny, others were accurate. The tags were expected, but the captions were fascinating. The captions describe the scene as the Computer Vision API sees it. I spent most of the day taking photos and seeing what was returned. Some examples:

    • My barista, Matt, was “a smiling woman working in a store”
    • My mom was “a smiling man” – she was not amused

    Most of the time, as long as the subjects were clear, the scene recognition was correct:


    Or close to correct, in this shot with a turtle at Petsmart:


    Sometimes, though, nothing useful would be returned:


    I would have thought it would have found “White Castle”. I wonder if it won’t show brand names for some reason? They do have an OCR endpoint, so maybe that would be useful in another use case.

    Sometimes, even though I thought an image would “obviously” be recognized, it wasn’t:


    I’ll need to read more about how to improve accuracy, if and whether that’s even an option.

    Good thing I implemented it with an interface! I could try Google’s computer vision services next.

    Next Steps

    We’re not done with the app yet – this week, we will discuss how to handle the scoring. I’ll post updates as we work on it. Here’s a link to the iOS beta.

    Some things I’d like to try:

    • Highlight the tags in the image, by drawing over the image. I’d make this a toggle.
    • Clean up the UI to toggle “developer details”. It’s cool to show those now, but it doesn’t necessarily help the target user. I’ll ask my mentee what he thinks.

    Please let me know if you have any questions by leaving a comment!

    Want to learn more about Xamarin? I suggest Microsoft’s totally awesome Xamarin University. All the classes you need to get started are free.

    Update 2018-11-06:

    • The tags are in two different locations – Tags and Description.Tags. Two different sets of tags are in there, so I’m now combining those lists and getting better results.
    • I found I could get color details. I’ve updated the accent color surrounding the photo. Just a nice design touch.

    I ran into this issue this week. I would define the Source as a URL and then, nothing…

    It turns out, with FFImageLoading, an indispensable Xamarin.Forms plugin available via NuGet, you must also set the ErrorPlaceholder property if loading your image from a URL. That did the trick – images started loading perfectly!

    I’ve reported what I think is a bug. I haven’t yet looked at their code.

    Here’s an example of how I fixed it:

    Working Code:

        Source="{Binding ModelImageUrl}"
        VerticalOptions="Center" />

    Non-Working Code, note the missing ErrorPlaceholder property:

        Source="{Binding ModelImageUrl}"
        VerticalOptions="Center" />

    I hope that helps others with the same issue. Enjoy!

    As part of my .NET 301 Advanced class at the fantastic Eleven Fifty Academy, I teach Xamarin development. It’s sometimes tough, as every student has a different machine. Some have PCs, others have Macs running Parallels or Bootcamp. Some – many – have Intel processors, while others have AMD. I try to recommend students come to the class with Intel processors, due to the accelerated Android emulator benefit Intel’s HAXM – Hardware Acceleration Manager – provides. This blog entry is a running list of how I’ve solved getting the emulator running on so many machines. I hope the list helps you, too.

    This list will be updated from time to time, as I find new bypasses. At this time, the list is targeted primarily for machines with an Intel processor. Those with AMD and Windows are likely stuck with the ARM emulators. Umm, sorry. I welcome solutions, there, too, please!

    Last updated: December 4, 2017

    Make sure you’re building from a path that’s ultimate length is less than 248 characters.

    That odd Windows problem of long file paths bites us again here. Many new developers tend to build under c:\users\username\documents\Visual Studio 2017\projectname. Add to that the name of the project, and all its subfolders, and the eventual DLLs and executable are out of reach of various processes.

    I suggest in this case you have a folder such as c:\dev\ and build your projects under there. That’s solved many launch and compile issues.

    Use the x86 emulators.

    If you have an Intel processor, then use the x86 and x64 based emulators instead of ARM. They’re considerably faster, as long as you have a) an Intel processor with virtualization abilities, which I believe all or most modern Intel processors do, and b) Intel’s HAXM installed.

    Make sure VTI-X / Hardware Virtualization is enabled.

    Intel’s HAXM – which you can download here – won’t run if the processor’s virtualization is disabled. You need to tackle this in the BIOS. That varies per machine. Many devices seem to chip with the feature disabled. Enabling it will enable HAXM to work.

    Uninstall the Mobile Development with .NET Workload using the Visual Studio Installer, and reinstall.

    Yes, I’m suggesting Uninstall + Reinstall. This has worked well in the class. Go to Start, then Visual Studio Installer, and uncheck the box. Restart afterwards. Then reinstall, and restart.

    Mobile Development Workload Screenshot

    Use the Xamarin Android SDK Manager.

    The Xamarin team has built a much better Android SDK Manager than Google’s. It’s easy to install HAXM, update Build Tools and Platforms, and so forth. Use it instead and dealing with tool version conflicts may be a thing of the past.

    Make sure you’re using the latest version of Visual Studio.

    Bugs are fixed all the time, especially with Xamarin. Make sure you’re running the latest bits and your problems may be solved.

    Experiment with Hyper-V Enabled and Disabled.

    I’ve generally had issues with virtualization when Hyper-V is enabled. If you’re having trouble with it enabled, try with it disabled.

    To enable/disable Hyper-V, go to Start, then type Windows Features. Choose Turn Windows Features On or Off. When the selection list comes up, toggle the Hyper-V feature accordingly.

    Note: You may need to disable Windows Device Guard before you can disable Hyper-V. Thanks to Matt Soucoup for this tip.

    Use a real device.

    As a mobile developer, you should never trust the emulators to reflect the real thing. If you can’t get the emulators to work, and even if you can, you have the option of picking up an Android phone or tablet for cheap. Get one and test with it. If you’re not clear on how to set up Developer Mode on Android devices, it’s pretty simple. Check out Google’s article on the subject.

    Try Xamarin’s HAXM and emulator troubleshooting guide.

    The Xamarin folks have a guide, too.

    If all else fails, use the ARM processors.

    This is your last resort. If you don’t have an Intel processor, or a real device available, use the ARM processors. They’re insanely slow. I’ve heard there’s an x86 emulator from AMD, yet it’s supposedly only available for Linux. Not sure why that decision was made, but moving on… 🙂

    Have another solution?

    Have a suggestion, solution, or feature I’ve left out? Let me know and I’ll update!


    My latest Visual Studio extension is now available! Get it here: 2017, 2015

    So what is CodeLink?

    Getting two developers on the same page over chat can be time consuming. I work remote, so I can’t just walk to someone’s desk. I often find myself saying “go to this file” and “ok, now find function <name>”. Then I wait. Most of the time it’s only 10-20 seconds lost. If it’s a common filename or function, it takes longer. Even then, mistakes can be made.

    So I asked myself: Self, wouldn’t it be great if I could send them a link to the place / cursor location in the solution I’m at? Just like a web link?

    CodeLink was born.

    So here’s what a CodeLink looks like:


    I would simply share that CodeLink with a fellow developer. They’d select “Open CodeLink…” in VisualStudio, paste it in, and be brought to that line of code in that project. No more walking them through it, much less waiting.

    Technically, the format is:

    codelink://[Platform]/[Project Unique Path]/[File Unique Path]/[LineNumber]

    What’s it good for?

    Other than what I’ve suggested, and what you come up with, I’m thinking CodeLink will help you, teams, teachers, and students with:

    • Include CodeLinks in bugs, code reviews to highlight what needs to be reviewed
    • Share CodeLinks on Git repos, pointing to specific code examples, points of interest, and so forth
    • Share CodeLinks with students so they can continue referring / reviewing useful code

    So what’s next?

    When I was thinking of the link format, I figured I may end up extending this to VS Code and other editors in the future. After all, not everyone uses VS. Why not XCode, Visual Studio Mac, Atom? So, I added a type identifier.

    As always, I look forward to your feedback. Hit me up on Twitter or LinkedIn.


    I recently deployed an Azure Cloud Service with Remote Desktop enabled. However, when I went to connect to it on port 3389, the server refused the connection. I remember there was something I had to do, but I had never written down the steps. So, here’s what you need to do, in case you’re looking 🙂

    Note: I use Remote Desktop Connection Manager, a.k.a. RDCMan, also from Microsoft, instead of the standard RDC client. I feel it’s much better, more configurable, and great if you need to work with many remote desktops. I’ve love to know why they don’t include it in Windows!

    Step 1: Find your Cloud Service and Slot in Azure Portal

    In Azure, find your Cloud Service. Also select the slot to which you want to connect, such as Production or Staging.

    Step 2: Select the Roles and Instances option

    You’ll see it on the left.

    Step 3: Choose the item to which you want to connect and click Connect

    For example, your web role instance. This will download an .RDP file. You can double-click this file to connect. Ooh! Neat!

    Step 4: If you’re using RDCMan…

    To connect with RDCMan, you’ll need to grab the Cookie: something something something string out of the RDP file. Open it in Notepad++, or your text editor of choice, and grab that value. Ignore the s: text.

    In RDCMan, for the VM, add the string under Connection Settings tab in the Load balance config textbox.

    Step 5: You’re Connected!




    Have you been wondering how to access the Azure Multi-Factor Authentication Settings in the Azure Classic Portal without first having to create an Azure account? I figured this out a few days ago, having an Office 365 tenant, and wanting to use the EMS and Azure Active Directory Premium features. Following Microsoft’s instructions, it said to go to the Azure Classic Portal. The problem is, Office 365 doesn’t include an Azure subscription, it just includes Azure Active Directory, which you manage through the “modern” Azure portal. Unfortunately, the Trusted IPs and MFA capabilities are managed through the Azure Classic Portal, which you can’t directly access without an Azure subscription.

    So, here’s what you do:

    1. Go to
    2. Click Admin to open the admin tools
    3. In the search box, type MFA
    4. Select the Multi-factor authentication search result
    5. Click the link to open the Manage multi-factor authentication link
    6. There you go – manage MFA in your Azure AD to your heart’s content!


    Want to learn all about Xamarin and how you can use it, while not spending most of your time watching code scroll by in a video? I figured there was room for an explainer without being a close-captioner for a code tutorial. Enjoy my latest video!

    From the description, along with links:

    Have you been considering Xamarin for your cross-platform mobile app? This presentation will help.

    In this non-code-heavy presentation, we’ll discuss:

    * What is Xamarin
    * Development Environment Gotchas
    * Creating a Sample To Do List App without writing any code
    * Reviewing a real Xamarin app that’s “in the wild”
    * Review native, platform-specific integrations
    * Discuss gotchas when using Xamarin, and mobile apps in general
    * Answer audience questions

    Why not code-heavy? Because there are many examples you can follow online. This presentation will provide valuable information you can consider while reviewing the myriad of tutorials available to you with a simple Bing or Google search, or visiting Pluralsight, Microsoft Virtual Academy, or Xamarin University.

    If you have any feedback, please leave in the comments, or ask me on Twitter: @Auri

    Here are the links relevant for this presentation:


    Indy.Code Slides with Cost and Performance Figures:!AmKBMqPeeM_1-JZR4…
    (you can find the Indy.Code() presentation on my YouTube channel)

    Google Xamarin vs. Native iOS with Swift/Objective C vs. Android with Java Performance Article:…

    Example code for push notifications, OAuth Twitter/Facebook/Google authentication, and more:…

    Link to Microsoft Dev Essentials for $30/month free Azure credit and free Xamarin training:

    Microsoft Virtual Academy Multi-Threading Series:…


    I’m continuing my resolution to record as many of my programming and technical presentations as possible. I recently spoke at the inaugural Indy.Code() conference. It was excellent, with an incredible speaker line-up. I hope they, too, post some of their presentations online!

    Watch the Video on YouTube

    From the synopsis:

    Should you write your app “native” or use a “cross-platform” solution like React Native, Xamarin, or NativeScript? The new wave of native-cross-compiling solutions provide significant cost savings, code reuse opportunities, and lower technical debt. Does wholly native, per platform development, still play a role in future mobile development? Let’s discuss together.

    In this presentation, we’ll discuss:

    • The growth of native, hybrid, and cross-platform mobile development solutions
    • Cost analysis of multiple native and cross-platform apps
    • Considerations for each native and cross-platform solution
    • Lessons learned

    Slides are available here:

    If you have any questions, I’m happy to answer them! Please email me or ask on Twitter.


    I’ve been struggling with carrying a Mac and PC for Xamarin development for a couple years now. Wouldn’t it be nice to just run OS X in a VM so I could use my Surface Book and not mess with the Apple ecosystem more than necessary? Well, I finally got it working, thanks in large part to the work that’s been done by many people, links of which I’ll credit in this article. Thanks, all!



    • macOS X Sierra Installer, or a machine with Sierra installed – extraction details below
    • Intel powered machine, preferably i5 or higher
    • 16GB or larger thumb drive, preferably USB 3
    • VirtualBox 5.x
    • Visual Studio 2015 or higher
    • If on a laptop, you’re plugged in

    Create the OS X Installer USB Drive

    First things first – you’ll need a Mac running Sierra and at least a 16 GB USB thumb drive. We’ll be using Unibeast, Multibeast, and the Clover bootloader. I imagine you own both Mac OS and the drive. I’d go the USB 3.0 or higher route so things run a bit faster. We’ll be extracting a Sierra installer in a moment. If you’re all set with the above, follow the instructions at the awesome Tony Mac x86 website. Special thanks to the Hackintosh website. When asked whether to use UEFI or Legacy boot mode, choose Legacy. Here is a marked-up PDF of the article in case the link doesn’t work.

    In a nutshell, here’s what you’ll be doing in this step:

    1. Insert the thumb drive into the Mac. Launch Disk Utility and format the USB drive with the name USB and the format of GUID Partition Map.
    2. Download the macOS Sierra installer via the App Store. The installer will be saved in your Applications folder. Make a copy of it somewhere, just in case it gets deleted and you need it again. Don’t move the installer.
    3. Download and Run Unibeast and follow the prompts. Use Legacy boot mode. You’ll need a [free] account on the Tony Mac x86 site to download, fyi.
    4. Let Unibeast create the thumb drive. This will take about 10 minutes on a USB 3 drive.
    5. Download and Copy Multibeast to the newly created Unibeast drive.
    6. You’re now ready to start configuring VirtualBox.

    Create the VirtualBox USB Drive Shim

    You have a USB thumb drive, but VirtualBox doesn’t make it easy to boot from such a device. You’ll need to create a fake virtual disk that points to the USB drive. This tutorial walks you through it. Here’s a PDF if that link doesn’t work.

    In a nutshell, here’s what you’ll be doing in this step:

    1. Open Disk Management and get the Disk Number of the thumb drive, as shown below
    2. Open command prompt as an administrator
    3. Navigate to %programfiles%\oracle\virtualbox
    4. Run the command
      VBoxManage internalcommands createrawvmdk -filename C:\usb.vmdk -rawdisk \\.\PhysicalDrive#

      to create the virtual drive pointer

    5. You’re now ready to create the VirtualBox virtual machine.


    Create the VM

    Windows won’t allow VirtualBox to use the USB shim you just created unless you launch with administrator privileges. Right-click VirtualBox and select Run as Administrator. VirtualBox should open. Then, follow the instructions on this page. Ignore the download portion – you already have an install thumb drive, and you just want the VM configuration steps. If that link doesn’t work, here’s a PDF.

    In a nutshell, here’s what you’ll be doing in this step:

    1. Create a new Virtual Machine, name it Sierra – although that’s not a requirement – and choose OS X 64-bit as the guest OS. VirtualBox’s settings aren’t fully correct, but we’ll get there.
    2. Choose 4 GB of RAM. I didn’t test with any other memory configs. So, YMMV if you go another route.
    3. When asked which drive to use, choose an existing drive, and select the USB shim you created in the previous section. The example above saved the file as usb.vmdk at the root of C:
    4. You should now have a VM, like every other time you’ve used VirtualBox 🙂
    5. Add another Virtual Disk to stand in as your Mac’s hard drive. I suggest VDI format, dynamically sized, and 60 GB in size. Ignore that my screen shot shoes 40 GB <grin> In future steps you’ll need to install XCode and Xamarin Studio. Don’t skimp on size here or you’ll be reinstalling later. Much sad.

    Note: XCode uses a lot of space when it updates. Don’t skimp on virtual disk size. If that’s a big deal, save the VM’s drive to a location that will have enough space.

    Once you’ve added the hard drive, you’ll need to finish configuring the VM. You already have an installer on the thumb drive.

    Aside from the defaults, confirm the settings you have match settings below. I’ve also included some screen shots a little further down.

    1. After performing the steps above, you’ll be using the following settings in your VM:
      • System, Motherboard, Base Memory: 4096 MB
      • System, Motherboard, Boot Order: Only Optical and Hard Disk checked
      • System, Motherboard, Pointing Device: USB Tablet
      • System, Motherboard, Chipset: ICH9
      • System, Motherboard, Extended Features: Enable I/O APIC, Enable EFI, Hardware Clock in UTC Time, all checked
      • System, Processor, Processors: 2 CPUs
      • System, Processor, Execution Cap: 100%
      • System, Processor, Enable PAE/NX: Checked
      • Display, Screen, Video Memory: 128 MB
      • Display, Screen, Monitor Count: 1
      • Display, Screen, Scale Factor: 100% (you can change this later if you’re on a high-res display)
      • Display, Screen, Accelerator: 3D and 2D both unchecked
      • Storage: One controller, first item is USB shim, then the hard drive and “Empty” optical drive. The order of those two don’t matter.

    After configuring the VM in the UI, close VirtualBox and run the following commands, of which I’ve created a convenient all-in-one script here. You may need to edit it depending on what you named your VM.

    These make the appropriate settings to fool OS X to thinking you’re on a real Mac.

    cd "C:\Program Files\Oracle\VirtualBox\"
    VBoxManage modifyvm "Your VM Name" --cpuidset 00000001 000106e5 00100800 0098e3fd bfebfbff
    VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/efi/0/Config/DmiSystemProduct" "iMac11,3"
    VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/efi/0/Config/DmiSystemVersion" "1.0"
    VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Iloveapple"
    VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/smc/0/Config/DeviceKey" "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc"
    VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC" 1

    Boot the VM and Install Sierra

    Alright, we’re ready to boot! Re-launch VirtualBox as an administrator and start up. After a bunch of Unix style text scrolling, you should see the Apple logo appear and begin to load macOS. If not, something’s configured wrong.  Read through the above steps and see what you missed. Of course, things may have changed over time, and this tutorial may no longer be valid. Bummer if that’s the case! Much sad. I want you to be much happy.

    NOTE: If things appear frozen during boot, wait a minute. In sanity checking this on another machine with a friend, his seemed to be frozen, and then resumed. A watched installer never boils… [terrible joke]

    The instructions for installing Sierra are pretty straightforward:

    1. When the installer appears, select the Utilities menu on top, then Disk Utility.
    2. Format the Virtual Hard Disk. I named mine VBox, but that doesn’t matter. Make sure the format is GUID Partition Map and Mac OS Journaled. Do not select the case sensitive option.
    3. When formatting is complete, quit Disk Utility and you’ll be back at the installer.
    4. Select the freshly formatted hard drive and start the install process.
    5. Wait. It took about 20 minutes to install on my 6th Gen Core i7 SSD Surface Book. YMMV.
    6. Keep an eye on the installer. When it’s done, remove the thumb drive. Otherwise, it’ll boot back into the installer. If that happens, wait for the installer to boot so you don’t corrupt anything, then remove the thumb drive, and restart the VM.
    7. When the Mac boots back up, follow the prompts. Do *not* use an Apple account – it won’t let you. Make note of the username – it will be in lowercase – you’ll need that when you enter a username and password for Visual Studio later. Don’t worry about the Apple Account issue, though – this won’t affect your ability to install XCode or use the App Store.
    8. Once setup is complete, shut down the Mac.
    9. In the VM’s settings, remove the USB shim.
    10. OS X is now installed.

    From this point forward, you no longer need to run VirtualBox as an administrator. Yay!

    NOTE: After configuring OS X, you may be presented with a dialog stating the keyboard cannot be identified. Don’t worry – just follow the prompts and you’ll be all set.

    Install Xcode

    For OS X to act as a build server, you must have Xcode and Xamarin Studio installed. Let’s install and configure Xcode first.

    To complete this step, do the following:

    1. Open the App Store on the Mac
    2. Search for Xcode
    3. Click Get to install it. You’ll need to enter your Apple account credentials.
    4. Wait a while – it’s big and takes a while to install. About 30 minutes on my machine.
    5. Once installed, Launch Xcode, agree to any terms, and let it finish installing components.
    6. When Xcode is finished configuring, open the Xcode menu, select Preferences, then Accounts, and click the + symbol. Enter your Apple Developer Account details.
    7. Great! Xcode is configured! Time to get Xamarin set up.


    Install Xamarin Studio

    Xamarin Studio handles installing the OS X build agent so you can debug apps with Visual Studio, while performing the necessary build and simulation tasks on the Mac. This is required for licensing reasons, and Apple being a closed system for iOS developers. Boo.

    Note: Xamarin Studio may be called Visual Studio for Mac by the time you read this.

    1. First, open Safari – unless you installed something else on the Mac already – and download Xamarin Studio for Mac. This is simple – go to, and download the installer.
    2. Open the installer on your Mac from the Downloads folder, and click Open when it warns you that it’s an application downloaded from the Internet.
    3. Install everything except Android. You can do Android dev on your PC, so I feel there’s no reason to install it again here. Again, YMMV – do as you wish 🙂 This process can take a while due to downloading and installing many items.
      • Note: I’m not sure if you need Profiler or Workbooks, so I kept them in there. I’m thinking it’s an insignificant difference.
      • Another Note: The installer will say it’s installing Android SDK anyway, not sure why! 🙂 I complained to Microsoft about this – it didn’t make sense to me.
    4. Once Xamarin Studio is installed, start it and make sure it comes up.
    5. Under the Xamarin Studio menu item – which may be Visual Studio by the time you read this – select Check for Updates and make sure everything’s up to date.
    6. Note to Visual Studio 2017 Release Candidate Users: If you’re running Visual Studio 2017 Release Candidate, it [annoyingly] installs and targets the alpha channel of Xamarin. You’ll need to switch to the Alpha channel in Xamarin Studio to match this, otherwise Visual Studio will refuse to compile/build/debug through the Mac instance. A channel switching option is available in the Check for Updates menu to address this issue.


    Configure the Mac for Remote Login

    In order to connect to the Mac from Visual Studio, we’ll need to open a port on the Mac side. The process is described in this article.

    In a nutshell, here’s what you’ll be doing in this step:

    1. Press Windows-Space, which translates to Apple-Space, and type remote login to open the Sharing control panel.
    2. Check the box for Remote Login, and select All Users, or at least ensure your user account is in there. You’re on a private network only accessible by your machine, so I see few security issues here. Behind the scenes, this is opening Port 22 for SSH access to your Mac.


    Alright, we should be all configured! Let’s switch back to Windows!

    Configure VirtualBox Networking and Port Forwarding for Remote Debugging

    Now that the Mac is configured, we have to tell VirtualBox how to allow your computer to talk with it. We do this by configuring Port Forwarding in VirtualBox.

    1. Open command prompt and type ipconfig.
    2. Take note of the Ethernet adapter VirtualBox Host-Only Network, which may be #2, #3 etc. You want the one with an IP address. Copy that IP address to the clipboard.
    3. In VirtualBox, open the Settings of your VM, and select Network, then Advanced, then Port Forwarding.
    4. Add a new rule. I named mine Remote Access.
    5. For Protocol, choose TCP.
    6. For Host IP, paste in your host adapter IP.
    7. For Host Port, enter 22.
    8. For Guest Port, enter 22.
    9. For Guest IP, go to your Mac, use Windows-Space to search for Network Utility, and type in the IP that appears there.




    Note: It’s possible the Guest IP will change from time to time. This is especially true if the Mac isn’t the only virtual machine you run. If you can no longer connect, check whether you need to update the Guest IP.

    VirtualBox is now configured! If you want to verify this, you can launch bash shell on your Windows 10 machine and type ssh username@ipaddress, accept the certificate, and enter your password when prompted. If you can type ls and see your Mac’s files, all is good in the world.

    Link Visual Studio to macOS

    Alright, hard part’s over. Now we need to configure Visual Studio. The steps for accomplishing this can be found at the same link above, or you can just click here if you don’t want to scroll. There’s also a tutorial in Visual Studio.

    In a nutshell, here’s what you’ll be doing in this step:

    1. Launch Visual Studio.
    2. Type Control-Q to access the Quick Access Menu, and type iOS Settings. This will take you to the Xamarin iOS settings pane.
    3. Choose Find Xamarin Mac Agent, follow the prompts to ensure you’ve configured everything properly.
    4. In Enter Mac name or IP address enter your VirtualBox host adapter’s IP. If everything’s configured properly, you should be prompted to enter your Mac’s username and password.
    5. If all went well, a lock-like icon should appear next to the IP address, as shown below. If not, make sure the version of Xamarin installed in Visual Studio is the same as that on the Mac. See my note above about Visual Studio 2017 and its Xamarin Alpha Channel issue.

    And, Go!

    If everything went well, you should now be able to do all your Windows and Xamarin / Mac development on one machine!

    Please provide feedback in the comments. Enjoy!

    Tips / Updates

    • If you’d like to tweak the video resolution, you can follow this article. The command is:
    VBoxManage setextradata "VM name" VBoxInternal2/EfiGopMode N
    Where N can be one of 0,1,2,3,4,5 referring to the 640x480, 800x600, 1024x768, 1280x1024, 1440x900, 1920x1200 screen resolution respectively
    • My goal with this article is to build a machine for building a build/test VM. I am not trying to replace a Mac environment for doing lots of work on the Mac side of things.