Crosswind, the app that does one specific thing beautifully

While on vacation with my parents earlier this year, my father, the airline pilot, asked me to make him an app. Often when he’s coming in for a landing he wants to know the crosswind on the runway. He knows the runway heading, he knows the wind heading and speed, he knows he has robust tools in his fight kit to do the calculations. But all he really wants to know is if the crosswind is close enough to the plane’s crosswind rating to worry about it. He wants an estimate, he wants it quick, and he wants to get on with the landing.

So I built Crosswind.

Crosswind is a single-purpose Windows Phone app that can take three inputs, do a sine for the result, and get out of the way. It was designed to be simple, beautiful, and (most of all) fast.

CrosswindMainPage

Though I receive my commission at the end of May, I didn’t start work on Crosswind until the beginning of August during the Summer 2014 SEP Startup Weekend. It wasn’t until this last week that I had an opportunity to finish it up and publish it. I have probably put 40 hours into it so far and though there are still several changes I’d like to make to the code, it is published and live on the Windows Phone app store. It is my first mobile app.

While working on the app I found a couple of very awesome sites. RGB.to is a great resource for converting colors between different formats. e.g. hex to HSL. It even supports HTML color names (which Windows Phone also uses). The other is ModernUIIcons.com, an large, high-quality, free icon pack that really embraces the Windows Phone aesthetic. I will certainly be using more of those icons in the future.

And now, the link you’ve all been waiting for: check out “Crosswind” in the Windows Phone Store! http://www.windowsphone.com/en-us/store/app/crosswind/285e269d-0574-46ac-97e7-7f5386d154b2

http://www.windowsphone.com/en-us/store/app/crosswind/285e269d-0574-46ac-97e7-7f5386d154b2

This one’s for you, Dad.

Pinned Site Live Tiles belong on all sites

Imagine if you could take your existing website and turn it into an app with minimal effort. Of course, that’s impossible. But you can get 75%* of the way there with an awesome new Internet Explorer feature I recently implemented on one of SEP’s sites called Pinned Site Live Tiles.

What are Pinned Site Live Tiles?

I am sure you are familiar with live tiles. They first came with the launch of Windows Phone and now are a defining feature of Windows 8+ as well. Live tiles allow apps that have been pinned to the user’s start screen to update their tile with dynamically generated and presumably relevant information. Pinned SLTs (which I will now call slivets) bring that feature to Windows 8.1′s IE11 when you pin a web link to the start screen. They basically transform a simple bookmark with a blurry favicon into something almost indistinguishable from a real app. Scott Hanselman wrote an easy how-to guide on his blog.

But things just got better. Nestled deep within Matt Hidinger‘s interesting “[Live Tiles Enhancements](http://channel9.msdn.com/Events/Build/2014/2-523 “MSDN Channel9″)” talk from Microsoft’s BUILD conference was a cool little revelation: slivets work on Windows Phone 8.1 as well as Windows 8.1. So now they work on all of Microsoft’s desktop, tablet, and phone platforms.

A Disclaimer

I guess it’s worth mentioning that slivets only work when IE11 is the default browser. But that limitation doesn’t matter since it won’t affect your target audience. Anyone interested in apps, namely users of Windows tablets and Windows Phones, are almost certain to have IE as their default browser. And frankly, many desktop users never change their default browser away from IE.

The Case for Pinned Site Live Tiles

Slivets work for almost the entire the app-inclined Windows user base and for all of Windows Phone users. This is a large market, and although currently perched at third place in worldwide market share, it is an underserved market too. Some may scoff at the size of this user base in comparison with Android and iOS. But anyone with a great website who wants apps is likely already going the Android/iOS route since they give the most bang for the many bucks it takes to build an app. That leaves just the Windows platforms in need of apps, and slivets fills those exact markets.

You can enable one of the signature Windows platforms’ features just by adding a couple meta tags to your header and a few xml files. Who cares about bang vs. buck when the price is nearly free. In fact, it’s so easy that even if you don’t have iOS/Android apps you should still enable slivets, the same way you would be silly not to include an apple-touch-icon.

From now on, I plan to add slivets to all the websites I build unless it’s unnecessary or technically impossible.

Adding slivets to your site is not difficult, but there are some tricky situations that can waste your time if you don’t know where to look for answers. I’ve included some more technical information and helpful tips in my companion article, “How to create a Pinned Site Live Tile without pain.”

*Disclaimer: invented number.

Creating a Pinned Site Live Tile easily and without pain

The list of things a developer must add to their website is constantly growing. I’m not talking about the big things; I’m talking about the little stuff that would be stupid to leave out. For instance, favicons were introduced by Internet Explorer 5 in 1999 (they made it into the HTML 4.01 recommendation later that year). Your site would function just as well without a favicon but you would be crazy not to have one. It’s basically a requirement. The same thing goes for the description meta tag and apple-touch-icon, among others.

And now there’s another one: Pinned Site Live Tiles as implemented by IE11 in Windows 8.1 and Windows Phone 8.1. Pinned SLTs (which I call “slivets”) allows a website to have a series of beautiful images for the different sizes of Windows tiles and even allows the display of website information using some lovely built-in tile templates using a simple xml schema.

It’s a little more involved than, say, a favicon but it’s really not hard. Especially for the value you get. Microsoft has a lot of documentation to make this easy. What can be hard is finding the right page since it’s not all in one place. Here are some links to help you avoid wasted time and pain.

Quick start

buildmypinnedsite.com - This is the very first place you should go if you want slivets. This easy wizard will get you up and running in no time. You will probably want to replace the images with something more professional and customize the urls to match your site, but it quickly gives you something that’s working and gives you a good place from which to start customizing. It’s basically the File > New of slivets.

Make a Windows 8.1 Pinned Live Tile for YOUR website in minutes – I’m not going to give a complete how-to because Scott Hanselman already has and his is better than mine would be. He walks you through the wizard site above and explains what it all means.

Designing

Create live tiles for your websites in IE11 – This is the jumping off place to explore the Microsoft help for slivets. Start here with questions.

Pinned Sites – This the jumping off place to explore the Microsoft API documentation for pinned sites including schemas for the browser config, for html meta tags, and the complete list of properties, methods and events used by the browser. This is really helpful for pulling off some cool and crazy website-to-slivet interactions with the variety of available javascript hooks.

The tile template catalog (Windows Runtime apps) – You’ll want to pick your tiles to fit the data you are displaying. This is the comprehensive list of all possible tiles with example xml and result photo to get you started. You should find several you like. Of course, you can make the tile look like whatever you want by simply picking the single photo template and generating the custom-formatted image yourself. But that would take more server infrastructure on your end and would risk making your tiles clash with the aesthetic of the OS. Still, the option is there.

Debugging

Build a live tile – This starts out as Microsoft’s how-to guide but important part is at the very bottom under “Testing and finding problems with live tiles.” Slivets are designed to light up with whatever pieces are present and if they aren’t there, fallback to normal behavior. This is really nice for end-users, but it can make development difficult because when something doesn’t work, IE is quite taciturn about reasons. The tips at this link are simple but indispensable.

Fiddler – While we are on the topic of debugging, you pretty much have to have Fiddler to monitor the network traffic. This will tell you if the endpoints you defined are even being hit. I wasted a couple hours trying to solve a seemingly impossible problem with my slivets, but after I used Fiddler I solved the problem in minutes.

If you need any more help feel free to contact me. Of course, if you’d like to talk to someone who actually knows something, I’ve found Microsoft Program Managers MattHidinger and Jacob Rossi to be quick, friendly and very helpful.

Wrestling with CheckedTextViews in an Android Multi-Choice ListView

I was building an Android ListView in an AlertDialog.Builder that allowed multi-choice. It displayed a list of accounts and you could select the one or more you wanted to operate on. I also needed to be able to set certain accounts as checked by default.

Android MultiChooser AlertDialog

I couldn’t use the built in AlertDialog.Builder(context).setMultiChoiceItems() method because it only accepts an array of strings of display data and I needed a custom list item view with the more complex AccountSummary object.

Here is the getView method on my adapter.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    AccountSummary account = getItemAt(position);

    if (convertView == null) {
        convertView = getInflater().inflate(R.layout.account_multi_choice_dialog_item, null);
    }

    CheckedTextView text = convertView.findViewById(R.id.text_view);
    text.setText(account.name);

    // Set the CheckedTextView to checked if its a default here

    return convertView;
}

Everything is standard except for the need to potentially set the item as checked. You would think this would be very simple, just take the CheckedTextView and set it to checked.

    CheckedTextView text = convertView.findViewById(R.id.text_view);
    text.setText(account.name);

    // This does not work
    text.setChecked(account.isDefault);

This does not work. For some reason you can set CheckedTextView to checked for an hour’s worth on mintues in a row (I sure did) but it will never be remembered. In fact, I even tried checking the TextView from the ‘outside’ by accessing the ListView from my activity, grabbing the correct CheckedTextView, and setting checked there. And that didn’t work either.

It turns out, as I understand it, that the ListView maintains the checked state of its list items and ignores the state that item says it should have. The following small change in the code makes everything work charmingly.

    CheckedTextView text = convertView.findViewById(R.id.text_view);
    text.setText(account.name);

    // This, quite charmingly, works
    ((ListView) parent).setItemChecked(position, account.isDefault);

Instead of checking the item, I tell the ListView to set checked on the correct item. According to the Android source, AbsListView keeps all the checked state in a SparseBooleanArray so the checked state in the TextView goes nowhere and has no effect. I’m not sure I understand the full picture, but just set the checked state on the ListView, not the list item.

So now you know.

Using factories for cleanliness in Android testing

I am on a team building a native Android app for a local credit union. We are doing some really cool stuff around testing with unit tests, automated instrumentation tests using spoon, and manual user experience testing. We are working in a low-ceremony, flow-based process with continuous client feedback.

One tool we are using to greatly improve our test quality is factories. Android uses Java and so the very name “factory” on a Java project (for a credit union, no less) is probably making you think of BaseAbstractStrategyBuilderFactoryImpl and such, but such enterprisyness is not the case.

Factory chimneys billowing polution

In reality, factories aren’t obligatorily complex: we are simply building an object. If there was any business logic going on I’m sure it would be more complex, but we’re just using them in tests to make writing, debugging, and understanding them easier. Even with a test-first development flow, many tests end up needing some state setup to run correctly and hit to correct code paths. And state setup is a chore.

Java is fairly verbose. Factories allow us to hide that boring instantiation and assignment snooze-festing in a separate place from the main test function.

Take this example from a bit of code I’ve been working on recently. I’ve added some Arrange, Act, Assert comments to make this easier to follow.

@RunWith(AppTestRunner.class)
public class AccountsListActivityTest extends AppActivityUnitTestCase<AccountsListActivity> {

    public AccountsListActivityTest() {
        super(AccountsListActivity.class);
    }

    @Test
    public void selectingAccountListItemLaunchesAccountDetail() {

        // Arrange account
        Account account = new Account();
        account.id = "checking-account-id";
        account.name = "CHECKING";
        account.isInCashFlow = false;
        account.isFavorite = false;

        // Arrange group
        AccountGroup group = new AccountGroup();
        group.id = "group-id";
        group.owners.add("George E. Meade");
        group.owners.add("Robert E. Lee");

        // Arrange group account
        group.accounts.add(account);

        // Arrange list item
        AccountListItem accountListItem = new AccountListItem();
        accountListItem.build(group, account);

        // Act
        activity.onItemSelected(accountListItem);

        // Assert
        Intent startedIntent = assertThat(activity).launchedActivity(AccountDetailActivity.class);
        assertThat(startedIntent).hasExtra(AppExtras.ACCOUNT, account);
    }
}

Not very thrilling? At least it is straightforward, especially since you can see exactly what state is necessary to build make this action work. But why do we care that you can only build an accountListItem from a group and an account? Why do we care that account.isFavorite is required? “isFavorite = false” is my motto when it comes to this load of excess. All of the necessary state arrangements are clear, necessary, and completely irrelevant to what we’re testing. The boring explicitness makes the thing we care about hard to find. I told you this was a snooze-fest.

I’m going to take all the arrange stuff out and make a private method on my test class to hide all the boring setup.

@RunWith(AppTestRunner.class)
public class AccountsListActivityTest extends AppActivityUnitTestCase<AccountsListActivity> {

    public AccountsListActivityTest() {
        super(AccountsListActivity.class);
    }

    @Test
    public void selectingAccountListItemLaunchesAccountDetail() {
        // Arrange
        AccountListItem accountListItem = setupState();

        // Act
        activity.onItemSelected(accountListItem);

        // Assert
        Intent startedIntent = assertThat(activity).launchedActivity(AccountDetailActivity.class);
        assertThat(startedIntent).hasExtra(AppExtras.ACCOUNT, account);
    }

    private AccountListItem setupState() {
        // Arrange account
        Account account = new Account();
        account.id = "checking-account-id";
        account.name = "CHECKING";
        account.isInCashFlow = false;
        account.isFavorite = false;

        // Arrange group
        AccountGroup group = new AccountGroup();
        group.id = "group-id";
        group.owners.add("George E. Meade");
        group.owners.add("Robert E. Lee");

        // Arrange group account
        group.accounts.add(account);

        // Arrange list item
        AccountListItem accountListItem = new AccountListItem();
        accountListItem.build(group, account);
    } 
}

The setupState() method is still pretty overwhelming, but we can ignore it when we read the test method and that is an instant readability win.

Now comes the point of this article. Since we don’t care about the details of the state setup for this test and the (redacted) others in this class, we can move all this out into a factory that will build the objects we need for us. Now other test classes that will need similar state just say “give me one” and no fuss will ensue. The reusability aspect is really nice. The test is now looking clean.

@RunWith(AppTestRunner.class)
public class AccountsListActivityTest extends AppActivityUnitTestCase<AccountsListActivity> {

    public AccountsListActivityTest() {
        super(AccountsListActivity.class);
    }

    @Test
    public void selectingAccountListItemLaunchesAccountDetail() {
        activity.onItemSelected(basicAccountListItem());

        Intent startedIntent = assertThat(activity).launchedActivity(AccountDetailActivity.class);
        assertThat(startedIntent).hasExtra(AppExtras.ACCOUNT_account, account);
    }
}

In my factory I’ve refactored the state into a few simple, reusable methods that I can mix and match. This arrangement grew out of the needs of the various tests as we wrote them and needed different pieces of data.

public class AccountsFactory {

    private static AccountGroup emptyGroup() {
        AccountGroup group = new AccountGroup();
        group.id = "group-id";
        group.owners.add("George E. Meade");
        group.owners.add("Robert E. Lee");

        return group;
    }

    public static AccountGroup groupWithAccount(Account account) {
        AccountGroup group = emptyGroup();
        group.accounts.add(basicAccount());

        return group;
    }

    public static Account basicAccount() {
        Account account = new Account();
        account.id = "checking-account-id";
        account.name = "CHECKING";
        account.isInCashFlow = false;
        account.isFavorite = false;

        return account;
    }

    public static AccountListItem basicAccountListItem() {
        AccountListItem accountListItem = new AccountListItem();
        accountListItem.build(groupWithAccount(), basicAccount());

        return accountListItem;
    }
}

The Aesop-approved moral to this story is to only put the relevant stuff in the test and hide the rest of the boring state-making in a convenient spot for reuse. On this current project we call them factories, and they work great.